←  Sugeerth Murugesan Instacart ML Assignment Portfolio

Summary of Results

Here is an all encompassing jupyter notebook that will take care of the train, test and evaluation of a model responsible for identifying the trip time for shopping to take place.

For the prediction, given a trip id with the relevant features, the model predicts the total time for prediction,

*trip_id,  shopping_time
130622,900
130625,45*

Please note that this is a Google Colab notebook so please upload the train and test data into the runtime environment as the data is lost for every new runtime.

Breakdown of this notebook:

  Loading the dataset: Load the data and import the libraries.
  Data Preprocessing:
  Analysing missing data
  Removing redundant columns.
  Plots for different attributes of feature columns.
  Analysing the feature columns and combining them into a form that makes sense
  Modelling 
    Linear Regression
    Gradient Boosting Tree Regressor 
.
# Importing all the relvant libraries and features that is responseible for the jupyter notebook 
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
import pylab
import seaborn as sns

import sklearn
%matplotlib inline
import pandas
from sklearn.model_selection import train_test_split
import numpy
#Import the 2 csv files into dataframes
test_table = pd.read_csv('instacart/test_trips.csv',parse_dates=['shopping_started_at'])
train_table = pd.read_csv('instacart/train_trips.csv',parse_dates=['shopping_started_at','shopping_ended_at'])
order_items = pd.read_csv('instacart/order_items.csv')
# Take a look at the data for my test set
test_table.head(5)
trip_id shopper_id fulfillment_model store_id shopping_started_at
0 4310899 60930 model_2 123 2015-11-16 07:00:12
1 4310904 59815 model_2 123 2015-11-16 07:00:12
2 4310907 60878 model_2 123 2015-11-16 07:00:13
3 4310911 60879 model_2 123 2015-11-16 07:00:13
4 4310328 66726 model_1 1 2015-11-16 07:01:08
# This is my training set where I have the data about when the shopper started shopping and when the shopper ended 
train_table.head(5)
trip_id shopper_id fulfillment_model store_id shopping_started_at shopping_ended_at
0 3119519 48539 model_1 6 2015-09-01 07:03:56 2015-09-01 07:30:56
1 3119513 3775 model_1 1 2015-09-01 07:04:33 2015-09-01 07:40:33
2 3119516 4362 model_1 1 2015-09-01 07:23:21 2015-09-01 07:41:21
3 3119792 47659 model_1 1 2015-09-01 07:29:52 2015-09-01 08:55:52
4 3119922 11475 model_1 1 2015-09-01 07:32:21 2015-09-01 09:01:21
order_items.head(5)
trip_id item_id department_name quantity
0 3119513 368671 Produce 10.0
1 3120462 368671 Produce 10.0
2 3120473 368671 Produce 10.0
3 3121910 368671 Produce 6.0
4 3122332 368671 Produce 10.0
train_table['fulfillment_model']=train_table['fulfillment_model'].astype('str')
# Identifying the total time in seconds that a shopper spent within a given trip 
train_table['time_difference'] = (train_table.shopping_ended_at- train_table.shopping_started_at).astype('timedelta64[s]')

Understanding the data

In this section we look at the data can be explored in a vareity of different ways

# Looking at the distribution of the store data, it seems like there are few stores that attract a lot of shoppers 
sns.distplot(train_table['store_id']);
# A statistical measure indicating the asymmetry of the probability distribution of a random-variable about its mean 
print("Skewness: %f" % train_table['store_id'].skew())
Skewness: 2.289490

The distribution actually moves away from the normal distribution, indicating that a very few stores attract a lot of customers.

The positive skewness indicate that supporting resources for a few stores may actually account for supporting 80-90% percent of the shoppers

# While now we can look at other distributions of the test dataset, we could see a similar pattern 
hist = test_table.hist(bins=9)
# Understanding the distributions of what people actually buy in the store
hist = order_items.hist(bins=49)

While from the distributions we can understand most people buy very less quantities of items, etc, they actually buy few items frequently.

Understanding what this item maybe and better recommending these items could be a powerful way to increase engagements, and conversion to buy a product

# Plotting the distribution of the models  
sns.catplot(x="fulfillment_model", kind="count", palette="ch:.25", data=train_table);

Now we plot the distribution of the trip times that the shoppers spend at a given place

# Looking at the distribution of the store data, it seems like there are few stores that attract a lot of shoppers 
sns.distplot(train_table['time_difference']);

Upon looking at the data we can see that the data is a form of a gaussian distribution that is positively skewed

train_table.count()
trip_id                117063
shopper_id             117063
fulfillment_model      117063
store_id               117063
shopping_started_at    117063
shopping_ended_at      117063
time_difference        117063
dtype: int64

Adding more informative features

While understanding time is important, important patterns like the shoppers may have more time to shop during the weekends vs weekdays, during the evenings vs during noon and especially a high turnout on a Monday evening or a Sunday morning

