Pengenalan

Saya Briandamar Kencana seorang data enthusiast. Saya lulus dengan gelar sarjana statistik. Saya memiliki beberapa pengalaman kerja di bidang data, seperti magang di momobil.id, independent research and advisory Indonesia, staf data analis di Alif Aza Asia dan asisten peneliti di Bank Indonesia, dan kemudian saya melanjutkan karir saya sebagai analis di sebuah bank komersial di Indonesia. Selain itu, saya telah berpartisipasi dalam beberapa kursus pelatihan data di Algoritma Data Science School, Coursera, Udemy dan Dicoding.

Informasi Data

Kumpulan data ini diunduh dari situs web “UCI Machine Learning Repository”, berupa Kumpulan data terkait dengan kampanye pemasaran lembaga perbankan Portugis. Kampanye pemasaran didasarkan pada telemarketing. Informasi kontak termasuk tanggal, waktu dan jumlah kontak yang dilakukan kepada pelanggan untuk mendapatkan jawaban “ya” atau “tidak” untuk deposito berjangka mereka.

Permasalahan

Sebuah Bank di portugis mengadakan direct marketing campaign dalam meluncurkan deposito berjangka untuk pelanggannya. Sebelumnya mereka menghubungi ke pelanggan mereka melalui panggilan telepon. Hasil kampanye sebelumnya telah dicatat dan telah diberikan kepada manajer kampanye saat ini, untuk menggunakan hal yang sama dalam membuat kampanye ini lebih efektif.

Tantangan yang dihadapi manajer adalah sebagai berikut:

  • Pelanggan baru-baru ini mulai mengeluh bahwa staf pemasaran bank mengganggu mereka dengan panggilan untuk menawarkan produk yang tidak relevan dan ini harus segera dihentikan
  • Tidak ada kerangka kerja sebelumnya untuk memutuskan dan memilih pelanggan mana yang akan dihubungi dan mana yang tidak.

Sehinnga , Dia telah memutuskan untuk menggunakan data masa lalu untuk mengotomatiskan keputusan ini, daripada memilih secara manual melalui data setiap pelanggan. Data kampanye sebelumnya yang telah disediakan untuknya; berisi karakteristik pelanggan, karakteristik kampanye, informasi kampanye sebelumnya serta apakah pelanggan akhirnya berlangganan produk sebagai hasil dari kampanye tersebut atau tidak. Dengan menggunakan ini dia berencana untuk mengembangkan model statistik yang diberikan informasi ini memprediksi apakah pelanggan yang bersangkutan akan berlangganan produk atau tidak. Model yang berhasil yang mampu melakukan ini, akan membuat kampanyenya ditargetkan secara efisien dan tidak terlalu mengganggu pelanggan yang tidak tertarik.

Metode and Tujuan

Metode yang akan digunakan pada artikel ini adalah analisis regresi Logistik dan KNN. Regresi Logistik dan K-Nearest Neighbor adalah teknik supervised machine learning yang berhubungan dengan prediksi dalam klasifikasi. Saya akan mencoba mendapatkan wawasan dari Data yang terkait dengan kampanye pemasaran langsung (panggilan telepon) dari lembaga perbankan Portugis.

Data Preparation

library(DT)
library(graphics)
library(tidyverse)
library(class)
library(ggplot2)

Data Input

bank <- read.csv("data_input/bank-full.csv", header = TRUE, sep = ";")
rmarkdown::paged_table(bank)

