Introduction

Pada kali ini saya akan melakukan prediksi terhadap data whosale untuk melihat apakah client berasal dari channel HoReCa (hotel/restoran/cafe) atau retail. Pada kasus ini saya akan mengunakan metode Logistic Regression dan K-Neares Neighbour.

Libarary

library(tidyverse)
library(class)
library(caret)

Read Data

Data set yang akan digunakan yaitu data yang telah disediakan oleh Team Algoritma.

wholesale <- read.csv("wholesale.csv")
str(wholesale)
## 'data.frame':    440 obs. of  8 variables:
##  $ Channel         : int  2 2 2 1 2 2 2 2 1 2 ...
##  $ Region          : int  3 3 3 3 3 3 3 3 3 3 ...
##  $ Fresh           : int  12669 7057 6353 13265 22615 9413 12126 7579 5963 6006 ...
##  $ Milk            : int  9656 9810 8808 1196 5410 8259 3199 4956 3648 11093 ...
##  $ Grocery         : int  7561 9568 7684 4221 7198 5126 6975 9426 6192 18881 ...
##  $ Frozen          : int  214 1762 2405 6404 3915 666 480 1669 425 1159 ...
##  $ Detergents_Paper: int  2674 3293 3516 507 1777 1795 3140 3321 1716 7425 ...
##  $ Delicassen      : int  1338 1776 7844 1788 5185 1451 545 2566 750 2098 ...

Data wholesale merupakan data di bidang retail yang terdiri dari 440 usaha dan 8 variabel.

*Channel = jenis usaha yang terdiri dari horeca (hotel/restoran/cafe) dan retail

*Region = tempat dimana usaha berada. Terdiri dari 3 region, yaitu region 1, 2, dan

*6 variabel sisanya adalah kuantitas pemebelian dari setiap produk

Data Manipulation

Cek adakah ada variabel yang belum sesuai tipe datanya? Ternyata ada variabel yang belum sesuai sehingga kita perlu melakukan penyesuaian tipe data pada.

wholesale <- wholesale %>% 
  select(-Region) %>% 
  mutate(Channel = factor(Channel, levels = c(1, 2), labels = c("HoReCa", "Retail")))


head(wholesale)

Kemudian kita akan melakukan pengecekan terhadap missing value agar tidak menggangu dalam melakukan pemodelan.

anyNA(wholesale)
## [1] FALSE

Exploratory Data Analysis

Cek proporsi target apakah sudah seimbang atau belum

prop.table(table(wholesale$Channel))
## 
##    HoReCa    Retail 
## 0.6772727 0.3227273
table(wholesale$Channel)
## 
## HoReCa Retail 
##    298    142

Terlihat sudah cukup seimbang dari proporsi kedua kelas.

Cek range nilai antar prediktor (untuk k-NN)

summary(wholesale)
##    Channel        Fresh             Milk          Grocery     
##  HoReCa:298   Min.   :     3   Min.   :   55   Min.   :    3  
##  Retail:142   1st Qu.:  3128   1st Qu.: 1533   1st Qu.: 2153  
##               Median :  8504   Median : 3627   Median : 4756  
##               Mean   : 12000   Mean   : 5796   Mean   : 7951  
##               3rd Qu.: 16934   3rd Qu.: 7190   3rd Qu.:10656  
##               Max.   :112151   Max.   :73498   Max.   :92780  
##      Frozen        Detergents_Paper    Delicassen     
##  Min.   :   25.0   Min.   :    3.0   Min.   :    3.0  
##  1st Qu.:  742.2   1st Qu.:  256.8   1st Qu.:  408.2  
##  Median : 1526.0   Median :  816.5   Median :  965.5  
##  Mean   : 3071.9   Mean   : 2881.5   Mean   : 1524.9  
##  3rd Qu.: 3554.2   3rd Qu.: 3922.0   3rd Qu.: 1820.2  
##  Max.   :60869.0   Max.   :40827.0   Max.   :47943.0

Logistic Regression

Splitting Data

Melakukan splitting data menjadi :

*Data Train : digunakan untuk modeling

*Data Test : digunakan sebagai penguji model yang sudah dibuat

RNGkind(sample.kind = "Rounding")
set.seed(123)
intrain <- sample(nrow(wholesale), nrow(wholesale)*0.8)
w_train <- wholesale[intrain, ]
w_test <- wholesale[-intrain, ]

wholesale$Channel %>% 
  levels()
## [1] "HoReCa" "Retail"
prop.table(table(w_train$Channel))
## 
##    HoReCa    Retail 
## 0.6846591 0.3153409

Modelling