train_table.head(3)
trip_id shopper_id fulfillment_model store_id shopping_started_at shopping_ended_at time_difference
0 3119519 48539 model_1 6 2015-09-01 07:03:56 2015-09-01 07:30:56 1620.0
1 3119513 3775 model_1 1 2015-09-01 07:04:33 2015-09-01 07:40:33 2160.0
2 3119516 4362 model_1 1 2015-09-01 07:23:21 2015-09-01 07:41:21 1080.0
train_table['day_of_week'] = train_table['shopping_started_at'].dt.day_name()
sns.catplot(x="day_of_week", kind="count", palette="ch:.25", data=train_table);

Most of the shopping actually happens during Sunday and Monday, which is informative. One major reason could be that the people are gearing up to get groceries for the upcoming week

# Adding numerical value to the feature
train_table['day_of_week'] = train_table['shopping_started_at'].dt.dayofweek
train_table.dtypes
trip_id                         int64
shopper_id                      int64
fulfillment_model              object
store_id                        int64
shopping_started_at    datetime64[ns]
shopping_ended_at      datetime64[ns]
time_difference               float64
day_of_week                     int64
dtype: object
# Understanding the segment of the day 
train_table = train_table.assign(day_segment=pd.cut(train_table.shopping_started_at.dt.hour,[0,6,12,18,24],labels=[1,2,3,4]))
train_table['day_segment']=train_table['day_segment'].astype('int')
sns.catplot(x="day_segment", kind="count", palette="ch:.25", data=train_table);

Same can be said about the segment of the day during which people buy items. Most of the items are bought during a monday or a sunday afternoon

train_table.dtypes
trip_id                         int64
shopper_id                      int64
fulfillment_model              object
store_id                        int64
shopping_started_at    datetime64[ns]
shopping_ended_at      datetime64[ns]
time_difference               float64
day_of_week                     int64
day_segment                     int64
dtype: object
train_table.head(9)
trip_id shopper_id fulfillment_model store_id shopping_started_at shopping_ended_at time_difference day_of_week day_segment
0 3119519 48539 model_1 6 2015-09-01 07:03:56 2015-09-01 07:30:56 1620.0 1 2
1 3119513 3775 model_1 1 2015-09-01 07:04:33 2015-09-01 07:40:33 2160.0 1 2
2 3119516 4362 model_1 1 2015-09-01 07:23:21 2015-09-01 07:41:21 1080.0 1 2
3 3119792 47659 model_1 1 2015-09-01 07:29:52 2015-09-01 08:55:52 5160.0 1 2
4 3119922 11475 model_1 1 2015-09-01 07:32:21 2015-09-01 09:01:21 5340.0 1 2
5 3119518 10720 model_1 1 2015-09-01 07:37:53 2015-09-01 08:18:53 2460.0 1 2
6 3119520 43442 model_1 115 2015-09-01 07:39:11 2015-09-01 08:39:11 3600.0 1 2
7 3119703 15696 model_1 6 2015-09-01 07:41:06 2015-09-01 08:46:06 3900.0 1 2
8 3120376 44675 model_2 1 2015-09-01 08:00:08 2015-09-01 08:28:08 1680.0 1 2

Merging order items

To get a more richer dataset, we can now merge what exact deaprment was bought with what quantity

The next step would then be to aggregate this information such that there is unique feature value for every trip id

train_table = train_table.merge(order_items,how='left',on='trip_id')
train_table.head()
trip_id shopper_id fulfillment_model store_id shopping_started_at shopping_ended_at time_difference day_of_week day_segment item_id department_name quantity
0 3119519 48539 model_1 6 2015-09-01 07:03:56 2015-09-01 07:30:56 1620.0 1 2 619098 Meat & Seafood 1.0
1 3119519 48539 model_1 6 2015-09-01 07:03:56 2015-09-01 07:30:56 1620.0 1 2 313592 Produce 1.0
2 3119519 48539 model_1 6 2015-09-01 07:03:56 2015-09-01 07:30:56 1620.0 1 2 979903 Bakery 1.0
3 3119519 48539 model_1 6 2015-09-01 07:03:56 2015-09-01 07:30:56 1620.0 1 2 1331310 Breakfast 1.0
4 3119519 48539 model_1 6 2015-09-01 07:03:56 2015-09-01 07:30:56 1620.0 1 2 1329835 Snacks 2.0

The data that we have here is merged with the trip_id being the primary key. This makes sure that all of the data is taken into account for analysis

