04 Mar
04Mar

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.

Food Delivery Time Prediction

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.

Food Delivery Time Prediction 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!

Calculating Distance Between Two Latitudes and Longitudes

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

Data Exploration

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:

  • age of the delivery partner
  • ratings of the delivery partner
  • distance between the restaurant and the delivery location

In the section below, I will take you through how to train a Machine Learning model for food delivery time prediction.

Food Delivery Time Prediction Model

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.

Summary

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. 

Comments
* The email will not be published on the website.
I BUILT MY SITE FOR FREE USING