Pemodelan Machine Learning dalam memprediksi Jumlah Pesanan Perusahaan Layanan Pengiriman Makanan

Panji Lokajaya Arifa

Latar Belakang

Perusahaan layanan pengiriman makanan beroperasi di berbagai kota dengan pusat pemenuhan (fulfillment centers) yang bertugas menyiapkan dan mengirimkan pesanan kepada pelanggan. Perencanaan permintaan yang akurat ini menjadi sangat penting karena bahan baku makanan bersifat mudah rusak dan harus dipasok secara mingguan. Selain itu, perkiraan permintaan yang baik membantu dalam efisiensi operasional, seperti pengelolaan stok bahan baku dan alokasi tenaga kerja. Dengan memanfaatkan data historis pesanan, harga, promosi, dan faktor lainnya, perusahaan ingin membangun model prediksi yang dapat memperkirakan jumlah pesanan secara akurat untuk beberapa minggu ke depan.

Tujuan

Membangun model untuk memprediksi jumlah pesanan (Num_Orders) untuk 10 minggu kedepan yaitu pada minggu 136-145 berdasarkan data historis yang diberikan sehingga perusahaan dapat meningkatkan efisiensi operasional seperti pengadaan bahan baku dan perencanaan tenaga kerja serta meningkatkan kepuasaan pelanggan dengan memastikan ketersediaan makanan tanpa keterlambatan.

Package

#library(skimr)
library(DataExplorer)
library(tidyverse)
Warning: package 'readr' was built under R version 4.4.3
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.6
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.5.1     ✔ tibble    3.2.1
✔ lubridate 1.9.3     ✔ tidyr     1.3.1
✔ purrr     1.0.2     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ROSE)
Warning: package 'ROSE' was built under R version 4.4.2
Loaded ROSE 0.0-4
library(xgboost)

Attaching package: 'xgboost'

The following object is masked from 'package:dplyr':

    slice
library(lightgbm)
Warning: package 'lightgbm' was built under R version 4.4.2
library(randomForest)
Warning: package 'randomForest' was built under R version 4.4.2
randomForest 4.7-1.2
Type rfNews() to see new features/changes/bug fixes.

Attaching package: 'randomForest'

The following object is masked from 'package:dplyr':

    combine

The following object is masked from 'package:ggplot2':

    margin
library(Metrics)
Warning: package 'Metrics' was built under R version 4.4.2
library(forecast)
Warning: package 'forecast' was built under R version 4.4.2
Registered S3 method overwritten by 'quantmod':
  method            from
  as.zoo.data.frame zoo 

Attaching package: 'forecast'

The following object is masked from 'package:Metrics':

    accuracy
library(GGally)
Warning: package 'GGally' was built under R version 4.4.2
Registered S3 method overwritten by 'GGally':
  method from   
  +.gg   ggplot2
library(corrplot)
corrplot 0.95 loaded

#Import Data

train_data <- read.csv("train.csv")
test_data <- read.csv("test.csv")
meal_data <- read.csv("meal_info.csv")
fulfil_data <- read.csv("fulfilment_center_info.csv")
submission <- read.csv("submission.csv")

Eksplorasi Data

glimpse(train_data)
Rows: 456,548
Columns: 9
$ id                    <int> 1379560, 1466964, 1346989, 1338232, 1448490, 127…
$ week                  <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
$ center_id             <int> 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, …
$ meal_id               <int> 1885, 1993, 2539, 2139, 2631, 1248, 1778, 1062, …
$ checkout_price        <dbl> 136.83, 136.83, 134.86, 339.50, 243.50, 251.23, …
$ base_price            <dbl> 152.29, 135.83, 135.86, 437.53, 242.50, 252.23, …
$ emailer_for_promotion <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, …
$ homepage_featured     <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, …
$ num_orders            <int> 177, 270, 189, 54, 40, 28, 190, 391, 472, 676, 8…
glimpse(test_data)
Rows: 32,821
Columns: 8
$ id                    <int> 1017495, 1395634, 1007493, 1042952, 1022147, 119…
$ week                  <int> 136, 136, 136, 136, 136, 136, 136, 136, 136, 136…
$ center_id             <int> 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, …
$ meal_id               <int> 1885, 1993, 2539, 2631, 1248, 1778, 1062, 2707, …
$ checkout_price        <dbl> 148.44, 151.38, 152.35, 96.03, 97.00, 164.90, 17…
$ base_price            <dbl> 148.44, 151.38, 151.35, 165.93, 165.93, 164.90, …
$ emailer_for_promotion <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, …
$ homepage_featured     <int> 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, …
glimpse(meal_data)
Rows: 51
Columns: 3
$ meal_id  <int> 1885, 1993, 2539, 1248, 2631, 1311, 1062, 1778, 1803, 1198, 2…
$ category <chr> "Beverages", "Beverages", "Beverages", "Beverages", "Beverage…
$ cuisine  <chr> "Thai", "Thai", "Thai", "Indian", "Indian", "Thai", "Italian"…
glimpse(fulfil_data)
Rows: 77
Columns: 5
$ center_id   <int> 11, 13, 124, 66, 94, 64, 129, 139, 88, 143, 101, 86, 32, 1…
$ city_code   <int> 679, 590, 590, 648, 632, 553, 593, 693, 526, 562, 699, 699…
$ region_code <int> 56, 56, 56, 34, 34, 77, 77, 34, 34, 77, 85, 85, 34, 77, 34…
$ center_type <chr> "TYPE_A", "TYPE_B", "TYPE_C", "TYPE_A", "TYPE_C", "TYPE_A"…
$ op_area     <dbl> 3.7, 6.7, 4.0, 4.1, 3.6, 4.4, 3.9, 2.8, 4.1, 3.8, 2.8, 4.0…
str(train_data)
'data.frame':   456548 obs. of  9 variables:
 $ id                   : int  1379560 1466964 1346989 1338232 1448490 1270037 1191377 1499955 1025244 1054194 ...
 $ week                 : int  1 1 1 1 1 1 1 1 1 1 ...
 $ center_id            : int  55 55 55 55 55 55 55 55 55 55 ...
 $ meal_id              : int  1885 1993 2539 2139 2631 1248 1778 1062 2707 1207 ...
 $ checkout_price       : num  137 137 135 340 244 ...
 $ base_price           : num  152 136 136 438 242 ...
 $ emailer_for_promotion: int  0 0 0 0 0 0 0 0 0 0 ...
 $ homepage_featured    : int  0 0 0 0 0 0 0 0 0 1 ...
 $ num_orders           : int  177 270 189 54 40 28 190 391 472 676 ...