# Convert the date time, categorize them into time of day
train_table.isnull().sum()
trip_id                0
shopper_id             0
fulfillment_model      0
store_id               0
shopping_started_at    0
shopping_ended_at      0
time_difference        0
day_of_week            0
day_segment            0
item_id                0
department_name        0
quantity               0
dtype: int64
# Create a new training set that can group by trip_id, store_id','department_name','item_id','fulfillment_model','shopping_started_at' 
cleaned_train_data = train_table.groupby(['trip_id','store_id','department_name','item_id','fulfillment_model','shopping_started_at','day_of_week','day_segment']).agg({'quantity':np.sum,'time_difference':np.mean,'shopper_id':np.median}).reset_index()
cleaned_train_data.head(9)
trip_id store_id department_name item_id fulfillment_model shopping_started_at day_of_week day_segment quantity time_difference shopper_id
0 3119513 1 Beverages 1233034 model_1 2015-09-01 07:04:33 1 2 4.0 2160.0 3775
1 3119513 1 Beverages 1233035 model_1 2015-09-01 07:04:33 1 2 4.0 2160.0 3775
2 3119513 1 Dairy & Eggs 1235199 model_1 2015-09-01 07:04:33 1 2 10.0 2160.0 3775
3 3119513 1 Dairy & Eggs 1243597 model_1 2015-09-01 07:04:33 1 2 12.0 2160.0 3775
4 3119513 1 Dairy & Eggs 1245142 model_1 2015-09-01 07:04:33 1 2 2.0 2160.0 3775
5 3119513 1 Dairy & Eggs 1245145 model_1 2015-09-01 07:04:33 1 2 2.0 2160.0 3775
6 3119513 1 Dairy & Eggs 1250880 model_1 2015-09-01 07:04:33 1 2 2.0 2160.0 3775
7 3119513 1 Deli 1257280 model_1 2015-09-01 07:04:33 1 2 1.0 2160.0 3775
8 3119513 1 International 1255586 model_1 2015-09-01 07:04:33 1 2 1.0 2160.0 3775
cleaned_train_data.count()
trip_id                1859920
store_id               1859920
department_name        1859920
item_id                1859920
fulfillment_model      1859920
shopping_started_at    1859920
day_of_week            1859920
day_segment            1859920
quantity               1859920
time_difference        1859920
shopper_id             1859920
dtype: int64
sns.scatterplot(x="store_id", y="time_difference", hue="day_of_week", data=train_table)
<matplotlib.axes._subplots.AxesSubplot at 0x7f232ade4f98>
Error in callback <function flush_figures at 0x7f23448b0378> (for post_execute):

A lot of the items are bought at a few stores (121, 1) on a few days (6)

shopper_average_data_cleaned = cleaned_train_data.groupby(['shopper_id']).agg({'time_difference':np.mean}).reset_index()
store_average_data_cleaned = cleaned_train_data.groupby(['store_id']).agg({'time_difference':np.mean}).reset_index()
sns.scatterplot(x="time_difference", y="shopper_id", data=shopper_average_data_cleaned)
<matplotlib.axes._subplots.AxesSubplot at 0x7f23201dde80>

There seems to be an average amount of time that the shoppers like to spend at the store, around say about 3000 seconds

