Pada kesempatan kali ini saya akan menggunakan dataset yang berisikan data telemarketing pada lembaga bank Portugis. Output yang diinginkan adalah membuat model yang mampu memprediksi keberhasilan dari telemarketing tersebut berdasarkan prediktor-prediktor yang tersedia. Dari output tersebut lembaga bank dapat mengidentifikasikan faktor-faktor yang meningkatkan tingkat keberhasilan dari sebuah telemarketing.
library(dplyr)
library(e1071)
library(rsample)
library(caret)
library(partykit)
#{-}
Pertama kita akan memanggil data yang akan kita olah.
bank <- read.csv2("bank/bank-full.csv")
Gunakan fungsi glimpse untuk memberikan gambaran dataset bank yang telah dipanggil.
glimpse(bank)
## Rows: 45,211
## Columns: 17
## $ age <int> 58, 44, 33, 47, 33, 35, 28, 42, 58, 43, 41, 29, 53, 58, 57, …
## $ job <chr> "management", "technician", "entrepreneur", "blue-collar", "…
## $ marital <chr> "married", "single", "married", "married", "single", "marrie…
## $ education <chr> "tertiary", "secondary", "secondary", "unknown", "unknown", …
## $ default <chr> "no", "no", "no", "no", "no", "no", "no", "yes", "no", "no",…
## $ balance <int> 2143, 29, 2, 1506, 1, 231, 447, 2, 121, 593, 270, 390, 6, 71…
## $ housing <chr> "yes", "yes", "yes", "yes", "no", "yes", "yes", "yes", "yes"…
## $ loan <chr> "no", "no", "yes", "no", "no", "no", "yes", "no", "no", "no"…
## $ contact <chr> "unknown", "unknown", "unknown", "unknown", "unknown", "unkn…
## $ day <int> 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, …
## $ month <chr> "may", "may", "may", "may", "may", "may", "may", "may", "may…
## $ duration <int> 261, 151, 76, 92, 198, 139, 217, 380, 50, 55, 222, 137, 517,…
## $ campaign <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
## $ pdays <int> -1, -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, 0, 0, 0, 0, …
## $ poutcome <chr> "unknown", "unknown", "unknown", "unknown", "unknown", "unkn…
## $ y <chr> "no", "no", "no", "no", "no", "no", "no", "no", "no", "no", …
Data bank terdiri dari 45.211 baris dan 17 kolom. Kolom-kolom tersebut terdiri dari :
Selanjutnya kita akan check missing value
anyNA(bank)
## [1] FALSE
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
Sekilas tidak ada missing value, namun kita juga akan mengecek nilai unique beberapa kolomnya
unique(bank$contact)
## [1] "unknown" "cellular" "telephone"
unique(bank$poutcome)
## [1] "unknown" "failure" "other" "success"
unique(bank$education)
## [1] "tertiary" "secondary" "unknown" "primary"
Ternyata terdapat values “unknown” dalam kolom contact, poutcome, dan education. Kita juga dapat melihat sebarapa banyak nila “unknown” dalam kolom-kolom tersebut.
table(bank$contact)
##
## cellular telephone unknown
## 29285 2906 13020
table(bank$poutcome)
##
## failure other success unknown
## 4901 1840 1511 36959
table(bank$education)
##
## primary secondary tertiary unknown
## 6851 23202 13301 1857
Pada kolom putcome terdapat nilai “unknown” yang cukup besar dan menjadi mayoritas dibandingkan kelas lainnya. Nilai-nilai unknown tersebut nantinya akan kita coba hilangkan.
Kita akan menghilankan nilai “unknown” dan mengubah type data character menjadi factor.
bank_clean <- bank %>%
filter(contact != "unknown" & poutcome != "unknown" & education != "unknown") %>%
mutate_if(is.character,as.factor)
Gambaran dari data yang sudah dibersihkan:
glimpse(bank_clean)
## Rows: 7,864
## Columns: 17
## $ age <int> 33, 42, 33, 36, 36, 44, 26, 51, 33, 30, 30, 44, 51, 51, 44, …
## $ job <fct> admin., admin., services, management, management, blue-colla…
## $ marital <fct> married, single, married, married, married, married, single,…
## $ education <fct> tertiary, secondary, secondary, tertiary, tertiary, secondar…
## $ default <fct> no, no, no, no, no, no, no, no, no, no, no, no, no, no, no, …
## $ balance <int> 882, -247, 3444, 2415, 0, 1324, 172, 3132, 1005, 873, 1243, …
## $ housing <fct> no, yes, yes, yes, yes, yes, no, no, yes, yes, yes, yes, no,…
## $ loan <fct> no, yes, no, no, no, no, yes, no, no, no, no, no, no, no, ye…
## $ contact <fct> telephone, telephone, telephone, telephone, telephone, telep…
## $ day <int> 21, 21, 21, 22, 23, 25, 4, 5, 10, 12, 13, 17, 17, 17, 17, 17…
## $ month <fct> oct, oct, oct, oct, oct, oct, nov, nov, nov, nov, nov, nov, …
## $ duration <int> 39, 519, 144, 73, 140, 119, 21, 449, 175, 119, 86, 81, 200, …
## $ campaign <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
## $ pdays <int> 151, 166, 91, 86, 143, 89, 140, 176, 174, 167, 174, 195, 165…
## $ previous <int> 3, 1, 4, 4, 3, 2, 4, 1, 2, 3, 1, 2, 2, 2, 1, 2, 1, 1, 2, 3, …
## $ poutcome <fct> failure, other, failure, other, failure, other, other, failu…
## $ y <fct> no, yes, yes, no, yes, no, no, no, no, no, no, no, no, no, n…
Sebelum membuat model, kita akan memisahkan data bank menjadi data train dan data test.
RNGkind(sample.kind = "Rounding")
## Warning in RNGkind(sample.kind = "Rounding"): non-uniform 'Rounding' sampler
## used
set.seed(2012)
index <- initial_split(data = bank_clean,
prop = 0.8,
strata = "y")
bank_train <- training(index)
bank_test <- testing(index)
Cek proporsi data train
prop.table(table(bank_train$y))
##
## no yes
## 0.7717011 0.2282989
Dari hasil di atas, data train belum seimbang, maka akan kita upsampling pada data tersebut
set.seed(2012)
bank_train.up <- upSample(x = bank_train %>% select(-y),
y = bank_train$y,
yname = "y")
Cek kembali proporsi data train
prop.table(table(bank_train.up$y))
##
## no yes
## 0.5 0.5
Dapat dilihat data train sudah memiliki proporsi yang seimbang.
Naive Bayes adalah metode yang cocok untuk klasifikasi biner dan multiclass. Metode yang juga dikenal sebagai Naive Bayes Classifier ini menerapkan teknik supervised klasifikasi objek di masa depan dengan menetapkan label kelas ke instance/catatan menggunakan probabilitas bersyarat.
Model naive yang akan kita buat adalah sebagai berikut
model_naive <- naiveBayes(formula = y ~.,
data = bank_train.up,
laplace = 1)
Buat prediksi dari model naive
pred.naive <- predict(model_naive, newdata = bank_test,
type = "class")
Decision tree adalah amachine learning yang menggunakan seperangkat aturan untuk membuat keputusan dengan struktur seperti pohon yang memodelkan kemungkinan hasil, biaya sumber daya, utilitas dan kemungkinan konsekuensi atau resiko.
Berikut model decision tree yang akan kita buat:
model_dtree <- ctree(formula = y ~.,
data = bank_train.up,
control = ctree_control(mincriterion = 0.97))
plot(model_dtree,
type = "simple")
Kemudian kita juga akan membuat prediksi dari model tersebut
test_pred <- predict(object = model_dtree,
newdata = bank_test,
type = "response")
train_pred <- predict(object = model_dtree,
newdata = bank_train.up,
type = "response")
#{-}
confusionMatrix(data = pred.naive,
reference = bank_test$y,
positive = "yes")
## Confusion Matrix and Statistics
##
## Reference
## Prediction no yes
## no 941 84
## yes 273 276
##
## Accuracy : 0.7732
## 95% CI : (0.7517, 0.7937)
## No Information Rate : 0.7713
## P-Value [Acc > NIR] : 0.4425
##
## Kappa : 0.4573
##
## Mcnemar's Test P-Value : <0.0000000000000002
##
## Sensitivity : 0.7667
## Specificity : 0.7751
## Pos Pred Value : 0.5027
## Neg Pred Value : 0.9180
## Prevalence : 0.2287
## Detection Rate : 0.1753
## Detection Prevalence : 0.3488
## Balanced Accuracy : 0.7709
##
## 'Positive' Class : yes
##
Model naive menghasilkan accuracy sebesar 77%, sensitivity sebesar 76%, dan precision sebesar 50%
confusionMatrix(data = test_pred, reference = bank_test$y,
positive = "yes")
## Confusion Matrix and Statistics
##
## Reference
## Prediction no yes
## no 980 66
## yes 234 294
##
## Accuracy : 0.8094
## 95% CI : (0.7891, 0.8285)
## No Information Rate : 0.7713
## P-Value [Acc > NIR] : 0.000136
##
## Kappa : 0.5359
##
## Mcnemar's Test P-Value : < 0.00000000000000022
##
## Sensitivity : 0.8167
## Specificity : 0.8072
## Pos Pred Value : 0.5568
## Neg Pred Value : 0.9369
## Prevalence : 0.2287
## Detection Rate : 0.1868
## Detection Prevalence : 0.3355
## Balanced Accuracy : 0.8120
##
## 'Positive' Class : yes
##
Hasi evaluasi model dtree pada data test menghasilkan accuracy sebesar 80%, Sensistivity sebesar 81%, dan post pred values sebesar 55%
confusionMatrix(data = train_pred, reference = bank_train.up$y,
positive = "yes")
## Confusion Matrix and Statistics
##
## Reference
## Prediction no yes
## no 3980 461
## yes 874 4393
##
## Accuracy : 0.8625
## 95% CI : (0.8555, 0.8693)
## No Information Rate : 0.5
## P-Value [Acc > NIR] : < 0.00000000000000022
##
## Kappa : 0.725
##
## Mcnemar's Test P-Value : < 0.00000000000000022
##
## Sensitivity : 0.9050
## Specificity : 0.8199
## Pos Pred Value : 0.8341
## Neg Pred Value : 0.8962
## Prevalence : 0.5000
## Detection Rate : 0.4525
## Detection Prevalence : 0.5425
## Balanced Accuracy : 0.8625
##
## 'Positive' Class : yes
##
Hasi evaluasi model dtree pada data train menghasilkan accuracy sebesar 86%, Sensistivity sebesar 90%, dan post pred values sebesar 83%
Hasi evaluasi model dtree pada data test menghasilkan accuracy sebesar 80%, Sensistivity sebesar 81%, dan post pred values sebesar 55%. Oleh karena itu kita akan memilih model dtree untuk melakukan prediksi pada dataset telemarketing bank protugal. Selain itu sensitivity lebih penting pada kasus ini karena tentunya bank portugis tidak mau melewakan satu pun potential customer produk yang mereka tawarkan.