str(test_data)
'data.frame':   32821 obs. of  8 variables:
 $ id                   : int  1017495 1395634 1007493 1042952 1022147 1191480 1082166 1340029 1423809 1153607 ...
 $ week                 : int  136 136 136 136 136 136 136 136 136 136 ...
 $ center_id            : int  55 55 55 55 55 55 55 55 55 55 ...
 $ meal_id              : int  1885 1993 2539 2631 1248 1778 1062 2707 1207 1230 ...
 $ checkout_price       : num  148 151 152 96 97 ...
 $ base_price           : num  148 151 151 166 166 ...
 $ emailer_for_promotion: int  0 0 0 0 0 0 0 0 0 0 ...
 $ homepage_featured    : int  0 0 0 0 0 0 0 0 1 0 ...
str(meal_data)
'data.frame':   51 obs. of  3 variables:
 $ meal_id : int  1885 1993 2539 1248 2631 1311 1062 1778 1803 1198 ...
 $ category: chr  "Beverages" "Beverages" "Beverages" "Beverages" ...
 $ cuisine : chr  "Thai" "Thai" "Thai" "Indian" ...
str(fulfil_data)
'data.frame':   77 obs. of  5 variables:
 $ center_id  : int  11 13 124 66 94 64 129 139 88 143 ...
 $ city_code  : int  679 590 590 648 632 553 593 693 526 562 ...
 $ region_code: int  56 56 56 34 34 77 77 34 34 77 ...
 $ center_type: chr  "TYPE_A" "TYPE_B" "TYPE_C" "TYPE_A" ...
 $ op_area    : num  3.7 6.7 4 4.1 3.6 4.4 3.9 2.8 4.1 3.8 ...

Menggabungkan data

datatrain <- merge(train_data, meal_data, by = "meal_id")
train_data <- merge(datatrain, fulfil_data, by = "center_id")

datatest <- merge(test_data, meal_data, by = "meal_id")
test_data <- merge(datatest, fulfil_data, by = "center_id")

head(train_data)
  center_id meal_id      id week checkout_price base_price
1        10    2126 1193219   22         529.68     529.68
2        10    1778 1367365   29         181.39     183.39
3        10    2139 1314059  141         283.24     285.24
4        10    2664 1136385  119         302.64     304.64
5        10    1311 1247333  108         166.90     165.90
6        10    2760 1245112   19         241.53     241.53
  emailer_for_promotion homepage_featured num_orders     category cuisine
1                     0                 0        256        Pasta Italian
2                     0                 0        365    Beverages Italian
3                     0                 0        161    Beverages  Indian
4                     0                 0        852        Salad Italian
5                     0                 0        811       Extras    Thai
6                     0                 1        473 Other Snacks    Thai
  city_code region_code center_type op_area
1       590          56      TYPE_B     6.3
2       590          56      TYPE_B     6.3
3       590          56      TYPE_B     6.3
4       590          56      TYPE_B     6.3
5       590          56      TYPE_B     6.3
6       590          56      TYPE_B     6.3

Mengecek Missing Value dan duplicate

missing_values <- colSums(is.na(train_data))
missing_table <- data.frame(
  Column = names(missing_values),
  Missing_Values = missing_values
)

print(missing_table)
                                     Column Missing_Values
center_id                         center_id              0
meal_id                             meal_id              0
id                                       id              0
week                                   week              0
checkout_price               checkout_price              0
base_price                       base_price              0
emailer_for_promotion emailer_for_promotion              0
homepage_featured         homepage_featured              0
num_orders                       num_orders              0
category                           category              0
cuisine                             cuisine              0
city_code                         city_code              0
region_code                     region_code              0
center_type                     center_type              0
op_area                             op_area              0
sum(duplicated(train_data))
[1] 0

Distribusi dataset

plot_intro(train_data, ggtheme = theme_classic())

Dapat dilihat bahwa dataset menggunakan 36.6 MB memori yang terdiri dari 20% kolom berisi kategori dan 80% kolom berisi numerik. Tidak ada kolom atau observasi yang sepenuhnya hilang dan terlihat 100% baris lengkap tanpa ada missing values, sehingga dataset siap untuk dianalisis.

summary(train_data)
   center_id         meal_id           id               week       
 Min.   : 10.00   Min.   :1062   Min.   :1000000   Min.   :  1.00  
 1st Qu.: 43.00   1st Qu.:1558   1st Qu.:1124999   1st Qu.: 39.00  
 Median : 76.00   Median :1993   Median :1250184   Median : 76.00  
 Mean   : 82.11   Mean   :2024   Mean   :1250096   Mean   : 74.77  
 3rd Qu.:110.00   3rd Qu.:2539   3rd Qu.:1375140   3rd Qu.:111.00  
 Max.   :186.00   Max.   :2956   Max.   :1499999   Max.   :145.00  
 checkout_price     base_price     emailer_for_promotion homepage_featured
 Min.   :  2.97   Min.   : 55.35   Min.   :0.00000       Min.   :0.0000   
 1st Qu.:228.95   1st Qu.:243.50   1st Qu.:0.00000       1st Qu.:0.0000   
 Median :296.82   Median :310.46   Median :0.00000       Median :0.0000   
 Mean   :332.24   Mean   :354.16   Mean   :0.08115       Mean   :0.1092   
 3rd Qu.:445.23   3rd Qu.:458.87   3rd Qu.:0.00000       3rd Qu.:0.0000   
 Max.   :866.27   Max.   :866.27   Max.   :1.00000       Max.   :1.0000   
   num_orders        category           cuisine            city_code    
 Min.   :   13.0   Length:456548      Length:456548      Min.   :456.0  
 1st Qu.:   54.0   Class :character   Class :character   1st Qu.:553.0  
 Median :  136.0   Mode  :character   Mode  :character   Median :596.0  
 Mean   :  261.9                                         Mean   :601.6  
 3rd Qu.:  324.0                                         3rd Qu.:651.0  
 Max.   :24299.0                                         Max.   :713.0  
  region_code    center_type           op_area     
 Min.   :23.00   Length:456548      Min.   :0.900  
 1st Qu.:34.00   Class :character   1st Qu.:3.600  
 Median :56.00   Mode  :character   Median :4.000  
 Mean   :56.61                      Mean   :4.084  
 3rd Qu.:77.00                      3rd Qu.:4.500  
 Max.   :93.00                      Max.   :7.000  