unique_trip_id_data = cleaned_train_data.groupby(['trip_id','store_id','shopper_id','shopping_started_at']).agg({'day_segment':np.mean, 'day_of_week':np.mean,'time_difference':np.mean,'quantity': np.sum,'department_name': 'nunique'}).reset_index()
unique_trip_id_data.head(10)
trip_id store_id shopper_id shopping_started_at day_segment day_of_week time_difference quantity department_name
0 3119513 1 3775 2015-09-01 07:04:33 2 1 2160.0 183.0 8
1 3119516 1 4362 2015-09-01 07:23:21 2 1 1080.0 9.0 5
2 3119518 1 10720 2015-09-01 07:37:53 2 1 2460.0 21.0 6
3 3119519 6 48539 2015-09-01 07:03:56 2 1 1620.0 39.0 11
4 3119520 115 43442 2015-09-01 07:39:11 2 1 3600.0 36.0 14
5 3119703 6 15696 2015-09-01 07:41:06 2 1 3900.0 40.0 11
6 3119792 1 47659 2015-09-01 07:29:52 2 1 5160.0 92.0 10
7 3119922 1 11475 2015-09-01 07:32:21 2 1 5340.0 186.0 7
8 3119992 6 42965 2015-09-01 08:43:52 2 1 8400.0 52.0 11
9 3120074 115 44851 2015-09-01 08:15:08 2 1 2640.0 61.5 12
hist = unique_trip_id_data.hist(bins=9)
finalTrainData = newTrainData.groupby(['trip_id','store_id','department_name']).agg({'quantity':np.sum,'shopping_trip_time':np.mean,'shopper_id':np.mean,'item_id':'nunique'}).reset_index()
finalTrainData = finalTrainData.rename(columns = {'item_id':'num_item_department'})
departmentDf = finalTrainData[['trip_id','department_name']]
uniqueDepartments = finalTrainData['department_name'].unique()
uniqueTripIds = finalTrainData['trip_id'].unique()
pivotTrainData_department = pd.pivot_table(finalTrainData,columns = ['department_name'],values=['quantity'],index='trip_id')
pivotTrainData_department = pivotTrainData_department.fillna(0)
pivotTrainData_numItems = pd.pivot_table(finalTrainData,columns = ['department_name'],values=['num_item_department'],index='trip_id')
pivotTrainData_numItems = pivotTrainData_numItems.fillna(0)
pivotTrainData = pd.concat([pivotTrainData_department,pivotTrainData_numItems],axis = 1)
flat_pivotData = pd.DataFrame(pivotTrainData.to_records())
flat_pivotData.columns = [hdr.replace("('num_item_department', '", "num_item_dept.").replace("')", "") for hdr in flat_pivotData.columns]
flat_pivotData.columns = [hdr.replace("('num_item_department',", "num_item_dept.").replace(")", "") for hdr in flat_pivotData.columns]
flat_pivotData.columns = [hdr.replace("('quantity', '", "quantity.").replace("')", "") for hdr in flat_pivotData.columns]
# Identify the number of unique departments 
unique_department = working_training_data.department_name.unique()
unique_department
array(['Beverages', 'Dairy & Eggs', 'Deli', 'International', 'Pantry',
       'Popular', 'Produce', 'Snacks', 'Canned Goods', 'Household',
       'Bakery', 'Dry Goods & Pasta', 'Breakfast', 'Frozen',
       'Meat & Seafood', 'Smoothie Central', 'Alcohol', 'Babies',
       'Personal Care', "Valentine's Day Specials", 'Ice Cream Social!',
       'Bulk', "St. Patrick's Day Specials", 'Holiday Favorites',
       '25% OFF Supplements 8/14-8/16', 'All It Takes to Bake!',
       'Fill the Grill', 'Our Brands', 'Thanksgiving',
       'Thanksgiving A to Z', 'Pets', 'Floral', 'Holidays', 'Newly Added',
       'Holiday Essentials', 'Halloween', 'Local', 'Academy Awards',
       'Burning Man Essentials', 'Bi-Rite Creamery',
       "New Year's Eve Extravaganza!", "Valentine's- Made with Love!",
       'FitMarket', '4th of July', 'TEST SPECIAL AISLE', 'Dog',
       'Healthy Eating', 'Cheese', 'Aquatics', 'Cat', 'Summer Drinks',
       'Super Bowl Party', 'Healthy Choices for 2016', 'Local Favorites',
       "Father's Day", "Mother's Day", 'Business Items',
       'Game Day Specials', 'Olives, Gourmet Cheese, Salads',
       'Passover & Easter', 'Ready to Eat', 'Gifts for the Foodie',
       "Bi-Rite's Winter Favorites!", 'Bird', 'Travel', 'Fromagerie',
       'BBQ Favorites', 'Hanukkah', 'Ready to Cook', "Buyers' Picks",
       'Small Animal', 'Vitamins & Supplements', 'Star Wars',
       'Rosh Hashanah & Yom Kippur', 'Reptile', 'Holiday',
       'Fall Wine, Beer, & Spirits', 'Seasonal', 'Flowers & Plants',
       'Costumes', 'Holiday Turkeys', 'Christmas & NYE Menu',
       'Find it at Target'], dtype=object)
# The goal of this code is to tease a one-hot encoding of the store-id and department_name such that these features 
# uniquely identify patterns underlying a trip id

# Here the combination of the quantity and item_id with the department_name to create more descriptive features for the data

# The goal is to mention for a given trip how many quantities are present for department_name or what item_id is present for a department_name

working_training_data = cleaned_train_data.groupby(['trip_id','store_id','department_name','day_of_week','day_segment']).agg({'quantity':np.sum,'time_difference':np.mean,'shopper_id':np.mean,'item_id':'nunique'}).reset_index()

# Combining features department_name, quantity
training_data_department_name_quantity = pd.pivot_table(finalTrainData,columns = ['department_name'],values=['quantity'],index='trip_id')
training_data_department_name_quantity = training_data_department_name_quantity.fillna(0)

# Combining features department_name, item_id
training_data_department_name_item_id = pd.pivot_table(finalTrainData,columns = ['department_name'],values=['item_id'],index='trip_id')
training_data_department_name_item_id = training_data_department_name_item_id.fillna(0)

train_data = pd.concat([training_data_department_name_quantity,training_data_department_name_item_id],axis = 1)