model_l <- glm(Channel ~ ., data = w_train, family = "binomial")
summary(model_l)
## 
## Call:
## glm(formula = Channel ~ ., family = "binomial", data = w_train)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -2.8246  -0.2821  -0.2092   0.0294   3.4120  
## 
## Coefficients:
##                    Estimate Std. Error z value Pr(>|z|)    
## (Intercept)      -3.583e+00  4.691e-01  -7.637 2.22e-14 ***
## Fresh             3.328e-06  1.928e-05   0.173   0.8629    
## Milk              8.070e-05  6.260e-05   1.289   0.1974    
## Grocery           1.117e-04  6.923e-05   1.614   0.1065    
## Frozen           -2.078e-04  1.126e-04  -1.846   0.0649 .  
## Detergents_Paper  8.402e-04  1.571e-04   5.348 8.89e-08 ***
## Delicassen       -1.576e-04  1.384e-04  -1.138   0.2550    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 438.81  on 351  degrees of freedom
## Residual deviance: 153.08  on 345  degrees of freedom
## AIC: 167.08
## 
## Number of Fisher Scoring iterations: 7

Dapat dilihat masih banyak variabel prediktor yang tidak signifikan terhadap variabel target. Selanjutnya kita melakukan pemodelan dengan metode step wise

model_backward <- step(model_l, direction = "backward")
## Start:  AIC=167.08
## Channel ~ Fresh + Milk + Grocery + Frozen + Detergents_Paper + 
##     Delicassen
## 
##                    Df Deviance    AIC
## - Fresh             1   153.11 165.11
## - Delicassen        1   154.50 166.50
## - Milk              1   154.70 166.70
## <none>                  153.08 167.08
## - Grocery           1   155.95 167.95
## - Frozen            1   157.89 169.89
## - Detergents_Paper  1   185.78 197.78
## 
## Step:  AIC=165.11
## Channel ~ Milk + Grocery + Frozen + Detergents_Paper + Delicassen
## 
##                    Df Deviance    AIC
## - Delicassen        1   154.51 164.51
## - Milk              1   154.93 164.93
## <none>                  153.11 165.11
## - Grocery           1   155.99 165.99
## - Frozen            1   158.48 168.48
## - Detergents_Paper  1   187.66 197.66
## 
## Step:  AIC=164.51
## Channel ~ Milk + Grocery + Frozen + Detergents_Paper
## 
##                    Df Deviance    AIC
## - Milk              1   156.38 164.38
## - Grocery           1   156.47 164.47
## <none>                  154.51 164.51
## - Frozen            1   163.50 171.50
## - Detergents_Paper  1   193.56 201.56
## 
## Step:  AIC=164.38
## Channel ~ Grocery + Frozen + Detergents_Paper
## 
##                    Df Deviance    AIC
## <none>                  156.38 164.38
## - Grocery           1   161.69 167.69
## - Frozen            1   163.52 169.52
## - Detergents_Paper  1   195.83 201.83

Dengan menggunakan metode backward pada stepwise diatas , kita memperoleh model sebagai berikut :

summary(model_backward)
## 
## Call:
## glm(formula = Channel ~ Grocery + Frozen + Detergents_Paper, 
##     family = "binomial", data = w_train)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -2.8312  -0.2966  -0.2235   0.0340   3.2083  
## 
## Coefficients:
##                    Estimate Std. Error z value Pr(>|z|)    
## (Intercept)      -3.523e+00  4.527e-01  -7.781 7.17e-15 ***
## Grocery           1.274e-04  5.518e-05   2.309   0.0210 *  
## Frozen           -1.948e-04  8.521e-05  -2.286   0.0223 *  
## Detergents_Paper  8.554e-04  1.481e-04   5.775 7.70e-09 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 438.81  on 351  degrees of freedom
## Residual deviance: 156.38  on 348  degrees of freedom
## AIC: 164.38
## 
## Number of Fisher Scoring iterations: 7

Prediksi

Dengan menggunakan model diatas kita akan melakukan prediksi dengan data test

w_test$prob_Channel <- predict(model_backward, newdata = w_test, type = "response")

Melihat sebaran peluang prediksi data

ggplot(w_test, aes(x=prob_Channel)) +
  geom_density(lwd=0.5) +
  labs(title = "Distribusi Peluang Prediksi Data") +
  theme_gray()

Dapat diinterpretasikan bahwa hasil prediksi yang dilakukan lebih condong ke arah 0 yang artinya HoReCa (Hotel, Restaurant, Cafe)

w_test$pred_Channel <- factor(ifelse(w_test$prob_Channel > 0.5, "Retail","HoReCa"))

w_test[1:10, c("pred_Channel", "Channel")]

Evaluation Model

logistic_conf <- confusionMatrix(data = w_test$pred_Channel, 
                          reference = w_test$Channel)