plot_density(train_data,
             ggtheme = theme_light(),
             geom_density_args = list("fill" = "blue", "alpha" = 0.5),
             ncol=5)

Distribusi Jumlah Pesanan

ggplot(train_data, aes(x = num_orders)) +
  geom_histogram(bins = 50, fill = "blue", alpha = 0.5) +
  labs(title = "Distribusi Jumlah Pesanan (num_orders)", x = "Jumlah Pesanan", y = "Frekuensi")

dapat dilihat dari histogram diatas bahwa sebaran data tidak normal dan terlihat bentuk condong ke kanan yang menunjukkan bahwa jumlah pesanan yang tinggi di banyak toko dibandingkan dengan toko yang jumlah pesanannya rendah, hal ini bisa disebabkan oleh jenis makanan populer atau promosi tertentu.

Jumlah pesanan berdasarkan kategori makanan

category_meal <- train_data%>%
  group_by(category) %>%
  summarise(total_num_orders = sum(num_orders))

ggplot(data = category_meal, aes(x = reorder(category, total_num_orders), y = total_num_orders, fill = as.factor(category))) +
  geom_bar(stat = "identity") +
  scale_fill_manual(values = rainbow(length(unique(category_meal$category)))) +  
  labs(title = "Jumlah Pesanan per Kategori Makanan",
       x = "Kategori Makanan",
       y = "Total Pesanan") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        legend.position = "none") 

Dapat dilihat bahwa jumlah pesanan berdasarkan kategori makanan menunjukkan Beverages memiliki jumlah pesanan tertinggi, diikuti oleh Rice Bowl dan Sandwich. Kategori makanan seperti Biryani, Fish, dan Soup memiliki jumlah pesanan paling rendah. Hal ini mengindikasikan bahwa minuman dan makanan cepat saji lebih diminati dibandingkan dengan hidangan utama tertentu, kemungkinan karena faktor kenyamanan dan preferensi pelanggan.

Jumlah pesanan per tipe center

center_type <- train_data%>%
  group_by(center_type) %>%
  summarise(total_num_orders = sum(num_orders))


ggplot(data = center_type, aes(x = reorder(as.factor(center_type), total_num_orders), y = total_num_orders, fill = as.factor(center_type))) +
  geom_bar(stat = "identity") +
  scale_fill_brewer(palette = "Set1") +
  labs(title = "Total Pesanan per Tipe Center",
       x = "Tipe Center",
       y = "Total Pesanan") +
  theme_minimal() +
  theme(legend.position = "none")

Dapat dilihat bahwa total jumlah pesanan berdasarkan tipe pusat pemenuhan menunjukkan Tipe A memiliki jumlah pesanan tertinggi, Tipe B berada di posisi tengah, sementara tipe C memiliki jumlah pesanan terendah. Hal ini mengindikasikan bahwa pusat tipe A memiliki permintaan tertinggi, kemungkinan karena cakupan area yang lebih luas atau efisiensi operasional yang lebih baik.

Jumlah pesanan berdasarkan asal makanan

cuisine <- train_data%>%
  group_by(cuisine) %>%
  summarise(total_num_orders = sum(num_orders))


ggplot(data = cuisine, aes(x = reorder(as.factor(cuisine), total_num_orders), y = total_num_orders, fill = as.factor(cuisine))) +
  geom_bar(stat = "identity") +
  scale_fill_brewer(palette = "Set1") +
  labs(title = "Total Pesanan per Asal Makanan",
       x = "Asal Makanan",
       y = "Total Pesanan") +
  theme_minimal() +
  theme(legend.position = "none")

Rata-Rata harga berdasarkan kategori makanan

avg_price_category <-train_data %>%
  group_by(category) %>%
  summarise(avg_price_category = mean(checkout_price, na.rm = TRUE)) %>%
  arrange(desc(avg_price_category))

ggplot(data = avg_price_category, aes(x = reorder(as.factor(category), avg_price_category), y = avg_price_category, fill = as.factor(category))) +
  geom_bar(stat = "identity") +
  geom_text(aes(label = round(avg_price_category, 4)), vjust = 0.5, size =3) +
  scale_fill_manual(values = c("#E41A1C", "#377EB8", "#4DAF4A", "#984EA3", "#FF7F00", 
                               "#FFFF33", "#A65628", "#F781BF", "#999999", "#66C2A5",
                               "#FC8D62", "#8DA0CB", "#E78AC3", "#A6D854")) +
  coord_flip() +
  labs(title = "Rata-rata harga per Kategori Makanan",
       x = "rata rata harga",
       y = "kategori") +
  theme_minimal() +
  theme(legend.position = "none")

Dapat dilihat dari histogram diatas bahwa kategori makanan Seafood, Pizza, dan Fish memiliki harga rata-rata tertinggi yang menunjukkan bahwa makanan berbasis ikan dan laut cenderung lebih mahal. Biryani, Dessert, dan Pasta berada di kategori menengah kemungkinan karena bahan premium. Sementara itu, Soup, Beverages, dan Extras memiliki harga rata-rata terendah kemungkinan karena porsi kecil atau bahan yang lebih murah.

Rata Rata harga berdasarkan asal makanan

avg_price_cuisine <-train_data %>%
  group_by(cuisine) %>%
  summarise(avg_price_cuisine = mean(base_price, na.rm = TRUE)) %>%
  arrange(desc(avg_price_cuisine))

ggplot(data = avg_price_cuisine, aes(x = reorder(as.factor(cuisine), avg_price_cuisine), y = avg_price_cuisine, fill = as.factor(cuisine))) +
  geom_bar(stat = "identity") +
  geom_text(aes(label = round(avg_price_cuisine, 4)), vjust = 0.5, size =4) +
  scale_fill_brewer(palette = "Set1") +
  coord_flip() +
  labs(title = "Rata-rata Harga asli per Asal Makanan",
       x = "Rata rata harga",
       y = "Asal Makanan") +
  theme_minimal() +
  theme(legend.position = "none")

Dapat dilihat pada histogram diatas bahwa makanan yang berasal dari continental memiliki rata rata harga asli yang tinggi sekitar di harga $557.63, kemungkinan karena bahan premium atau porsi besar. sementara makanan yang berasal dari Indian dan Italian memiliki harga rata-rata sedang sementara Thai memiliki harga rata-rata terendah 224.1071 kemungkinan karena bahan baku yang lebih terjangkau atau porsi yang lebih kecil.