# Instantiating the value so that the data convert to records
flattened_data = pd.DataFrame(train_data.to_records())
flattened_data
trip_id ('quantity', '25% OFF Supplements 8/14-8/16') ('quantity', '4th of July') ('quantity', 'Academy Awards') ('quantity', 'Alcohol') ('quantity', 'All It Takes to Bake!') ('quantity', 'Aquatics') ('quantity', 'BBQ Favorites') ('quantity', 'Babies') ('quantity', 'Bakery') ('quantity', 'Beverages') ('quantity', 'Bi-Rite Creamery') ('quantity', "Bi-Rite's Winter Favorites!") ('quantity', 'Bird') ('quantity', 'Breakfast') ('quantity', 'Bulk') ('quantity', 'Burning Man Essentials') ('quantity', 'Business Items') ('quantity', "Buyers' Picks") ('quantity', 'Canned Goods') ('quantity', 'Cat') ('quantity', 'Cheese') ('quantity', 'Christmas & NYE Menu') ('quantity', 'Costumes') ('quantity', 'Dairy & Eggs') ('quantity', 'Deli') ('quantity', 'Dog') ('quantity', 'Dry Goods & Pasta') ('quantity', 'Fall Wine, Beer, & Spirits') ('quantity', "Father's Day") ('quantity', 'Fill the Grill') ('quantity', 'Find it at Target') ('quantity', 'FitMarket') ('quantity', 'Floral') ('quantity', 'Flowers & Plants') ('quantity', 'Fromagerie') ('quantity', 'Frozen') ('quantity', 'Game Day Specials') ('quantity', 'Gifts for the Foodie') ('quantity', 'Halloween') ... ('item_id', 'Holiday Essentials') ('item_id', 'Holiday Favorites') ('item_id', 'Holiday Turkeys') ('item_id', 'Holidays') ('item_id', 'Household') ('item_id', 'Ice Cream Social!') ('item_id', 'International') ('item_id', 'Local') ('item_id', 'Local Favorites') ('item_id', 'Meat & Seafood') ('item_id', "Mother's Day") ('item_id', "New Year's Eve Extravaganza!") ('item_id', 'Newly Added') ('item_id', 'Olives, Gourmet Cheese, Salads') ('item_id', 'Our Brands') ('item_id', 'Pantry') ('item_id', 'Passover & Easter') ('item_id', 'Personal Care') ('item_id', 'Pets') ('item_id', 'Popular') ('item_id', 'Produce') ('item_id', 'Ready to Cook') ('item_id', 'Ready to Eat') ('item_id', 'Reptile') ('item_id', 'Rosh Hashanah & Yom Kippur') ('item_id', 'Seasonal') ('item_id', 'Small Animal') ('item_id', 'Smoothie Central') ('item_id', 'Snacks') ('item_id', "St. Patrick's Day Specials") ('item_id', 'Star Wars') ('item_id', 'Summer Drinks') ('item_id', 'Super Bowl Party') ('item_id', 'TEST SPECIAL AISLE') ('item_id', 'Thanksgiving') ('item_id', 'Thanksgiving A to Z') ('item_id', 'Travel') ('item_id', "Valentine's Day Specials") ('item_id', "Valentine's- Made with Love!") ('item_id', 'Vitamins & Supplements')
0 3119513 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 8.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 28.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 5.0 11.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 7.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
1 3119516 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2 3119518 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 4.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 0.0 5.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
3 3119519 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 2.0 7.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 7.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 4.0 3.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
4 3119520 0.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 2.0 2.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 8.0 1.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 4.0 4.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
117058 4309197 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 1.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 4.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
117059 4309198 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
117060 4309202 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
117061 4309208 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 2.0 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 4.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 2.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
117062 4309209 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 3.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

117063 rows × 167 columns

# Rename the columns such that the columns are more readable
flattened_data.columns = [hdr.replace("('item_id',", "item_id_").replace(")", "") for hdr in flattened_data.columns]
flattened_data.columns = [hdr.replace("('quantity', '", "quantity_").replace("')", "") for hdr in flattened_data.columns]
# Removing any duplicate columns or data that one may have
flattened_data.columns.duplicated()
array([False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False, False, False, False, False,
       False, False, False, False, False])
# While day_segment is avaiable, the hour of the time is discriminative enough to identify as a feature
unique_trip_id_data['hour'] = unique_trip_id_data['shopping_started_at'].dt.hour
combined_train_data = pd.concat([unique_trip_id_data,flattened_data],axis = 1)