Data tersebut mengandung beberapa variabel berikut :

  • age (numerik) : Usia

  • job (Kategorikal) : Tipe pekerjaan

  • marital : status perkawinan (Kategorikal: “married”,“divorced”,“single”; note: “divorced” means divorced or widowed)

  • ducation (Kategorikal: “unknown”,“secondary”,“primary”,“tertiary”)

  • default: memiliki kredit ? (binary: “yes”,“no”)

  • housing: memiliki pinjaman perumahan? (binary: “yes”,“no”)

  • loan: memiliki pinjaman pribadi? (binary: “yes”,“no”)

  • contact: jenis komunikasi kontak (Kategorikal: “unknown”,“telephone”,“cellular”)

  • month: kontak terakhir Bulan tahun ini (Kategorikal: “jan”, “feb”, “mar”, ., “nov”, “dec”)

  • duration: durasi kontak terakhir, dalam detik (numerik)

  • campaign: jumlah kontak yang dilakukan selama kampanye ini dan untuk klien ini (numerik, termasuk kontak terakhir)

  • pdays: jumlah hari yang berlalu setelah klien terakhir dihubungi dari kampanye sebelumnya (numerik; 999 berarti klien sebelumnya tidak dihubungi

  • previous: jumlah kontak yang dilakukan sebelum kampanye ini dan untuk klien ini (numerik)

  • poutcome: hasil dari kampanye pemasaran sebelumnya (kategoris)

  • balance: saldo tahunan rata-rata

  • y - apakah klien telah berlangganan deposito berjangka? (biner: ‘yes’, ‘no’)

. ## merubah tipe data

bank<-bank %>% 
  mutate_if(is.character,as.factor)
rmarkdown::paged_table(bank)

Cek Missing Value

colSums(is.na(bank))
#>       age       job   marital education   default   balance   housing      loan 
#>         0         0         0         0         0         0         0         0 
#>   contact       day     month  duration  campaign     pdays  previous  poutcome 
#>         0         0         0         0         0         0         0         0 
#>         y 
#>         0

Cek Balancing Data

prop.table(table(bank$y))
#> 
#>        no       yes 
#> 0.8830152 0.1169848

Berdasarkan diatas , hasil proporsi kedua factor tersebut tidak seimbang. Hal tersebut dapat memengaruhi model yang akan dibuat sehingga perlu dilakukan metode balancing. Saya akan menggunakan metode downsample untuk menyeimbangkan kedua kelas.

library(caret)
bank_new <- downSample(x = bank[, -17], y = bank[, 17], yname = "y")
prop.table(table(bank_new$y))
#> 
#>  no yes 
#> 0.5 0.5

Setelah proporsi kedua kelas seimbang, selanjutnya saya akan membagi data tersebut kedalamdata train dan data test

Splitting Data Train-Test

set.seed(100)
intrain <- sample(nrow(bank_new), nrow(bank_new)*0.7)
bank_train <- bank_new[intrain,]
bank_test <- bank_new[-intrain,]
prop.table(table(bank_train$y))
#> 
#>        no       yes 
#> 0.5031064 0.4968936

Setelah dta berhasil di bagi kedalam data trai dan test , selanjutnya adalah membuat model dengan menggunakan data train yang sudah dibuat.

Membangun Model

Model yang akan dibuat pada artikel ini adalah model regresi logistic dan model KNN.

Regresi Logistik

mode1_logistik <- glm(y~.,
                  data = bank_train, family = "binomial")
summary(mode1_logistik)
#> 
#> Call:
#> glm(formula = y ~ ., family = "binomial", data = bank_train)
#> 
#> Deviance Residuals: 
#>     Min       1Q   Median       3Q      Max  
#> -5.9255  -0.5883  -0.1296   0.5997   2.8865  
#> 
#> Coefficients:
#>                       Estimate  Std. Error z value             Pr(>|z|)    
#> (Intercept)        -0.92495264  0.33711431  -2.744             0.006074 ** 
#> age                 0.00340447  0.00399150   0.853             0.393698    
#> jobblue-collar     -0.65073289  0.12907426  -5.042 0.000000461803600274 ***
#> jobentrepreneur    -0.44181191  0.21859181  -2.021             0.043262 *  
#> jobhousemaid       -0.87226811  0.23228028  -3.755             0.000173 ***
#> jobmanagement      -0.31318658  0.13312330  -2.353             0.018642 *  
#> jobretired          0.27211804  0.18225107   1.493             0.135412    
#> jobself-employed   -0.36984156  0.20425005  -1.811             0.070183 .  
#> jobservices        -0.42559422  0.14742428  -2.887             0.003891 ** 
#> jobstudent          0.51331648  0.21111458   2.431             0.015038 *  
#> jobtechnician      -0.42923838  0.12266322  -3.499             0.000466 ***
#> jobunemployed      -0.27498478  0.21381799  -1.286             0.198419    
#> jobunknown         -0.10065353  0.44578829  -0.226             0.821367    
#> maritalmarried     -0.03421849  0.10590215  -0.323             0.746609    
#> maritalsingle       0.27266337  0.12203352   2.234             0.025461 *  
#> educationsecondary  0.29671320  0.11398314   2.603             0.009238 ** 
#> educationtertiary   0.54248735  0.13451695   4.033 0.000055103272235206 ***
#> educationunknown    0.53659515  0.19525553   2.748             0.005993 ** 
#> defaultyes          0.16188643  0.25293529   0.640             0.522152    
#> balance             0.00002213  0.00001007   2.198             0.027955 *  
#> housingyes         -0.68823730  0.07629331  -9.021 < 0.0000000000000002 ***
#> loanyes            -0.52104490  0.10253110  -5.082 0.000000373830135027 ***
#> contacttelephone   -0.12385562  0.13981604  -0.886             0.375700    
#> contactunknown     -1.54937677  0.11780117 -13.152 < 0.0000000000000002 ***
#> day                 0.00145860  0.00435373   0.335             0.737608    
#> monthaug           -0.97232048  0.13680433  -7.107 0.000000000001182659 ***
#> monthdec            0.96582340  0.44079899   2.191             0.028446 *  
#> monthfeb           -0.15882623  0.15797526  -1.005             0.314711    
#> monthjan           -1.19140019  0.20544127  -5.799 0.000000006662199503 ***
#> monthjul           -1.12773262  0.13774278  -8.187 0.000000000000000267 ***
#> monthjun            0.14445055  0.16406938   0.880             0.378630    
#> monthmar            1.32841920  0.23552284   5.640 0.000000016975522843 ***
#> monthmay           -0.70258876  0.13037673  -5.389 0.000000070885338676 ***
#> monthnov           -1.11716821  0.14709216  -7.595 0.000000000000030774 ***
#> monthoct            1.59682121  0.25627341   6.231 0.000000000463679832 ***
#> monthsep            1.19653285  0.28225654   4.239 0.000022434988106012 ***
#> duration            0.00553104  0.00015504  35.676 < 0.0000000000000002 ***
#> campaign           -0.09156410  0.01708789  -5.358 0.000000083953187408 ***
#> pdays              -0.00055157  0.00054512  -1.012             0.311616    
#> previous            0.05348916  0.02296298   2.329             0.019840 *  
#> poutcomeother       0.18565604  0.16725972   1.110             0.267005    
#> poutcomesuccess     2.52720486  0.19149939  13.197 < 0.0000000000000002 ***
#> poutcomeunknown    -0.19904237  0.18067431  -1.102             0.270608    
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> (Dispersion parameter for binomial family taken to be 1)
#> 
#>     Null deviance: 10264  on 7403  degrees of freedom
#> Residual deviance:  5951  on 7361  degrees of freedom
#> AIC: 6037
#> 
#> Number of Fisher Scoring iterations: 6

Berdasarkan hasil diatas terdapat beberapa variabel yang tidak signifikan, selanjutnya saya akan mencoba metode backward untuk mendapatkan kemungkinan nilai AIC terkecil.

library(MASS)
model2_logistik <- stepAIC(mode1_logistik, direction = "backward")
#> Start:  AIC=6037.01
#> y ~ age + job + marital + education + default + balance + housing + 
#>     loan + contact + day + month + duration + campaign + pdays + 
#>     previous + poutcome
#> 
#>             Df Deviance    AIC
#> - day        1   5951.1 6035.1
#> - default    1   5951.4 6035.4
#> - age        1   5951.7 6035.7
#> - pdays      1   5952.0 6036.0
#> <none>           5951.0 6037.0
#> - balance    1   5955.9 6039.9
#> - previous   1   5957.2 6041.2
#> - marital    2   5964.9 6046.9
#> - education  3   5969.3 6049.3
#> - loan       1   5977.5 6061.5
#> - campaign   1   5982.3 6066.3
#> - job       11   6028.9 6092.9
#> - housing    1   6033.5 6117.5
#> - contact    2   6138.7 6220.7
#> - poutcome   3   6275.3 6355.3
#> - month     11   6404.8 6468.8
#> - duration   1   8379.2 8463.2
#> 
#> Step:  AIC=6035.13
#> y ~ age + job + marital + education + default + balance + housing + 
#>     loan + contact + month + duration + campaign + pdays + previous + 
#>     poutcome
#> 
#>             Df Deviance    AIC
#> - default    1   5951.5 6033.5
#> - age        1   5951.8 6033.8
#> - pdays      1   5952.2 6034.2
#> <none>           5951.1 6035.1
#> - balance    1   5956.0 6038.0
#> - previous   1   5957.3 6039.3
#> - marital    2   5965.0 6045.0
#> - education  3   5969.5 6047.5
#> - loan       1   5977.8 6059.8
#> - campaign   1   5982.6 6064.6
#> - job       11   6029.0 6091.0
#> - housing    1   6034.0 6116.0
#> - contact    2   6139.7 6219.7
#> - poutcome   3   6275.3 6353.3
#> - month     11   6409.9 6471.9
#> - duration   1   8379.7 8461.7
#> 
#> Step:  AIC=6033.53
#> y ~ age + job + marital + education + balance + housing + loan + 
#>     contact + month + duration + campaign + pdays + previous + 
#>     poutcome
#> 
#>             Df Deviance    AIC
#> - age        1   5952.2 6032.2
#> - pdays      1   5952.6 6032.6
#> <none>           5951.5 6033.5
#> - balance    1   5956.3 6036.3
#> - previous   1   5957.7 6037.7
#> - marital    2   5965.4 6043.4
#> - education  3   5969.9 6045.9
#> - loan       1   5977.9 6057.9
#> - campaign   1   5983.0 6063.0
#> - job       11   6029.3 6089.3
#> - housing    1   6034.2 6114.2
#> - contact    2   6139.8 6217.8
#> - poutcome   3   6275.5 6351.5
#> - month     11   6409.9 6469.9
#> - duration   1   8379.8 8459.8
#> 
#> Step:  AIC=6032.22
#> y ~ job + marital + education + balance + housing + loan + contact + 
#>     month + duration + campaign + pdays + previous + poutcome
#> 
#>             Df Deviance    AIC
#> - pdays      1   5953.2 6031.2
#> <none>           5952.2 6032.2
#> - balance    1   5957.3 6035.3
#> - previous   1   5958.4 6036.4
#> - marital    2   5966.1 6042.1
#> - education  3   5970.1 6044.1
#> - loan       1   5978.7 6056.7
#> - campaign   1   5983.9 6061.9
#> - job       11   6034.8 6092.8
#> - housing    1   6037.8 6115.8
#> - contact    2   6140.1 6216.1
#> - poutcome   3   6277.0 6351.0
#> - month     11   6410.5 6468.5
#> - duration   1   8379.8 8457.8
#> 
#> Step:  AIC=6031.22
#> y ~ job + marital + education + balance + housing + loan + contact + 
#>     month + duration + campaign + previous + poutcome
#> 
#>             Df Deviance    AIC
#> <none>           5953.2 6031.2
#> - balance    1   5958.3 6034.3
#> - previous   1   5959.8 6035.8
#> - marital    2   5967.1 6041.1
#> - education  3   5971.2 6043.2
#> - loan       1   5979.6 6055.6
#> - campaign   1   5984.9 6060.9
#> - job       11   6036.2 6092.2
#> - housing    1   6040.5 6116.5
#> - contact    2   6140.7 6214.7
#> - poutcome   3   6281.5 6353.5
#> - month     11   6410.7 6466.7
#> - duration   1   8381.4 8457.4
summary(model2_logistik)
#> 
#> Call:
#> glm(formula = y ~ job + marital + education + balance + housing + 
#>     loan + contact + month + duration + campaign + previous + 
#>     poutcome, family = "binomial", data = bank_train)
#> 
#> Deviance Residuals: 
#>     Min       1Q   Median       3Q      Max  
#> -5.9165  -0.5886  -0.1290   0.6021   2.8441  
#> 
#> Coefficients:
#>                       Estimate  Std. Error z value             Pr(>|z|)    
#> (Intercept)        -0.87231039  0.22884139  -3.812             0.000138 ***
#> jobblue-collar     -0.65184567  0.12903446  -5.052 0.000000437854387049 ***
#> jobentrepreneur    -0.43032127  0.21806548  -1.973             0.048455 *  
#> jobhousemaid       -0.85491095  0.23114846  -3.699             0.000217 ***
#> jobmanagement      -0.30884124  0.13307111  -2.321             0.020294 *  
#> jobretired          0.33944628  0.16538866   2.052             0.040129 *  
#> jobself-employed   -0.36971873  0.20426410  -1.810             0.070295 .  
#> jobservices        -0.43300749  0.14730898  -2.939             0.003288 ** 
#> jobstudent          0.48244240  0.20713951   2.329             0.019855 *  
#> jobtechnician      -0.42532727  0.12263878  -3.468             0.000524 ***
#> jobunemployed      -0.26967341  0.21388156  -1.261             0.207361    
#> jobunknown         -0.07818730  0.44565846  -0.175             0.860732    
#> maritalmarried     -0.04695929  0.10531162  -0.446             0.655664    
#> maritalsingle       0.23239677  0.11363373   2.045             0.040841 *  
#> educationsecondary  0.28454312  0.11317712   2.514             0.011932 *  
#> educationtertiary   0.53047126  0.13328178   3.980 0.000068894042015564 ***
#> educationunknown    0.53876312  0.19512353   2.761             0.005760 ** 
#> balance             0.00002260  0.00001003   2.254             0.024209 *  
#> housingyes         -0.70061496  0.07550903  -9.279 < 0.0000000000000002 ***
#> loanyes            -0.51863184  0.10232716  -5.068 0.000000401237945289 ***
#> contacttelephone   -0.10580653  0.13800798  -0.767             0.443278    
#> contactunknown     -1.53817490  0.11689597 -13.158 < 0.0000000000000002 ***
#> monthaug           -0.96628252  0.13513292  -7.151 0.000000000000863944 ***
#> monthdec            0.97321663  0.44065095   2.209             0.027203 *  
#> monthfeb           -0.16585137  0.15171430  -1.093             0.274314    
#> monthjan           -1.17270034  0.20345918  -5.764 0.000000008223529029 ***
#> monthjul           -1.12518807  0.13759277  -8.178 0.000000000000000289 ***
#> monthjun            0.13898749  0.15854612   0.877             0.380684    
#> monthmar            1.33292878  0.23412038   5.693 0.000000012457222429 ***
#> monthmay           -0.71014494  0.12916524  -5.498 0.000000038421663559 ***
#> monthnov           -1.09837584  0.14613503  -7.516 0.000000000000056404 ***
#> monthoct            1.59777275  0.25570668   6.248 0.000000000414521542 ***
#> monthsep            1.18152379  0.27959197   4.226 0.000023800242883015 ***
#> duration            0.00552878  0.00015494  35.683 < 0.0000000000000002 ***
#> campaign           -0.09106486  0.01692177  -5.382 0.000000073859124882 ***
#> previous            0.05554167  0.02301937   2.413             0.015829 *  
#> poutcomeother       0.19571915  0.16655110   1.175             0.239943    
#> poutcomesuccess     2.56726991  0.18714855  13.718 < 0.0000000000000002 ***
#> poutcomeunknown    -0.06188795  0.11970807  -0.517             0.605163    
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> 
#> (Dispersion parameter for binomial family taken to be 1)
#> 
#>     Null deviance: 10263.8  on 7403  degrees of freedom
#> Residual deviance:  5953.2  on 7365  degrees of freedom
#> AIC: 6031.2
#> 
#> Number of Fisher Scoring iterations: 6

Prediksi

bank_test$pred_camp <-predict(model2_logistik, type = "response", newdata = bank_test)


ggplot(bank_test, aes(x=pred_camp)) +
  geom_density(lwd=0.5) +
  labs(title = "Distribution of Probability Prediction Data") +
  theme_minimal()

bank_test$pred_camph <- factor(ifelse(bank_test$pred_camp > 0.5, "yes","no"))
log_conf <- confusionMatrix(bank_test$pred_camph, bank_test$y, positive = "yes")
log_conf
#> Confusion Matrix and Statistics
#> 
#>           Reference
#> Prediction   no  yes
#>        no  1350  297
#>        yes  214 1313
#>                                                
#>                Accuracy : 0.839                
#>                  95% CI : (0.8257, 0.8516)     
#>     No Information Rate : 0.5072               
#>     P-Value [Acc > NIR] : < 0.00000000000000022
#>                                                
#>                   Kappa : 0.6782               
#>                                                
#>  Mcnemar's Test P-Value : 0.0002862            
#>                                                
#>             Sensitivity : 0.8155               
#>             Specificity : 0.8632               
#>          Pos Pred Value : 0.8599               
#>          Neg Pred Value : 0.8197               
#>              Prevalence : 0.5072               
#>          Detection Rate : 0.4137               
#>    Detection Prevalence : 0.4811               
#>       Balanced Accuracy : 0.8393               
#>                                                
#>        'Positive' Class : yes                  
#> 
  • Accuracy: seberapa tepat model kita memprediksi kelas target (secara global). Seberapa baik model kita memprediksi kelas target (positif maupun negatif). dipakai ketika kelas positif dan negatif sama pentingnya atau ketika proporsi kelas seimbang.

(TP+TN/TOTAL)

(1322+1329)/nrow(bank_test)
#> [1] 0.8352237
  • Sensitivity/ Recall: ukuran kebaikan model terhadap kelas positif. Seberapa banyak yang benar diprediksi positif, dari yang reality-nya positif.

(TP/(TP+FN))

1322/(1322+298)
#> [1] 0.8160494
  • Specificity: ukuran kebaikan model terhadap kelas negatif. Ukuran kebaikan model terhadap kelas negatif. seberapa banyak yang tepat diprediksi negatif, dari yang reality-nya negatif. Metrics ini tidak menjadi fokus karena umumnya kita fokus pada kelas positif.

(TN/(TN+FP))

1329/(1329+225)
#> [1] 0.8552124
  • Pos Pred Value/Precision: seberapa presisi model memprediksi kelas positif. Seberapa banyak yang benar diprediksi positif, dari yang diprediksi positif.

(TP/(TP+FP))

1322/(1322+225)
#> [1] 0.8545572

Disini saya akan menggunakan ukuran presisi sebagai acuan karena model yang diharapkan dapat menebak secara tepat kelas positif pada data campaign tersebut. Sehingga meminimalkan phone call untuk penawaran produk yang tidak relevan ke para nasabah, agar tidak muncul komplain.

KNN

glimpse(bank_train)
#> Rows: 7,404
#> Columns: 17
#> $ age       <int> 34, 52, 44, 56, 37, 53, 37, 66, 59, 56, 33, 41, 25, 39, 5...
#> $ job       <fct> blue-collar, blue-collar, admin., management, services, b...
#> $ marital   <fct> single, divorced, divorced, married, married, married, ma...
#> $ education <fct> secondary, secondary, secondary, primary, secondary, prim...
#> $ default   <fct> no, no, no, no, no, no, no, no, no, no, no, no, no, no, n...
#> $ balance   <int> -231, 0, -88, 0, 2128, 5603, 204, 206, -546, 370, 2364, 4...
#> $ housing   <fct> yes, no, yes, no, no, no, yes, no, no, no, no, yes, no, n...
#> $ loan      <fct> no, yes, no, no, no, no, no, no, no, no, no, no, no, no, ...
#> $ contact   <fct> cellular, cellular, unknown, unknown, unknown, cellular, ...
#> $ day       <int> 13, 15, 27, 5, 18, 28, 21, 9, 25, 26, 17, 19, 14, 7, 27, ...
#> $ month     <fct> may, jul, may, jun, jun, aug, may, feb, aug, aug, may, ma...
#> $ duration  <int> 9, 231, 600, 153, 105, 2372, 161, 479, 1152, 128, 508, 10...
#> $ campaign  <int> 8, 2, 2, 2, 1, 6, 4, 1, 6, 12, 1, 1, 3, 2, 1, 3, 1, 2, 4,...
#> $ pdays     <int> -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -...
#> $ previous  <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, ...
#> $ poutcome  <fct> unknown, unknown, unknown, unknown, unknown, unknown, unk...
#> $ y         <fct> no, no, no, no, no, yes, no, yes, yes, no, yes, no, yes, ...

Selanjutnya saya akan menggunakan model KNN, karena konsep KNN adalah menghitung jarak maka model KNN akan baik digunakan jiaka variabel tersebut numerik.

# predictor variables in `train`
train_x <-bank_train %>% dplyr::select(age, balance, day, duration, campaign, pdays, previous)

# predictor variables in `test`
test_x <-bank_test %>% dplyr::select(age, balance, day, duration, campaign, pdays, previous)

# target variable in `train`
train_y <-bank_train[,17]

# target variable in `test`
test_y <-bank_test[,17]

Selanjutnya melakukan normalisasi untuk menyamakan satuan dari variabel.

# scale train_x data
train_x <- scale(train_x)

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

Setelah melakukan normalisasi data, kita perlu menemukan K yang tepat untuk digunakan untuk model K-NN kita. Ada satu praktik umum untuk menentukan bilangan K. Yaitu akar kuadrat dengan jumlah baris

k<-sqrt(nrow(train_x))
k
#> [1] 86.0465

Di sini, saya akan memilih 87 karena jumlah barisnya genap.

model_knn <- knn(train = train_x, test = test_x, cl = train_y, k = 87)
pred_knn_conf <- confusionMatrix(as.factor(model_knn), as.factor(test_y),"yes")
pred_knn_conf
#> Confusion Matrix and Statistics
#> 
#>           Reference
#> Prediction   no  yes
#>        no  1294  478
#>        yes  270 1132
#>                                                
#>                Accuracy : 0.7643               
#>                  95% CI : (0.7492, 0.779)      
#>     No Information Rate : 0.5072               
#>     P-Value [Acc > NIR] : < 0.00000000000000022
#>                                                
#>                   Kappa : 0.5295               
#>                                                
#>  Mcnemar's Test P-Value : 0.00000000000003771  
#>                                                
#>             Sensitivity : 0.7031               
#>             Specificity : 0.8274               
#>          Pos Pred Value : 0.8074               
#>          Neg Pred Value : 0.7302               
#>              Prevalence : 0.5072               
#>          Detection Rate : 0.3566               
#>    Detection Prevalence : 0.4417               
#>       Balanced Accuracy : 0.7652               
#>                                                
#>        'Positive' Class : yes                  
#> 

Disini saya mendapatkan hasil bahwa presisi yang dihasilkan dari model KNN lebih rendah dari model Logistik.

Interpretasi model

exp(model2_logistik$coefficients) %>% 
  data.frame() 
unique(bank$job)
#>  [1] management    technician    entrepreneur  blue-collar   unknown      
#>  [6] retired       admin.        services      self-employed unemployed   
#> [11] housemaid     student      
#> 12 Levels: admin. blue-collar entrepreneur housemaid management ... unknown

Untuk menafsirkan tabel ini, saya melihat bahwa kemungkinan pelanggan yang memiliki pekerjaan student kemungkinan akan menerima produk campaign yang ditawarkan tersebut “yes”sebesar 2.26 kali dibandingkan dengan pekerjaan admin.

Kesimpulan

Saya telah melakukan dua metode pengklasifikasian. Dari model diatas, sebaiknya menggunakan regresi logistik karena memberikan angka presisi yang lebih dari model_knn yang saya miliki.

 

A work by Briandamar Kencana

damarbrian@gmail.com