Tren Jumlah Pesanan Per Minggu

# Buat dataset weekly_trend
weekly_trend <- train_data %>%
  group_by(week) %>%
  summarise(avg_orders = mean(num_orders, na.rm = TRUE))

ggplot(data = weekly_trend, aes(x = week, y = avg_orders)) +
  geom_line(color = "blue", size = 1) +
  geom_smooth(method = "loess", color = "red") +
  labs(title = "Tren Rata-rata Pesanan per Minggu",
       x = "Minggu",
       y = "Rata-rata Pesanan") +
  theme_minimal()
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.
`geom_smooth()` using formula = 'y ~ x'

Dapat dilihat bawha plot diatas menunjukkan tren rata-rata jumlah pesanan per minggu dengan garis biru yang mepresentasikan fluktuasi pesanan dari waktu ke waktu. Pola musiman terlihat dengan lonjakan dan penurunan pesanan yang cukup tajam. Garis merah menunjukkan tren linier yang cenderung sedikit menurun dan mengindikasikan bahwa rata-rata pesanan mengalami penurunan bertahap seiring waktu. Namun, terdapat variabilitas yang tinggi dalam data sehingga faktor eksternal seperti promosi atau musim bisa mempengaruhi jumlah pesanan secara signifikan.

Pre Processing

Plot Normalitas

# Membuat fungsi untuk QQ Plot dengan ggplot2
qq_plot <- function(data, column_name) {
  ggplot(data, aes(sample = !!sym(column_name))) +
    stat_qq() +
    stat_qq_line(color = "red") +
    labs(title = paste("QQ Plot untuk", column_name),
         x = "Theoretical Quantiles",
         y = "Sample Quantiles") +
    theme_minimal()
}

# Buat QQ Plot untuk setiap variabel
qq_plot(train_data, "num_orders")

qq_plot(train_data, "checkout_price")

qq_plot(train_data, "base_price")

qq_plot(train_data, "op_area")

# Log transformasi untuk num_orders
train_data <- train_data %>%
  mutate(log_num_orders = log1p(num_orders))

# QQ Plot setelah log transformasi
ggplot(train_data, aes(sample = log_num_orders)) +
  stat_qq() +
  stat_qq_line(color = "red") +
  labs(title = "QQ Plot untuk Log-Transformed num_orders",
       x = "Theoretical Quantiles",
       y = "Sample Quantiles") +
  theme_minimal()

ggplot(train_data, aes(x = log_num_orders)) +
  geom_histogram(bins = 50, fill = "red", color = "black", alpha = 0.7) +
  labs(title = "Distribusi Log-Transformed Jumlah Pesanan",
       x = "Log(1 + num_orders)",
       y = "Frekuensi") +
  theme_minimal()

library(dplyr)
library(xgboost)
library(caret)
Loading required package: lattice

Attaching package: 'caret'
The following objects are masked from 'package:Metrics':

    precision, recall
The following object is masked from 'package:purrr':

    lift
library(zoo)
Warning: package 'zoo' was built under R version 4.4.2

Attaching package: 'zoo'
The following objects are masked from 'package:base':

    as.Date, as.Date.numeric

Feeature Engineering

# Transformasi log untuk num_orders agar distribusi lebih normal
train_data <- train_data %>%
  mutate(
    log_num_orders = log1p(num_orders), 
    price_difference = base_price - checkout_price,  
    discount_percentage = (price_difference / base_price) * 100,  
    discount = ifelse(price_difference > 0, 1, 0)  
  )

# Pastikan variabel kategori dikonversi ke faktor
train_data <- train_data %>%
  mutate(across(c(category, cuisine, center_type), as.factor))
# Split data untuk validasi model
set.seed(123)
train_index <- createDataPartition(train_data$log_num_orders, p = 0.8, list = FALSE)
train_set <- train_data[train_index, ]
test_set <- train_data[-train_index, ]
#distribusi num_orders setelah transformasi
ggplot(train_data, aes(x = log_num_orders)) +
  geom_histogram(bins = 30, fill = "blue", color = "black") +
  labs(title = "Distribusi Log Transformasi Jumlah Pesanan")

Pemodelan

Regresi Linear

library(caret)
# Model regresi linear dengan log-transformasi num_orders
model_reg <- lm(log_num_orders ~ week + checkout_price + op_area + discount_percentage + 
                emailer_for_promotion + homepage_featured + city_code + region_code + 
                category + cuisine + center_type, data = train_set)

summary(model_reg)

Call:
lm(formula = log_num_orders ~ week + checkout_price + op_area + 
    discount_percentage + emailer_for_promotion + homepage_featured + 
    city_code + region_code + category + cuisine + center_type, 
    data = train_set)

Residuals:
    Min      1Q  Median      3Q     Max 
-3.8859 -0.4448  0.0469  0.4896  3.5644 

Coefficients:
                        Estimate Std. Error  t value Pr(>|t|)    
(Intercept)            4.573e+00  1.534e-02  298.021  < 2e-16 ***
week                  -9.138e-05  2.822e-05   -3.239   0.0012 ** 
checkout_price        -2.554e-03  2.567e-05  -99.493  < 2e-16 ***
op_area                2.227e-01  1.235e-03  180.346  < 2e-16 ***
discount_percentage    5.252e-03  1.462e-04   35.918  < 2e-16 ***
emailer_for_promotion  4.121e-01  5.298e-03   77.784  < 2e-16 ***
homepage_featured      5.316e-01  4.220e-03  125.960  < 2e-16 ***
city_code              1.926e-04  1.795e-05   10.733  < 2e-16 ***
region_code            2.131e-03  6.614e-05   32.227  < 2e-16 ***
categoryBiryani       -5.943e-02  9.275e-03   -6.408 1.48e-10 ***
categoryDesert         5.026e-01  8.768e-03   57.325  < 2e-16 ***
categoryExtras        -4.522e-01  8.499e-03  -53.211  < 2e-16 ***
categoryFish          -2.380e-01  1.062e-02  -22.405  < 2e-16 ***
categoryOther Snacks  -9.427e-01  7.275e-03 -129.584  < 2e-16 ***
categoryPasta         -1.553e+00  8.678e-03 -178.908  < 2e-16 ***
categoryPizza          5.613e-01  9.030e-03   62.163  < 2e-16 ***
categoryRice Bowl      2.404e+00  6.938e-03  346.452  < 2e-16 ***
categorySalad          1.876e-01  6.918e-03   27.123  < 2e-16 ***
categorySandwich       3.143e-01  6.772e-03   46.411  < 2e-16 ***
categorySeafood       -2.621e-01  9.614e-03  -27.261  < 2e-16 ***
categorySoup          -1.592e+00  8.630e-03 -184.418  < 2e-16 ***
categoryStarters      -8.200e-01  7.398e-03 -110.851  < 2e-16 ***
cuisineIndian         -1.299e+00  7.275e-03 -178.508  < 2e-16 ***
cuisineItalian         4.995e-01  7.518e-03   66.434  < 2e-16 ***
cuisineThai            4.280e-01  8.525e-03   50.210  < 2e-16 ***
center_typeTYPE_B      1.214e-01  3.120e-03   38.895  < 2e-16 ***
center_typeTYPE_C     -1.887e-01  3.133e-03  -60.228  < 2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.7021 on 365213 degrees of freedom
Multiple R-squared:  0.6599,    Adjusted R-squared:  0.6599 
F-statistic: 2.726e+04 on 26 and 365213 DF,  p-value: < 2.2e-16