# AllTrainData = AllTrainData.iloc[:,~AllTrainData.columns.duplicated()]
# AllTrainData['day_of_week'] = AllTrainData['shopping_started_at'].dt.dayofweek
# AllTrainData['date'] = AllTrainData['shopping_started_at'].dt.date
# AllTrainData['hour'] = AllTrainData['shopping_started_at'].dt.hour
# collapsedTrainData = AllTrainData[['shopper_id','store_id','date','hour','day_of_week','quantity','time_difference','num_dept_visited']]
trip_id store_id shopper_id shopping_started_at day_segment day_of_week time_difference quantity department_name hour trip_id ('quantity', '25% OFF Supplements 8/14-8/16') ('quantity', '4th of July') ('quantity', 'Academy Awards') ('quantity', 'Alcohol') ('quantity', 'All It Takes to Bake!') ('quantity', 'Aquatics') ('quantity', 'BBQ Favorites') ('quantity', 'Babies') ('quantity', 'Bakery') ('quantity', 'Beverages') ('quantity', 'Bi-Rite Creamery') ('quantity', "Bi-Rite's Winter Favorites!") ('quantity', 'Bird') ('quantity', 'Breakfast') ('quantity', 'Bulk') ('quantity', 'Burning Man Essentials') ('quantity', 'Business Items') ('quantity', "Buyers' Picks") ('quantity', 'Canned Goods') ('quantity', 'Cat') ('quantity', 'Cheese') ('quantity', 'Christmas & NYE Menu') ('quantity', 'Costumes') ('quantity', 'Dairy & Eggs') ('quantity', 'Deli') ('quantity', 'Dog') ('quantity', 'Dry Goods & Pasta') ('quantity', 'Fall Wine, Beer, & Spirits') ('quantity', "Father's Day") ... ('item_id', 'Holiday Essentials') ('item_id', 'Holiday Favorites') ('item_id', 'Holiday Turkeys') ('item_id', 'Holidays') ('item_id', 'Household') ('item_id', 'Ice Cream Social!') ('item_id', 'International') ('item_id', 'Local') ('item_id', 'Local Favorites') ('item_id', 'Meat & Seafood') ('item_id', "Mother's Day") ('item_id', "New Year's Eve Extravaganza!") ('item_id', 'Newly Added') ('item_id', 'Olives, Gourmet Cheese, Salads') ('item_id', 'Our Brands') ('item_id', 'Pantry') ('item_id', 'Passover & Easter') ('item_id', 'Personal Care') ('item_id', 'Pets') ('item_id', 'Popular') ('item_id', 'Produce') ('item_id', 'Ready to Cook') ('item_id', 'Ready to Eat') ('item_id', 'Reptile') ('item_id', 'Rosh Hashanah & Yom Kippur') ('item_id', 'Seasonal') ('item_id', 'Small Animal') ('item_id', 'Smoothie Central') ('item_id', 'Snacks') ('item_id', "St. Patrick's Day Specials") ('item_id', 'Star Wars') ('item_id', 'Summer Drinks') ('item_id', 'Super Bowl Party') ('item_id', 'TEST SPECIAL AISLE') ('item_id', 'Thanksgiving') ('item_id', 'Thanksgiving A to Z') ('item_id', 'Travel') ('item_id', "Valentine's Day Specials") ('item_id', "Valentine's- Made with Love!") ('item_id', 'Vitamins & Supplements')
0 3119513 1 3775 2015-09-01 07:04:33 2 1 2160.0 183.0 8 7 3119513 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 8.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 28.0 1.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 5.0 11.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 7.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
1 3119516 1 4362 2015-09-01 07:23:21 2 1 1080.0 9.0 5 7 3119516 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2 3119518 1 10720 2015-09-01 07:37:53 2 1 2460.0 21.0 6 7 3119518 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 4.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 0.0 5.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
3 3119519 6 48539 2015-09-01 07:03:56 2 1 1620.0 39.0 11 7 3119519 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 2.0 7.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 7.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 4.0 3.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
4 3119520 115 43442 2015-09-01 07:39:11 2 1 3600.0 36.0 14 7 3119520 0.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 2.0 2.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 8.0 1.0 0.0 1.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 4.0 4.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
117058 4309197 6 66865 2015-11-15 21:49:51 4 6 4440.0 24.0 9 21 4309197 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 1.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 4.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
117059 4309198 1 4901 2015-11-15 21:50:18 4 6 1980.0 4.0 2 21 4309198 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
117060 4309202 6 64618 2015-11-15 21:51:54 4 6 1800.0 4.0 2 21 4309202 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
117061 4309208 1 60313 2015-11-15 22:10:09 4 6 3180.0 18.0 11 22 4309208 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 2.0 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 2.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
117062 4309209 1 18893 2015-11-15 22:17:32 4 6 1680.0 9.0 4 22 4309209 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 3.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

117063 rows × 177 columns

Train Test and Evaluation of the data

Here we look at two basic models such as the linear regression model vs the gradient boosted regressor

