Introduction
More businesses are moving online these days, and consumers are ordering online instead of traveling to the store to buy. Zomato and Swiggy are popular online platforms for ordering food products. Other examples are Uber Eats, Food Panda, and Deliveroo, which also have similar services. They provide food delivery options. If the order is complete, a partner will pick up and deliver the meal to the given address via a delivery service. In online food-ordering businesses, delivery time is critical. As a result, estimated food delivery time prediction to reach the buyer’s location is critical. The LSTM neural network is one of the methods that may be implemented in this circumstance. Come on, let’s study the LSTM models in detail.
This article was published as a part of the Data Science Blogathon.
Table of Contents
Objectives of Food Delivery Time Prediction
- Make an accurate estimate of when the food will arrive, thus increasing customer confidence.
- Plan delivery routes and driver schedules more efficiently by predicting how many orders will arrive so that delivery providers can use their resources better.
- Make deliveries faster by looking at past delivery data and determining the attributes that affect them.
- Grow business because of buyer satisfaction with the speed of delivery.
Based on these goals, we will use the LSTM Neural Network to develop a model that can estimate the delivery time of orders accurately based on the age of the delivery partner, the partner’s rating, and the distance between the restaurant and the buyer’s place. This article will guide you on predicting food delivery time using LSTM. Now, let’s make the prediction through the steps in the article.
Step 1: Import Library
import pandas as pd
import numpy as np
import plotly.express as px
from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.layers import Dense, LSTM
Pandas and NumPy libraries are used together for data analysis. NumPy provides fast mathematical functions for multidimensional arrays, while Pandas makes it easier to analyze and manipulate data with more complex data structures like DataFrame and Series. Meanwhile, the Plotly Express library makes it easy for users to create interactive visualizations in Python. It can use minimal code to create various charts, such as scatter plots, line charts, bar charts, and maps. The Sequential class is a type of model in Keras that allows users to create a neural network by adding layers to it in sequential order. Then, Dense and LSTM are to create layers in the Keras model and also customize their configurations.
Step 2: Read the Data
The availability of data is crucial to any data analysis task. It is essential to have a dataset that contains all the required features and
variables for the particular task at hand. And for this particular case, the appropriate dataset is on my github. The dataset given here is a cleaned version of the original dataset submitted by Gaurav Malik on Kaggle.
#reading dataset
url = 'https://raw.githubusercontent.com/ataislucky/Data-Science/main/dataset/food_delivery.txt'
data = pd.read_csv(url)
data.sample(5)
Let’s see detailed information about the dataset we use with the info() command.
data.info()
Checking a dataset’s columns and null values is essential in any data analysis project. Let’s do it.
data.isnull().sum()
The dataset is complete with no null values, so let’s proceed!
Step 3: Haversine Formula
The Haversine formula is used to find the distance between two geographical locations. The formula refers to this Wikipedia page as follows:
It takes the latitude and longitude of two points and converts the angles to radians to perform the necessary calculations. We use this formula because the dataset doesn’t provide the distance between the restaurant and the delivery location. There are only latitude and longitude. So, let’s calculate it and then create a distance column in the dataset.
R = 6371 ##The earth's radius (in km)
def deg_to_rad(degrees):
return degrees * (np.pi/180)
## The haversine formula
def distcalculate(lat1, lon1, lat2, lon2):
d_lat = deg_to_rad(lat2-lat1)
d_lon = deg_to_rad(lon2-lon1)
a1 = np.sin(d_lat/2)**2 + np.cos(deg_to_rad(lat1))
a2 = np.cos(deg_to_rad(lat2)) * np.sin(d_lon/2)**2
a = a1 * a2
c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1-a))
return R * c
# Create distance column & calculate the distance
data['distance'] = np.nan
for i in range(len(data)):
data.loc[i, 'distance'] = distcalculate(data.loc[i, 'Restaurant_latitude'],
data.loc[i, 'Restaurant_longitude'],
data.loc[i, 'Delivery_location_latitude'],
data.loc[i, 'Delivery_location_longitude'])
The parameter “lat” means latitude, and “lon” means longitude. The deg_to_rad function is helpful for converting degrees to radians. At the same time, calculate the distance between two location points using the variables a1 and a2. The variable stores the result of multiplying a1 and a2, while the c variable stores the result of the Haversine formula calculation, which produces the distance between the two location points.
We have added a distance column to the dataset. Now, we will analyze the effect of distance and delivery time.
figure = px.scatter(data_frame = data,
x="distance",
y="Time_taken(min)",
size="Time_taken(min)",
trendline="ols",
title = "Relationship Between Time Taken and Distance")
figure.show()
The graph shows that there is a consistent relationship between the time taken and the distance traveled for food delivery. This means that the majority of delivery partners deliver food within a range of 25–30 minutes, regardless of the distance.
Next, we will explore whether the delivery partner’s age affects delivery time or not.
figure = px.scatter(data_frame = data,
x="Delivery_person_Age",
y="Time_taken(min)",
size="Time_taken(min)",
color = "distance",
trendline="ols",
title = "Relationship Between Delivery Partner Age and Time Taken")
figure.show()
The graph shows faster food delivery when partners are younger than their older counterparts. Now let’s explore the correlation between delivery time and delivery partner ratings.
figure = px.scatter(data_frame = data,
x="Delivery_person_Ratings",
y="Time_taken(min)",
size="Time_taken(min)",
color = "distance",
trendline="ols",
title = "Relationship Between Delivery Partner Ratings and Time Taken")
figure.show()
The graph shows an inverse linear relationship. The higher the rating partner, the faster the time needed to deliver food, and vice versa.
The next step will be to see whether the delivery partner’s vehicle affects the delivery time or not.
fig = px.box(data,
x="Type_of_vehicle",
y="Time_taken(min)",
color="Type_of_order",
title = "Relationship Between Type of Vehicle and Type of Order")
fig.show()
The graph shows that the type of delivery partner’s vehicle and the type of food delivered do not significantly affect delivery time.
Through the analysis above, we can determine that the delivery partner’s age, the delivery partner’s rating, and the distance between the restaurant and the delivery location are the features that have the most significant impact on food delivery time.
Step 4: Build an LSTM Model and Make Predictions
Previously, we have determined three features that significantly affect the time taken, namely the delivery partner’s age, the delivery partner’s rating, and distance. So the three features will become independent variables (x), while the time taken will become the dependent variable (y).
x = np.array(data[["Delivery_person_Age",
"Delivery_person_Ratings",
"distance"]])
y = np.array(data[["Time_taken(min)"]])
xtrain, xtest, ytrain, ytest = train_test_split(x, y,
test_size=0.20,
random_state=33)
Now, we need to train an LSTM neural network to predict food delivery time. The aim is to create a precise model that uses features like distance, delivery partner age, and rating to estimate food delivery time. The trained model can then be used to predict new data points or unseen scenarios.
model = Sequential()
model.add(LSTM(128, return_sequences=True, input_shape= (xtrain.shape[1], 1)))
model.add(LSTM(64, return_sequences=False))
model.add(Dense(25))
model.add(Dense(1))
model.summary()
The code block above explains:
The first line starts building the model architecture by creating an instance of the Sequential class. The following three lines define the layers of the model. The first layer is an LSTM layer with 128 units, which returns sequences and takes input for shape (xtrain.shape[1], 1). Here, xtrain is the input training data, and shape[1] represents the number of features in the input data. The return_sequences parameter is set to True because there will be more layers after this one. The second layer is also an LSTM layer, but with 64 units and return_sequences set to False, indicating that this is the last layer. The third line adds a dense layer with 25 units, which reduces the output of the LSTM layers to a more manageable size. Finally, the fourth line adds a dense layer with one unit, which is the output layer of the model.
Now let’s train the previously created model.
model.compile(optimizer='adam', loss='mean_squared_error')
model.fit(xtrain, ytrain, batch_size=1, epochs=9)
The ‘adam’ parameter is a popular optimization algorithm for deep learning models, and the ‘mean_squared_error’ parameter is a common loss function used in regression problems. The parameter batch_size = 1 means that the model will update its weights after each sample is processed during training. The epochs parameter is set to 9, meaning the model will be trained on the entire dataset for nine iterations.
Finally, let’s test the model’s performance for predicting food delivery times given three input parameters (delivery partner age, delivery rating, and distance).
print("Food Delivery Time Prediction using LSTM")
a = int(input("Delivery Partner Age: "))
b = float(input("Previous Delivery Ratings: "))
c = int(input("Total Distance: "))
features = np.array([[a, b, c]])
print("Delivery Time Prediction in Minutes = ", model.predict(features))
The given result is a prediction of the delivery time for a hypothetical food delivery order based on the trained LSTM neural network model using the following input features:
- Delivery Partner’s Age: 33
- Previous Delivery Ratings: 4.0
- Total distance: 7
The output of the prediction is shown as “Delivery Time Prediction in Minutes = [[36.913715]],” which means that the model has estimated that the food delivery will take approximately 36.91 minutes to reach the destination.
Conclusion
This article starts by calculating the distance between the restaurant and the delivery location. Then, it analyzes previous delivery times for the same distance before predicting food delivery times in real-time using LSTM. Broadly speaking, in this post, we have discussed the following:
- How to calculate the distance using the haversine formula?
- How to find the features that affect the food delivery time prediction?
- How to use LSTM neural network model to predict the food delivery time?
Overall, the article provides a comprehensive guide on food delivery time prediction with an LSTM neural network using Python. If you have any questions or comments, please leave them below. The complete code can be seen here.
The media shown in this article is not owned by Analytics Vidhya and is used at the Author’s discretion.