XGboost

train_matrix <- model.matrix(log_num_orders ~ ., data = train_set)[,-1]
test_matrix <- model.matrix(log_num_orders ~ ., data = test_set)[,-1]

train_label <- train_set$log_num_orders
test_label <- test_set$log_num_orders

#Model XGBoost
xgb_model <- xgboost(data = train_matrix, 
                     label = train_label, 
                     nrounds = 500, 
                     objective = "reg:squarederror", 
                     eta = 0.06, 
                     max_depth = 6)
[1] train-rmse:4.277304 
[2] train-rmse:4.020710 
[3] train-rmse:3.779509 
[4] train-rmse:3.552777 
[5] train-rmse:3.339648 
[6] train-rmse:3.139303 
[7] train-rmse:2.950978 
[8] train-rmse:2.773950 
[9] train-rmse:2.607542 
[10]    train-rmse:2.451117 
[11]    train-rmse:2.304077 
[12]    train-rmse:2.165857 
[13]    train-rmse:2.035928 
[14]    train-rmse:1.913795 
[15]    train-rmse:1.798987 
[16]    train-rmse:1.691068 
[17]    train-rmse:1.589623 
[18]    train-rmse:1.494263 
[19]    train-rmse:1.404625 
[20]    train-rmse:1.320363 
[21]    train-rmse:1.241157 
[22]    train-rmse:1.166702 
[23]    train-rmse:1.096713 
[24]    train-rmse:1.030924 
[25]    train-rmse:0.969081 
[26]    train-rmse:0.910947 
[27]    train-rmse:0.856302 
[28]    train-rmse:0.804934 
[29]    train-rmse:0.756648 
[30]    train-rmse:0.711258 
[31]    train-rmse:0.668592 
[32]    train-rmse:0.628484 
[33]    train-rmse:0.590783 
[34]    train-rmse:0.555344 
[35]    train-rmse:0.522030 
[36]    train-rmse:0.490715 
[37]    train-rmse:0.461279 
[38]    train-rmse:0.433608 
[39]    train-rmse:0.407597 
[40]    train-rmse:0.383147 
[41]    train-rmse:0.360163 
[42]    train-rmse:0.338559 
[43]    train-rmse:0.318250 
[44]    train-rmse:0.299159 
[45]    train-rmse:0.281214 
[46]    train-rmse:0.264345 
[47]    train-rmse:0.248488 
[48]    train-rmse:0.233583 
[49]    train-rmse:0.219572 
[50]    train-rmse:0.206401 
[51]    train-rmse:0.194020 
[52]    train-rmse:0.182382 
[53]    train-rmse:0.171442 
[54]    train-rmse:0.161158 
[55]    train-rmse:0.151491 
[56]    train-rmse:0.142405 
[57]    train-rmse:0.133863 
[58]    train-rmse:0.125834 
[59]    train-rmse:0.118286 
[60]    train-rmse:0.111191 
[61]    train-rmse:0.104522 
[62]    train-rmse:0.098253 
[63]    train-rmse:0.092360 
[64]    train-rmse:0.086820 
[65]    train-rmse:0.081613 
[66]    train-rmse:0.076718 
[67]    train-rmse:0.072117 
[68]    train-rmse:0.067792 
[69]    train-rmse:0.063726 
[70]    train-rmse:0.059905 
[71]    train-rmse:0.056312 
[72]    train-rmse:0.052935 
[73]    train-rmse:0.049761 
[74]    train-rmse:0.046777 
[75]    train-rmse:0.043972 
[76]    train-rmse:0.041336 
[77]    train-rmse:0.038857 
[78]    train-rmse:0.036527 
[79]    train-rmse:0.034338 
[80]    train-rmse:0.032279 
[81]    train-rmse:0.030344 
[82]    train-rmse:0.028525 
[83]    train-rmse:0.026815 
[84]    train-rmse:0.025208 
[85]    train-rmse:0.023697 
[86]    train-rmse:0.022277 
[87]    train-rmse:0.020943 
[88]    train-rmse:0.019688 
[89]    train-rmse:0.018508 
[90]    train-rmse:0.017400 
[91]    train-rmse:0.016358 
[92]    train-rmse:0.015378 
[93]    train-rmse:0.014458 
[94]    train-rmse:0.013592 
[95]    train-rmse:0.012779 
[96]    train-rmse:0.012014 
[97]    train-rmse:0.011296 
[98]    train-rmse:0.010620 
[99]    train-rmse:0.009986 
[100]   train-rmse:0.009389 
[101]   train-rmse:0.008828 
[102]   train-rmse:0.008301 
[103]   train-rmse:0.007806 
[104]   train-rmse:0.007340 
[105]   train-rmse:0.006903 
[106]   train-rmse:0.006492 
[107]   train-rmse:0.006105 
[108]   train-rmse:0.005742 
[109]   train-rmse:0.005401 
[110]   train-rmse:0.005081 
[111]   train-rmse:0.004780 
[112]   train-rmse:0.004497 
[113]   train-rmse:0.004231 
[114]   train-rmse:0.003982 
[115]   train-rmse:0.003747 
[116]   train-rmse:0.003527 
[117]   train-rmse:0.003320 
[118]   train-rmse:0.003126 
[119]   train-rmse:0.002944 
[120]   train-rmse:0.002773 
[121]   train-rmse:0.002613 
[122]   train-rmse:0.002462 
[123]   train-rmse:0.002321 
[124]   train-rmse:0.002189 
[125]   train-rmse:0.002065 
[126]   train-rmse:0.001949 
[127]   train-rmse:0.001840 
[128]   train-rmse:0.001737 
[129]   train-rmse:0.001642 
[130]   train-rmse:0.001553 
[131]   train-rmse:0.001469 
[132]   train-rmse:0.001391 
[133]   train-rmse:0.001318 
[134]   train-rmse:0.001250 
[135]   train-rmse:0.001187 
[136]   train-rmse:0.001128 
[137]   train-rmse:0.001073 
[138]   train-rmse:0.001022 
[139]   train-rmse:0.000974 
[140]   train-rmse:0.000930 
[141]   train-rmse:0.000889 
[142]   train-rmse:0.000851 
[143]   train-rmse:0.000816 
[144]   train-rmse:0.000784 
[145]   train-rmse:0.000753 
[146]   train-rmse:0.000725 
[147]   train-rmse:0.000700 
[148]   train-rmse:0.000677 
[149]   train-rmse:0.000656 
[150]   train-rmse:0.000636 
[151]   train-rmse:0.000617 
[152]   train-rmse:0.000600 
[153]   train-rmse:0.000586 
[154]   train-rmse:0.000572 
[155]   train-rmse:0.000559 
[156]   train-rmse:0.000548 
[157]   train-rmse:0.000538 
[158]   train-rmse:0.000528 
[159]   train-rmse:0.000520 
[160]   train-rmse:0.000512 
[161]   train-rmse:0.000505 
[162]   train-rmse:0.000497 
[163]   train-rmse:0.000490 
[164]   train-rmse:0.000485 
[165]   train-rmse:0.000479 
[166]   train-rmse:0.000474 
[167]   train-rmse:0.000470 
[168]   train-rmse:0.000466 
[169]   train-rmse:0.000462 
[170]   train-rmse:0.000457 
[171]   train-rmse:0.000454 
[172]   train-rmse:0.000450 
[173]   train-rmse:0.000447 
[174]   train-rmse:0.000445 
[175]   train-rmse:0.000443 
[176]   train-rmse:0.000441 
[177]   train-rmse:0.000439 
[178]   train-rmse:0.000437 
[179]   train-rmse:0.000436 
[180]   train-rmse:0.000434 
[181]   train-rmse:0.000433 
[182]   train-rmse:0.000431 
[183]   train-rmse:0.000430 
[184]   train-rmse:0.000429 
[185]   train-rmse:0.000428 
[186]   train-rmse:0.000427 
[187]   train-rmse:0.000426 
[188]   train-rmse:0.000425 
[189]   train-rmse:0.000424 
[190]   train-rmse:0.000422 
[191]   train-rmse:0.000421 
[192]   train-rmse:0.000419 
[193]   train-rmse:0.000418 
[194]   train-rmse:0.000414 
[195]   train-rmse:0.000411 
[196]   train-rmse:0.000409 
[197]   train-rmse:0.000409 
[198]   train-rmse:0.000408 
[199]   train-rmse:0.000408 
[200]   train-rmse:0.000406 
[201]   train-rmse:0.000405 
[202]   train-rmse:0.000403 
[203]   train-rmse:0.000400 
[204]   train-rmse:0.000400 
[205]   train-rmse:0.000398 
[206]   train-rmse:0.000396 
[207]   train-rmse:0.000394 
[208]   train-rmse:0.000393 
[209]   train-rmse:0.000391 
[210]   train-rmse:0.000390 
[211]   train-rmse:0.000389 
[212]   train-rmse:0.000389 
[213]   train-rmse:0.000388 
[214]   train-rmse:0.000385 
[215]   train-rmse:0.000383 
[216]   train-rmse:0.000381 
[217]   train-rmse:0.000379 
[218]   train-rmse:0.000378 
[219]   train-rmse:0.000378 
[220]   train-rmse:0.000375 
[221]   train-rmse:0.000374 
[222]   train-rmse:0.000373 
[223]   train-rmse:0.000372 
[224]   train-rmse:0.000371 
[225]   train-rmse:0.000369 
[226]   train-rmse:0.000368 
[227]   train-rmse:0.000366 
[228]   train-rmse:0.000365 
[229]   train-rmse:0.000364 
[230]   train-rmse:0.000363 
[231]   train-rmse:0.000361 
[232]   train-rmse:0.000360 
[233]   train-rmse:0.000359 
[234]   train-rmse:0.000358 
[235]   train-rmse:0.000357 
[236]   train-rmse:0.000356 
[237]   train-rmse:0.000355 
[238]   train-rmse:0.000355 
[239]   train-rmse:0.000353 
[240]   train-rmse:0.000352 
[241]   train-rmse:0.000351 
[242]   train-rmse:0.000350 
[243]   train-rmse:0.000349 
[244]   train-rmse:0.000349 
[245]   train-rmse:0.000347 
[246]   train-rmse:0.000346 
[247]   train-rmse:0.000345 
[248]   train-rmse:0.000344 
[249]   train-rmse:0.000343 
[250]   train-rmse:0.000342 
[251]   train-rmse:0.000341 
[252]   train-rmse:0.000339 
[253]   train-rmse:0.000338 
[254]   train-rmse:0.000337 
[255]   train-rmse:0.000335 
[256]   train-rmse:0.000333 
[257]   train-rmse:0.000331 
[258]   train-rmse:0.000331 
[259]   train-rmse:0.000330 
[260]   train-rmse:0.000329 
[261]   train-rmse:0.000328 
[262]   train-rmse:0.000326 
[263]   train-rmse:0.000325 
[264]   train-rmse:0.000322 
[265]   train-rmse:0.000321 
[266]   train-rmse:0.000320 
[267]   train-rmse:0.000318 
[268]   train-rmse:0.000317 
[269]   train-rmse:0.000315 
[270]   train-rmse:0.000313 
[271]   train-rmse:0.000312 
[272]   train-rmse:0.000311 
[273]   train-rmse:0.000310 
[274]   train-rmse:0.000308 
[275]   train-rmse:0.000306 
[276]   train-rmse:0.000306 
[277]   train-rmse:0.000304 
[278]   train-rmse:0.000303 
[279]   train-rmse:0.000302 
[280]   train-rmse:0.000301 
[281]   train-rmse:0.000299 
[282]   train-rmse:0.000298 
[283]   train-rmse:0.000297 
[284]   train-rmse:0.000296 
[285]   train-rmse:0.000296 
[286]   train-rmse:0.000295 
[287]   train-rmse:0.000295 
[288]   train-rmse:0.000294 
[289]   train-rmse:0.000294 
[290]   train-rmse:0.000292 
[291]   train-rmse:0.000291 
[292]   train-rmse:0.000290 
[293]   train-rmse:0.000289 
[294]   train-rmse:0.000288 
[295]   train-rmse:0.000288 
[296]   train-rmse:0.000288 
[297]   train-rmse:0.000287 
[298]   train-rmse:0.000285 
[299]   train-rmse:0.000284 
[300]   train-rmse:0.000283 
[301]   train-rmse:0.000282 
[302]   train-rmse:0.000281 
[303]   train-rmse:0.000281 
[304]   train-rmse:0.000280 
[305]   train-rmse:0.000279 
[306]   train-rmse:0.000278 
[307]   train-rmse:0.000277 
[308]   train-rmse:0.000276 
[309]   train-rmse:0.000276 
[310]   train-rmse:0.000275 
[311]   train-rmse:0.000273 
[312]   train-rmse:0.000272 
[313]   train-rmse:0.000272 
[314]   train-rmse:0.000271 
[315]   train-rmse:0.000271 
[316]   train-rmse:0.000271 
[317]   train-rmse:0.000270 
[318]   train-rmse:0.000269 
[319]   train-rmse:0.000268 
[320]   train-rmse:0.000267 
[321]   train-rmse:0.000266 
[322]   train-rmse:0.000266 
[323]   train-rmse:0.000266 
[324]   train-rmse:0.000264 
[325]   train-rmse:0.000264 
[326]   train-rmse:0.000263 
[327]   train-rmse:0.000262 
[328]   train-rmse:0.000260 
[329]   train-rmse:0.000259 
[330]   train-rmse:0.000259 
[331]   train-rmse:0.000258 
[332]   train-rmse:0.000258 
[333]   train-rmse:0.000257 
[334]   train-rmse:0.000257 
[335]   train-rmse:0.000256 
[336]   train-rmse:0.000255 
[337]   train-rmse:0.000254 
[338]   train-rmse:0.000253 
[339]   train-rmse:0.000253 
[340]   train-rmse:0.000252 
[341]   train-rmse:0.000252 
[342]   train-rmse:0.000251 
[343]   train-rmse:0.000250 
[344]   train-rmse:0.000250 
[345]   train-rmse:0.000249 
[346]   train-rmse:0.000248 
[347]   train-rmse:0.000248 
[348]   train-rmse:0.000247 
[349]   train-rmse:0.000246 
[350]   train-rmse:0.000246 
[351]   train-rmse:0.000245 
[352]   train-rmse:0.000244 
[353]   train-rmse:0.000244 
[354]   train-rmse:0.000243 
[355]   train-rmse:0.000242 
[356]   train-rmse:0.000241 
[357]   train-rmse:0.000240 
[358]   train-rmse:0.000239 
[359]   train-rmse:0.000239 
[360]   train-rmse:0.000238 
[361]   train-rmse:0.000237 
[362]   train-rmse:0.000237 
[363]   train-rmse:0.000236 
[364]   train-rmse:0.000236 
[365]   train-rmse:0.000235 
[366]   train-rmse:0.000235 
[367]   train-rmse:0.000234 
[368]   train-rmse:0.000234 
[369]   train-rmse:0.000233 
[370]   train-rmse:0.000233 
[371]   train-rmse:0.000232 
[372]   train-rmse:0.000232 
[373]   train-rmse:0.000231 
[374]   train-rmse:0.000231 
[375]   train-rmse:0.000230 
[376]   train-rmse:0.000229 
[377]   train-rmse:0.000228 
[378]   train-rmse:0.000227 
[379]   train-rmse:0.000226 
[380]   train-rmse:0.000225 
[381]   train-rmse:0.000224 
[382]   train-rmse:0.000223 
[383]   train-rmse:0.000223 
[384]   train-rmse:0.000222 
[385]   train-rmse:0.000221 
[386]   train-rmse:0.000220 
[387]   train-rmse:0.000219 
[388]   train-rmse:0.000219 
[389]   train-rmse:0.000219 
[390]   train-rmse:0.000218 
[391]   train-rmse:0.000218 
[392]   train-rmse:0.000217 
[393]   train-rmse:0.000217 
[394]   train-rmse:0.000216 
[395]   train-rmse:0.000215 
[396]   train-rmse:0.000214 
[397]   train-rmse:0.000214 
[398]   train-rmse:0.000213 
[399]   train-rmse:0.000213 
[400]   train-rmse:0.000212 
[401]   train-rmse:0.000212 
[402]   train-rmse:0.000212 
[403]   train-rmse:0.000212 
[404]   train-rmse:0.000211 
[405]   train-rmse:0.000211 
[406]   train-rmse:0.000211 
[407]   train-rmse:0.000211 
[408]   train-rmse:0.000210 
[409]   train-rmse:0.000210 
[410]   train-rmse:0.000209 
[411]   train-rmse:0.000209 
[412]   train-rmse:0.000208 
[413]   train-rmse:0.000208 
[414]   train-rmse:0.000207 
[415]   train-rmse:0.000206 
[416]   train-rmse:0.000206 
[417]   train-rmse:0.000205 
[418]   train-rmse:0.000204 
[419]   train-rmse:0.000204 
[420]   train-rmse:0.000204 
[421]   train-rmse:0.000203 
[422]   train-rmse:0.000203 
[423]   train-rmse:0.000203 
[424]   train-rmse:0.000202 
[425]   train-rmse:0.000202 
[426]   train-rmse:0.000201 
[427]   train-rmse:0.000201 
[428]   train-rmse:0.000201 
[429]   train-rmse:0.000201 
[430]   train-rmse:0.000200 
[431]   train-rmse:0.000200 
[432]   train-rmse:0.000200 
[433]   train-rmse:0.000199 
[434]   train-rmse:0.000199 
[435]   train-rmse:0.000199 
[436]   train-rmse:0.000198 
[437]   train-rmse:0.000198 
[438]   train-rmse:0.000197 
[439]   train-rmse:0.000197 
[440]   train-rmse:0.000197 
[441]   train-rmse:0.000196 
[442]   train-rmse:0.000196 
[443]   train-rmse:0.000196 
[444]   train-rmse:0.000196 
[445]   train-rmse:0.000195 
[446]   train-rmse:0.000195 
[447]   train-rmse:0.000194 
[448]   train-rmse:0.000194 
[449]   train-rmse:0.000193 
[450]   train-rmse:0.000193 
[451]   train-rmse:0.000192 
[452]   train-rmse:0.000192 
[453]   train-rmse:0.000192 
[454]   train-rmse:0.000192 
[455]   train-rmse:0.000191 
[456]   train-rmse:0.000191 
[457]   train-rmse:0.000191 
[458]   train-rmse:0.000191 
[459]   train-rmse:0.000191 
[460]   train-rmse:0.000190 
[461]   train-rmse:0.000190 
[462]   train-rmse:0.000189 
[463]   train-rmse:0.000189 
[464]   train-rmse:0.000188 
[465]   train-rmse:0.000188 
[466]   train-rmse:0.000188 
[467]   train-rmse:0.000188 
[468]   train-rmse:0.000188 
[469]   train-rmse:0.000187 
[470]   train-rmse:0.000187 
[471]   train-rmse:0.000187 
[472]   train-rmse:0.000187 
[473]   train-rmse:0.000186 
[474]   train-rmse:0.000186 
[475]   train-rmse:0.000186 
[476]   train-rmse:0.000185 
[477]   train-rmse:0.000185 
[478]   train-rmse:0.000185 
[479]   train-rmse:0.000184 
[480]   train-rmse:0.000184 
[481]   train-rmse:0.000184 
[482]   train-rmse:0.000184 
[483]   train-rmse:0.000184 
[484]   train-rmse:0.000184 
[485]   train-rmse:0.000184 
[486]   train-rmse:0.000184 
[487]   train-rmse:0.000184 
[488]   train-rmse:0.000184 
[489]   train-rmse:0.000184 
[490]   train-rmse:0.000184 
[491]   train-rmse:0.000184 
[492]   train-rmse:0.000184 
[493]   train-rmse:0.000184 
[494]   train-rmse:0.000184 
[495]   train-rmse:0.000184 
[496]   train-rmse:0.000184 
[497]   train-rmse:0.000184 
[498]   train-rmse:0.000184 
[499]   train-rmse:0.000184 
[500]   train-rmse:0.000184 
print(xgb_model)
##### xgb.Booster
raw: 1.1 Mb 
call:
  xgb.train(params = params, data = dtrain, nrounds = nrounds, 
    watchlist = watchlist, verbose = verbose, print_every_n = print_every_n, 
    early_stopping_rounds = early_stopping_rounds, maximize = maximize, 
    save_period = save_period, save_name = save_name, xgb_model = xgb_model, 
    callbacks = callbacks, objective = "reg:squarederror", eta = 0.06, 
    max_depth = 6)