y = combined_train_data['time_difference'].values
X = combined_train_data.drop(['time_difference','trip_id','shopping_started_at'],axis=1)
X
store_id shopper_id day_segment day_of_week quantity department_name hour ('quantity', '25% OFF Supplements 8/14-8/16') ('quantity', '4th of July') ('quantity', 'Academy Awards') ('quantity', 'Alcohol') ('quantity', 'All It Takes to Bake!') ('quantity', 'Aquatics') ('quantity', 'BBQ Favorites') ('quantity', 'Babies') ('quantity', 'Bakery') ('quantity', 'Beverages') ('quantity', 'Bi-Rite Creamery') ('quantity', "Bi-Rite's Winter Favorites!") ('quantity', 'Bird') ('quantity', 'Breakfast') ('quantity', 'Bulk') ('quantity', 'Burning Man Essentials') ('quantity', 'Business Items') ('quantity', "Buyers' Picks") ('quantity', 'Canned Goods') ('quantity', 'Cat') ('quantity', 'Cheese') ('quantity', 'Christmas & NYE Menu') ('quantity', 'Costumes') ('quantity', 'Dairy & Eggs') ('quantity', 'Deli') ('quantity', 'Dog') ('quantity', 'Dry Goods & Pasta') ('quantity', 'Fall Wine, Beer, & Spirits') ('quantity', "Father's Day") ('quantity', 'Fill the Grill') ('quantity', 'Find it at Target') ('quantity', 'FitMarket') ('quantity', 'Floral') ... ('item_id', 'Holiday Essentials') ('item_id', 'Holiday Favorites') ('item_id', 'Holiday Turkeys') ('item_id', 'Holidays') ('item_id', 'Household') ('item_id', 'Ice Cream Social!') ('item_id', 'International') ('item_id', 'Local') ('item_id', 'Local Favorites') ('item_id', 'Meat & Seafood') ('item_id', "Mother's Day") ('item_id', "New Year's Eve Extravaganza!") ('item_id', 'Newly Added') ('item_id', 'Olives, Gourmet Cheese, Salads') ('item_id', 'Our Brands') ('item_id', 'Pantry') ('item_id', 'Passover & Easter') ('item_id', 'Personal Care') ('item_id', 'Pets') ('item_id', 'Popular') ('item_id', 'Produce') ('item_id', 'Ready to Cook') ('item_id', 'Ready to Eat') ('item_id', 'Reptile') ('item_id', 'Rosh Hashanah & Yom Kippur') ('item_id', 'Seasonal') ('item_id', 'Small Animal') ('item_id', 'Smoothie Central') ('item_id', 'Snacks') ('item_id', "St. Patrick's Day Specials") ('item_id', 'Star Wars') ('item_id', 'Summer Drinks') ('item_id', 'Super Bowl Party') ('item_id', 'TEST SPECIAL AISLE') ('item_id', 'Thanksgiving') ('item_id', 'Thanksgiving A to Z') ('item_id', 'Travel') ('item_id', "Valentine's Day Specials") ('item_id', "Valentine's- Made with Love!") ('item_id', 'Vitamins & Supplements')
0 1 3775 2 1 183.0 8 7 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 8.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 28.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 5.0 11.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 7.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
1 1 4362 2 1 9.0 5 7 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2 1 10720 2 1 21.0 6 7 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 4.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 0.0 5.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
3 6 48539 2 1 39.0 11 7 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 2.0 7.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 7.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 4.0 3.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
4 115 43442 2 1 36.0 14 7 0.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 2.0 2.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 8.0 1.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 4.0 4.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
117058 6 66865 4 6 24.0 9 21 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 1.0 0.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 4.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
117059 1 4901 4 6 4.0 2 21 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
117060 6 64618 4 6 4.0 2 21 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
117061 1 60313 4 6 18.0 11 22 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 2.0 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 3.0 0.0 0.0 0.0 2.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
117062 1 18893 4 6 9.0 4 22 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 2.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 3.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

117063 rows × 173 columns

# y = train_table['time_difference'].values
# #X = collapsedTrainData[['shopper_id','store_id','hour','day_of_week','quantity','num_dept_visited']]
# X = train_table.drop(['time_difference','fulfillment_model','shopping_ended_at','shopping_started_at','department_name'],axis=1)
# X
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Lasso
from sklearn.model_selection import train_test_split

X_train,X_val,y_train,y_val = train_test_split(X,y,test_size = 0.20)

reg_9 = LinearRegression().fit(X_train,y_train)

print('The R2 score for this model is', reg_9.score(X_val,y_val))

# A regularized version of the Linear Regression
lasso_params = {'alpha':[0.02, 0.024, 0.025, 0.026, 0.03]}

reg = GridSearchCV(sklearn.linear_model.Lasso(), param_grid=lasso_params, verbose = 2, cv = 3, n_jobs = -1,).fit(X_train, y_train).best_estimator_
 
print('The R2 score for this model is', reg.score(X_val,y_val))
The R2 score for this model is 0.32184440260690717
Fitting 3 folds for each of 5 candidates, totalling 15 fits
[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.
[Parallel(n_jobs=-1)]: Done  15 out of  15 | elapsed:  3.6min finished
The R2 score for this model is 0.3222553823936367
/usr/local/lib/python3.6/dist-packages/sklearn/linear_model/_coordinate_descent.py:476: ConvergenceWarning: Objective did not converge. You might want to increase the number of iterations. Duality gap: 58862189212.047, tolerance: 19089258.94276818
  positive)
from sklearn.ensemble import GradientBoostingRegressor
GBRegressor = GradientBoostingRegressor(learning_rate = 0.1,n_estimators = 100,max_depth=3,min_samples_split = 2,loss='ls')
GBRegressor.fit(X_train,y_train)
print('The GB R2 score is: ', GBRegressor.score(X_val,y_val))
The GB R2 score is:  0.36835182787786536
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import GradientBoostingRegressor


param_grid = {
    'learning_rate': [0.3],
    'max_depth': [4],
    'n_estimators': [2000],
    'min_samples_split':[5],
    'loss':['ls']
}

GBRegressor = GradientBoostingRegressor()