logistic_conf
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction HoReCa Retail
##     HoReCa     54     11
##     Retail      3     20
##                                           
##                Accuracy : 0.8409          
##                  95% CI : (0.7475, 0.9102)
##     No Information Rate : 0.6477          
##     P-Value [Acc > NIR] : 4.804e-05       
##                                           
##                   Kappa : 0.6296          
##                                           
##  Mcnemar's Test P-Value : 0.06137         
##                                           
##             Sensitivity : 0.9474          
##             Specificity : 0.6452          
##          Pos Pred Value : 0.8308          
##          Neg Pred Value : 0.8696          
##              Prevalence : 0.6477          
##          Detection Rate : 0.6136          
##    Detection Prevalence : 0.7386          
##       Balanced Accuracy : 0.7963          
##                                           
##        'Positive' Class : HoReCa          
## 
  • Re-call/Sensitivity = dari semua data aktual yang positif, seberapa mampu proporsi model saya menebak benar.

  • Specificity = dari semua data aktual yang negatif, seberapa mampu proporsi model saya menebak yang benar.

  • Accuracy = seberapa mampu model saya menebak dengan benar target Y.

  • Precision = dari semua hasil prediksi, seberapa mampu model saya dapat menebak benar kelas positif.

Berdasarkan hasil yang telah kita peroleh, dapat disimpulkan kemampuan model dalam menebak target Y (HoReCa dan Retail) sebesar 84.09%. Sedangkan dari keluruhan data aktual klien HoReCa, model mampu menebak dengan benar sebesar 94.74%. Dari keseluruhan data aktual klien Retail, model mampu menebak dengan benar sebesar 64.52%. Dari keseluruhan hasil prediksi yang mampu ditebak oleh model, model mampu menebak benar segmen klien Horeca sebesar 83.08%.

K-Nearest Neighbour

Splitting Data

Pada algoritma k-Nearest Neighbour, kita perlu melakukan satu tahap data pre-proses tambahan. Untuk setiap data train dan test hilangkan variabel kategorik kecuali variabel Channel. Pisahkan variabel prediktor dan target dari data train dan test.

# prediktor data train
train_x <- w_train[,-1] 

# prediktor data test
test_x <- w_test[,-c(1,8,9)]

#target data train
train_y <- w_train[,1] 

# target data test
test_y <- w_test [,1]

Scaling

Adanya prediktor yang memiliki range nilai yang amat berbeda dari prediktor lainnya dapat menyebabkan masalah pada model klasifikasi. Oleh karena itu, lakukan normalisasi data untuk menyamakan skala dari tiap variabel prediktor agar memiliki range nilai yang standar. Untuk menormalisasi data train_x, kita menggunakan gunakan fungsi scale(), sedangkan untuk menormalisasi data test, menggunakan fungsi yang sama namun menggunakan atribut center dan scale yang didapat dari data `train_x.

train_x <- scale(train_x)
test_x <- scale(test_x,
                center = attr(train_x,"scaled:center"),
                scale = attr(train_x, "scaled:scale"))

Modelling

Pertama kita perlu menemukan nilai K yang optimum untuk digunakan pada model KNN. Pemilihan nilai k dari akar observasi

sqrt(nrow(train_x))
## [1] 18.76166

k harus ganjil bila jumlah kelas target genap. Maka disini saya menggunakan nilai k 17

Prediksi

library(class)
whol_pred <- knn(train = train_x, #prediktor data train
                 test = test_x, #prediktor data test
                 cl =train_y, #prediktor data test
                 k = 17) 

Evaluation Model

library(caret)
confusionMatrix(data = whol_pred,reference = test_y)
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction HoReCa Retail
##     HoReCa     54      8
##     Retail      3     23
##                                           
##                Accuracy : 0.875           
##                  95% CI : (0.7873, 0.9359)
##     No Information Rate : 0.6477          
##     P-Value [Acc > NIR] : 1.329e-06       
##                                           
##                   Kappa : 0.7156          
##                                           
##  Mcnemar's Test P-Value : 0.2278          
##                                           
##             Sensitivity : 0.9474          
##             Specificity : 0.7419          
##          Pos Pred Value : 0.8710          
##          Neg Pred Value : 0.8846          
##              Prevalence : 0.6477          
##          Detection Rate : 0.6136          
##    Detection Prevalence : 0.7045          
##       Balanced Accuracy : 0.8447          
##                                           
##        'Positive' Class : HoReCa          
## 

Dari hasil di atas, dapat kita ambil informasi bahwa kemampuan model dalam menebak target Y (Horeca dan Retail) sebesar 87.5%. Sedangkan dari keluruhan data aktual klien Horeca, model mampu menebak dengan benar sebesar 94.74%. Dari keseluruhan data aktual klien Retail, model mampu menebak dengan benar sebesar 74.19%. Dari keseluruhan hasil prediksi yang mampu ditebak oleh model, model mampu menebak benar segmen klien Horeca sebesar 87.10%.

Conclusion

Dari kedua model diatas dapat disimpulkan bahwa kebanyakan client berasal dari HoReCa (hotel/restoran/cafe). Model KNN ternyata lebih baik dalam memprediksi dalam kasus ini dengan tingkat Accuracy sebesar 87.5% sedangakn model Logistic Regression tingkat Accuracy memprediksi sebesar 84.09%.