params (as set within xgb.train):
  objective = "reg:squarederror", eta = "0.06", max_depth = "6", validate_parameters = "TRUE"
xgb.attributes:
  niter
callbacks:
  cb.print.evaluation(period = print_every_n)
  cb.evaluation.log()
# of features: 33 
niter: 500
nfeatures : 33 
evaluation_log:
     iter   train_rmse
    <num>        <num>
        1 4.2773036430
        2 4.0207096070
---                   
      499 0.0001844433
      500 0.0001844433

GAM

library(mgcv)
Loading required package: nlme

Attaching package: 'nlme'
The following object is masked from 'package:forecast':

    getResponse
The following object is masked from 'package:dplyr':

    collapse
This is mgcv 1.9-1. For overview type 'help("mgcv-package")'.
gam_model <- gam(log_num_orders ~ s(week), data = train_set)
summary(gam_model)

Family: gaussian 
Link function: identity 

Formula:
log_num_orders ~ s(week)

Parametric coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 4.888130   0.001991    2455   <2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Approximate significance of smooth terms:
          edf Ref.df     F p-value    
s(week) 8.681   8.97 38.94  <2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

R-sq.(adj) =  0.000951   Deviance explained = 0.0975%
GCV =  1.448  Scale est. = 1.4479    n = 365240