grid_search = GridSearchCV(estimator = GBRegressor, param_grid = param_grid, 
                          cv = 3, n_jobs = -1, verbose = 2)
grid_search.fit(X_train,y_train)
print('The GB R2 score is: ', grid_search.score(X_val,y_val))
Fitting 3 folds for each of 1 candidates, totalling 3 fits
[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.
[Parallel(n_jobs=-1)]: Done   3 out of   3 | elapsed: 17.7min finished
GridSearchCV(cv=3, error_score=nan,
             estimator=GradientBoostingRegressor(alpha=0.9, ccp_alpha=0.0,
                                                 criterion='friedman_mse',
                                                 init=None, learning_rate=0.1,
                                                 loss='ls', max_depth=3,
                                                 max_features=None,
                                                 max_leaf_nodes=None,
                                                 min_impurity_decrease=0.0,
                                                 min_impurity_split=None,
                                                 min_samples_leaf=1,
                                                 min_samples_split=2,
                                                 min_weight_fraction_leaf=0.0,
                                                 n_estimators=100,
                                                 n_iter_no_change=None,
                                                 presort='deprecated',
                                                 random_state=None,
                                                 subsample=1.0, tol=0.0001,
                                                 validation_fraction=0.1,
                                                 verbose=0, warm_start=False),
             iid='deprecated', n_jobs=-1,
             param_grid={'learning_rate': [0.3], 'loss': ['ls'],
                         'max_depth': [4], 'min_samples_split': [5],
                         'n_estimators': [2000]},
             pre_dispatch='2*n_jobs', refit=True, return_train_score=False,
             scoring=None, verbose=2)
grid_search.score(X_val,y_val)
0.4500336622192095
from sklearn.model_selection import GridSearchCV
import xgboost as xgb
param_grid = {
    'learning_rate': [0.05],
    'n_estimators': [1000]
}

XGBR = xgb.XGBRegressor()
XGBR.fit(X_train,y_train, verbose=False)

grid_search_xg = GridSearchCV(estimator = XGBR, param_grid = param_grid, 
                          cv = 3, n_jobs = -1, verbose = 2)
grid_search_xg.fit(X, y)
print('The XG R2 score is: ', grid_search_xg.score(X_val,y_val))
[12:56:08] WARNING: /workspace/src/objective/regression_obj.cu:152: reg:linear is now deprecated in favor of reg:squarederror.
Fitting 3 folds for each of 1 candidates, totalling 3 fits
[Parallel(n_jobs=-1)]: Using backend LokyBackend with 4 concurrent workers.
[Parallel(n_jobs=-1)]: Done   3 out of   3 | elapsed:  6.4min finished
[13:03:09] WARNING: /workspace/src/objective/regression_obj.cu:152: reg:linear is now deprecated in favor of reg:squarederror.
The XG R2 score is:  0.43571771162071565
dictonary = {'Linear_Regression': 0.32184440260690717, 'Linear_Regression_CV':0.322 , 'GBR_CV': 0.4500336622192095, 'GBR': 0.36, 'XG_CV': 0.43571771162071565}
new_dictonary = {str(k1):v1 for k1,v1 in dictonary.items()}
plt.figure(figsize=(15,5))
plt.bar(new_dictonary.keys(), new_dictonary.values(), width=.5, color='g')
<BarContainer object of 5 artists>
# A possible future work is learning more about the model, how is behaves performs and 
# why does it predict the way it does? This goes into the whole
# theory of XAI where we better want to understand the best way to explore the model itself
# A simple approach would be to visulize gradients and the residuals that is being learnt by the model
# Todo
# take care of nans 
# merge item id into a list and quantity sum 
# segment of the day
# remove the percent missing values
# sum the quantity value 
# One hot encoding of department and adding to a list 
# one row per trip id 
# drop trip_id, shopper_id
# add segment of the data 
# day of the weekend vs weekday or day of the week 
# Without null values 
# Plot the residuals, longer durations and need more features 
# modelling skills and caliberations 
# EDA, visualizations 
# histogram of quantity, lesser quantity more or more quantitity less 
# K fold with different random search and different parameters 
 

Test set evaluation

test_table.head(9)
trip_id shopper_id fulfillment_model store_id shopping_started_at
0 4310899 60930 model_2 123 2015-11-16 07:00:12
1 4310904 59815 model_2 123 2015-11-16 07:00:12
2 4310907 60878 model_2 123 2015-11-16 07:00:13
3 4310911 60879 model_2 123 2015-11-16 07:00:13
4 4310328 66726 model_1 1 2015-11-16 07:01:08
5 4310306 524 model_1 6 2015-11-16 07:04:08
6 4311006 68052 model_1 115 2015-11-16 07:05:15
7 4310319 63455 model_1 1 2015-11-16 07:11:37
8 4311215 1678 model_1 1 2015-11-16 07:19:12
test_table['fulfillment_model']=test_table['fulfillment_model'].astype('str')