Food Delivery services like Zomato and Swiggy need to show the accurate time it will take to deliver your order to keep transparency with their customers. These companies use Machine Learning algorithms to predict the food delivery time based on how much time the delivery partners took for the same distance in the past. So, if you want to learn how to use Machine Learning for food delivery time prediction, this article is for you. This article will take you through food delivery time prediction with Machine Learning using Python.
To predict the food delivery time in real-time, we need to calculate the distance between the food preparation point and the point of food consumption. After finding the distance between the restaurant and the delivery locations, we need to find relationships between the time taken by delivery partners to deliver the food in the past for the same distance. So, for this task, we need a dataset containing data about the time taken by delivery partners to deliver food from the restaurant to the delivery location. I found an ideal dataset with all the features for this task. You can download the dataset from here. In the section below, I will take you through the task of Food Delivery Time Prediction with Machine Learning using Python.
I will start the task of food delivery time prediction by importing the necessary Python libraries and the dataset: 1
import pandas as pd
2
import numpy as np
3
import plotly.express as px
4
5
data = pd.read_csv("deliverytime.txt")
6
print(data.head())
ID Delivery_person_ID Delivery_person_Age Delivery_person_Ratings \ 0 4607 INDORES13DEL02 37 4.9 1 B379 BANGRES18DEL02 34 4.5 2 5D6D BANGRES19DEL01 23 4.4 3 7A6A COIMBRES13DEL02 38 4.7 4 70A2 CHENRES12DEL01 32 4.6 Restaurant_latitude Restaurant_longitude Delivery_location_latitude \ 0 22.745049 75.892471 22.765049 1 12.913041 77.683237 13.043041 2 12.914264 77.678400 12.924264 3 11.003669 76.976494 11.053669 4 12.972793 80.249982 13.012793 Delivery_location_longitude Type_of_order Type_of_vehicle Time_taken(min) 0 75.912471 Snack motorcycle 24 1 77.813237 Snack scooter 33 2 77.688400 Drinks motorcycle 26 3 77.026494 Buffet motorcycle 21 4 80.289982 Snack scooter 30
Let’s have a look at the column insights before moving forward: 1
data.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 45593 entries, 0 to 45592 Data columns (total 11 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID 45593 non-null object 1 Delivery_person_ID 45593 non-null object 2 Delivery_person_Age 45593 non-null int64 3 Delivery_person_Ratings 45593 non-null float64 4 Restaurant_latitude 45593 non-null float64 5 Restaurant_longitude 45593 non-null float64 6 Delivery_location_latitude 45593 non-null float64 7 Delivery_location_longitude 45593 non-null float64 8 Type_of_order 45593 non-null object 9 Type_of_vehicle 45593 non-null object 10 Time_taken(min) 45593 non-null int64 dtypes: float64(5), int64(2), object(4) memory usage: 3.8+ MB
Now let’s have a look at whether this dataset contains any null values or not: 1
data.isnull().sum()
ID 0 Delivery_person_ID 0 Delivery_person_Age 0 Delivery_person_Ratings 0 Restaurant_latitude 0 Restaurant_longitude 0 Delivery_location_latitude 0 Delivery_location_longitude 0 Type_of_order 0 Type_of_vehicle 0 Time_taken(min) 0 dtype: int64
The dataset does not have any null values. Let’s move further!
The dataset doesn’t have any feature that shows the difference between the restaurant and the delivery location. All we have are the latitude and longitude points of the restaurant and the delivery location. We can use the haversine formula to calculate the distance between two locations based on their latitudes and longitudes. Below is how we can find the distance between the restaurant and the delivery location based on their latitudes and longitudes by using the haversine formula: 1
# Set the earth's radius (in kilometers)
2
R = 6371
3
4
# Convert degrees to radians
5
def deg_to_rad(degrees):
6
return degrees * (np.pi/180)
7
8
# Function to calculate the distance between two points using the haversine formula
9
def distcalculate(lat1, lon1, lat2, lon2):
10
d_lat = deg_to_rad(lat2-lat1)
11
d_lon = deg_to_rad(lon2-lon1)
12
a = np.sin(d_lat/2)**2 + np.cos(deg_to_rad(lat1)) * np.cos(deg_to_rad(lat2)) * np.sin(d_lon/2)**2
13
c = 2 * np.arctan2(np.sqrt(a), np.sqrt(1-a))
14
return R * c
15
16
# Calculate the distance between each pair of points
17
data['distance'] = np.nan
18
19
for i in range(len(data)):
20
data.loc[i, 'distance'] = distcalculate(data.loc[i, 'Restaurant_latitude'],
21
data.loc[i, 'Restaurant_longitude'],
22
data.loc[i, 'Delivery_location_latitude'],
23
data.loc[i, 'Delivery_location_longitude'])
We have now calculated the distance between the restaurant and the delivery location. We have also added a new feature in the dataset as distance. Let’s look at the dataset again: 1
print(data.head())
ID Delivery_person_ID Delivery_person_Age Delivery_person_Ratings \ 0 4607 INDORES13DEL02 37 4.9 1 B379 BANGRES18DEL02 34 4.5 2 5D6D BANGRES19DEL01 23 4.4 3 7A6A COIMBRES13DEL02 38 4.7 4 70A2 CHENRES12DEL01 32 4.6 Restaurant_latitude Restaurant_longitude Delivery_location_latitude \ 0 22.745049 75.892471 22.765049 1 12.913041 77.683237 13.043041 2 12.914264 77.678400 12.924264 3 11.003669 76.976494 11.053669 4 12.972793 80.249982 13.012793 Delivery_location_longitude Type_of_order Type_of_vehicle Time_taken(min) \ 0 75.912471 Snack motorcycle 24 1 77.813237 Snack scooter 33 2 77.688400 Drinks motorcycle 26 3 77.026494 Buffet motorcycle 21 4 80.289982 Snack scooter 30 distance 0 3.025149 1 20.183530 2 1.552758 3 7.790401 4 6.210138
Now let’s explore the data to find relationships between the features. I’ll start by looking at the relationship between the distance and time taken to deliver the food: 1
figure = px.scatter(data_frame = data,
2
x="distance",
3
y="Time_taken(min)",
4
size="Time_taken(min)",
5
trendline="ols",
6
title = "Relationship Between Distance and Time Taken")
7
figure.show()
There is a consistent relationship between the time taken and the distance travelled to deliver the food. It means that most delivery partners deliver food within 25-30 minutes, regardless of distance. Now let’s have a look at the relationship between the time taken to deliver the food and the age of the delivery partner: 1
figure = px.scatter(data_frame = data,
2
x="Delivery_person_Age",
3
y="Time_taken(min)",
4
size="Time_taken(min)",
5
color = "distance",
6
trendline="ols",
7
title = "Relationship Between Time Taken and Age")
8
figure.show()
There is a linear relationship between the time taken to deliver the food and the age of the delivery partner. It means young delivery partners take less time to deliver the food compared to the elder partners. Now let’s have a look at the relationship between the time taken to deliver the food and the ratings of the delivery partner: 1
figure = px.scatter(data_frame = data,
2
x="Delivery_person_Ratings",
3
y="Time_taken(min)",
4
size="Time_taken(min)",
5
color = "distance",
6
trendline="ols",
7
title = "Relationship Between Time Taken and Ratings")
8
figure.show()
There is an inverse linear relationship between the time taken to deliver the food and the ratings of the delivery partner. It means delivery partners with higher ratings take less time to deliver the food compared to partners with low ratings. Now let’s have a look if the type of food ordered by the customer and the type of vehicle used by the delivery partner affects the delivery time or not: 1
fig = px.box(data,
2
x="Type_of_vehicle",
3
y="Time_taken(min)",
4
color="Type_of_order")
5
fig.show()
So there is not much difference between the time taken by delivery partners depending on the vehicle they are driving and the type of food they are delivering. So the features that contribute most to the food delivery time based on our analysis are:
In the section below, I will take you through how to train a Machine Learning model for food delivery time prediction.
Now let’s train a Machine Learning model using an LSTM neural network model for the task of food delivery time prediction: 1
#splitting data
2
from sklearn.model_selection import train_test_split
3
x = np.array(data[["Delivery_person_Age",
4
"Delivery_person_Ratings",
5
"distance"]])
6
y = np.array(data[["Time_taken(min)"]])
7
xtrain, xtest, ytrain, ytest = train_test_split(x, y,
8
test_size=0.10,
9
random_state=42)
10
11
# creating the LSTM neural network model
12
from keras.models import Sequential
13
from keras.layers import Dense, LSTM
14
model = Sequential()
15
model.add(LSTM(128, return_sequences=True, input_shape= (xtrain.shape[1], 1)))
16
model.add(LSTM(64, return_sequences=False))
17
model.add(Dense(25))
18
model.add(Dense(1))
19
model.summary()
Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= lstm (LSTM) (None, 3, 128) 66560 lstm_1 (LSTM) (None, 64) 49408 dense (Dense) (None, 25) 1625 dense_1 (Dense) (None, 1) 26 ================================================================= Total params: 117,619 Trainable params: 117,619 Non-trainable params: 0 _________________________________________________________________
1
# training the model
2
model.compile(optimizer='adam', loss='mean_squared_error')
3
model.fit(xtrain, ytrain, batch_size=1, epochs=9)
Epoch 1/9 41033/41033 [==============================] - 410s 10ms/step - loss: 69.7154 Epoch 2/9 41033/41033 [==============================] - 405s 10ms/step - loss: 63.6772 Epoch 3/9 41033/41033 [==============================] - 404s 10ms/step - loss: 61.4656 Epoch 4/9 41033/41033 [==============================] - 406s 10ms/step - loss: 60.5741 Epoch 5/9 41033/41033 [==============================] - 401s 10ms/step - loss: 59.7685 Epoch 6/9 41033/41033 [==============================] - 401s 10ms/step - loss: 59.3501 Epoch 7/9 41033/41033 [==============================] - 397s 10ms/step - loss: 59.3121 Epoch 8/9 41033/41033 [==============================] - 402s 10ms/step - loss: 58.6929 Epoch 9/9 41033/41033 [==============================] - 399s 10ms/step - loss: 58.6897
Now let’s test the performance of our model by giving inputs to predict the food delivery time: 1
print("Food Delivery Time Prediction")
2
a = int(input("Age of Delivery Partner: "))
3
b = float(input("Ratings of Previous Deliveries: "))
4
c = int(input("Total Distance: "))
5
6
features = np.array([[a, b, c]])
7
print("Predicted Delivery Time in Minutes = ", model.predict(features))
Food Delivery Time Prediction Age of Delivery Partner: 29 Ratings of Previous Deliveries: 2.9 Total Distance: 6 1/1 [==============================] - 0s 23ms/step Predicted Delivery Time in Minutes = [[41.34929]]
So this is how you can use Machine Learning for the task of food delivery time prediction using the Python programming language.
To predict the food delivery time in real time, you need to calculate the distance between the food preparation point and the point of food consumption. After finding the distance between the restaurant and the delivery locations, you need to find relationships between the time taken by delivery partners to deliver the food in the past for the same distance. I hope you liked this article on food delivery time prediction with Machine Learning using Python. Feel free to ask valuable questions in the comments section below.