Evaluasi Model

library(Metrics)

# Prediksi untuk semua model
regresi_pred <-predict(model_reg, newdata = train_set)
xgb_pred <- exp(predict(xgb_model, newdata = model.matrix(log_num_orders ~ ., data = train_set)[,-1])) - 1
gam_pred <-  predict(gam_model, newdata = train_set)

# Menghitung RMSE untuk setiap model
rmse_reg <-rmse(train_set$log_num_orders, regresi_pred)
rmse_gam <- rmse(train_set$log_num_orders, gam_pred)
rmse_xgb <-rmse(train_set$num_orders, xgb_pred)

# Menampilkan hasil perbandingan
results <- data.frame(
  Model = c("Regresi", "GAM", "XGBoost"),
  RMSE = c(rmse_reg, rmse_gam, rmse_xgb)
)

print(results)
    Model      RMSE
1 Regresi 0.7020705
2     GAM 1.2032848
3 XGBoost 0.5134026

Dapat dilihat bahwa model xgboost menghasilka rmse terkecil yaitu sebeesar 0,555161 sehingga xgboost digunaakan sebagai pemodelan dalam memprediksi jumlah pesanan untuk 10 minggu kedepan.

Prediksi Num Orders

#Ambil fitur yang digunakan dalam training
train_matrix <- model.matrix(log_num_orders ~ ., data = train_set)[,-1]
test_matrix <- model.matrix(log_num_orders ~ ., data = test_set)[,-1]
common_cols <- intersect(colnames(train_matrix), colnames(test_matrix))
test_matrix <- test_matrix[, common_cols, drop = FALSE]
for (col in colnames(test_set)) {
  if (is.factor(train_set[[col]])) {
    test_set[[col]] <- factor(test_set[[col]], levels =levels(train_set[[col]]))
  }
}

Submission

# prediksi menggunakan XGBoost
xgb_pred_test <- exp(predict(xgb_model, newdata = test_matrix)) - 1  

#tmbahkan hasil prediksi ke test_set
test_set$predicted_orders <- xgb_pred_test

#simpan ke file submission.csv
submission <- data.frame(
  id = test_set$id,  
  num_orders = round(test_set$predicted_orders)  
)

write.csv(submission, "submission.csv", row.names = FALSE)