#Library yang akan digunakan
Tahap awal kita akan menginstall packages yang akan kita gunakan.
library(tidyverse)
library(SnowballC)
library(textstem)
library(ROCR)
library(caret)
library(class)
library(partykit)
library(e1071)
telco <- read.csv("telcochurn.csv", stringsAsFactors = T)
head(telco)
## X customerID gender SeniorCitizen Partner Dependents tenure PhoneService
## 1 1 7590-VHVEG Female 0 Yes No 1 No
## 2 2 5575-GNVDE Male 0 No No 34 Yes
## 3 3 3668-QPYBK Male 0 No No 2 Yes
## 4 4 7795-CFOCW Male 0 No No 45 No
## 5 5 9237-HQITU Female 0 No No 2 Yes
## 6 6 9305-CDSKC Female 0 No No 8 Yes
## MultipleLines InternetService OnlineSecurity OnlineBackup DeviceProtection
## 1 No DSL No Yes No
## 2 No DSL Yes No Yes
## 3 No DSL Yes Yes No
## 4 No DSL Yes No Yes
## 5 No Fiber optic No No No
## 6 Yes Fiber optic No No Yes
## TechSupport StreamingTV StreamingMovies Contract PaperlessBilling
## 1 No No No Month-to-month Yes
## 2 No No No One year No
## 3 No No No Month-to-month Yes
## 4 Yes No No One year No
## 5 No No No Month-to-month Yes
## 6 No Yes Yes Month-to-month Yes
## PaymentMethod MonthlyCharges TotalCharges Churn
## 1 Electronic check 29.85 29.85 No
## 2 Mailed check 56.95 1889.50 No
## 3 Mailed check 53.85 108.15 Yes
## 4 Bank transfer (automatic) 42.30 1840.75 No
## 5 Electronic check 70.70 151.65 Yes
## 6 Electronic check 99.65 820.50 Yes
Dengan data ini, kita akan memprediksi apakah seseorang akan melanjutkan langganan akan layanan yang kita berikan.
glimpse(telco)
## Rows: 7,043
## Columns: 22
## $ X <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16~
## $ customerID <fct> 7590-VHVEG, 5575-GNVDE, 3668-QPYBK, 7795-CFOCW, 9237-~
## $ gender <fct> Female, Male, Male, Male, Female, Female, Male, Femal~
## $ SeniorCitizen <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,~
## $ Partner <fct> Yes, No, No, No, No, No, No, No, Yes, No, Yes, No, Ye~
## $ Dependents <fct> No, No, No, No, No, No, Yes, No, No, Yes, Yes, No, No~
## $ tenure <int> 1, 34, 2, 45, 2, 8, 22, 10, 28, 62, 13, 16, 58, 49, 2~
## $ PhoneService <fct> No, Yes, Yes, No, Yes, Yes, Yes, No, Yes, Yes, Yes, Y~
## $ MultipleLines <fct> No, No, No, No, No, Yes, Yes, No, Yes, No, No, No, Ye~
## $ InternetService <fct> DSL, DSL, DSL, DSL, Fiber optic, Fiber optic, Fiber o~
## $ OnlineSecurity <fct> No, Yes, Yes, Yes, No, No, No, Yes, No, Yes, Yes, No,~
## $ OnlineBackup <fct> Yes, No, Yes, No, No, No, Yes, No, No, Yes, No, No, N~
## $ DeviceProtection <fct> No, Yes, No, Yes, No, Yes, No, No, Yes, No, No, No, Y~
## $ TechSupport <fct> No, No, No, Yes, No, No, No, No, Yes, No, No, No, No,~
## $ StreamingTV <fct> No, No, No, No, No, Yes, Yes, No, Yes, No, No, No, Ye~
## $ StreamingMovies <fct> No, No, No, No, No, Yes, No, No, Yes, No, No, No, Yes~
## $ Contract <fct> Month-to-month, One year, Month-to-month, One year, M~
## $ PaperlessBilling <fct> Yes, No, Yes, No, Yes, Yes, Yes, No, Yes, No, Yes, No~
## $ PaymentMethod <fct> Electronic check, Mailed check, Mailed check, Bank tr~
## $ MonthlyCharges <dbl> 29.85, 56.95, 53.85, 42.30, 70.70, 99.65, 89.10, 29.7~
## $ TotalCharges <dbl> 29.85, 1889.50, 108.15, 1840.75, 151.65, 820.50, 1949~
## $ Churn <fct> No, No, Yes, No, Yes, Yes, No, No, Yes, No, No, No, N~
Hal yang bisa dibersihkan 1. data X dan Customer Id akan dihapus karena data tersebut tidak memiliki efek dalam prediksi 2. semua data type yang bersifat character akan kita ubah menjadi kategori (sudah diubah saat read data) 3. data type Int dan Num tidak akan diubah 4. list Senior Citizen akan kita ubah dari 0 dan 1 menjadi No dan Yes. kategory Int diubah menjadi kategori
telco <- telco %>%
mutate(SeniorCitizen = as.character(SeniorCitizen),
SeniorCitizen = ifelse(SeniorCitizen == "0","No", "Yes"),
SeniorCitizen = as.factor(SeniorCitizen)) %>%
select(-c(X, customerID))
glimpse(telco)
## Rows: 7,043
## Columns: 20
## $ gender <fct> Female, Male, Male, Male, Female, Female, Male, Femal~
## $ SeniorCitizen <fct> No, No, No, No, No, No, No, No, No, No, No, No, No, N~
## $ Partner <fct> Yes, No, No, No, No, No, No, No, Yes, No, Yes, No, Ye~
## $ Dependents <fct> No, No, No, No, No, No, Yes, No, No, Yes, Yes, No, No~
## $ tenure <int> 1, 34, 2, 45, 2, 8, 22, 10, 28, 62, 13, 16, 58, 49, 2~
## $ PhoneService <fct> No, Yes, Yes, No, Yes, Yes, Yes, No, Yes, Yes, Yes, Y~
## $ MultipleLines <fct> No, No, No, No, No, Yes, Yes, No, Yes, No, No, No, Ye~
## $ InternetService <fct> DSL, DSL, DSL, DSL, Fiber optic, Fiber optic, Fiber o~
## $ OnlineSecurity <fct> No, Yes, Yes, Yes, No, No, No, Yes, No, Yes, Yes, No,~
## $ OnlineBackup <fct> Yes, No, Yes, No, No, No, Yes, No, No, Yes, No, No, N~
## $ DeviceProtection <fct> No, Yes, No, Yes, No, Yes, No, No, Yes, No, No, No, Y~
## $ TechSupport <fct> No, No, No, Yes, No, No, No, No, Yes, No, No, No, No,~
## $ StreamingTV <fct> No, No, No, No, No, Yes, Yes, No, Yes, No, No, No, Ye~
## $ StreamingMovies <fct> No, No, No, No, No, Yes, No, No, Yes, No, No, No, Yes~
## $ Contract <fct> Month-to-month, One year, Month-to-month, One year, M~
## $ PaperlessBilling <fct> Yes, No, Yes, No, Yes, Yes, Yes, No, Yes, No, Yes, No~
## $ PaymentMethod <fct> Electronic check, Mailed check, Mailed check, Bank tr~
## $ MonthlyCharges <dbl> 29.85, 56.95, 53.85, 42.30, 70.70, 99.65, 89.10, 29.7~
## $ TotalCharges <dbl> 29.85, 1889.50, 108.15, 1840.75, 151.65, 820.50, 1949~
## $ Churn <fct> No, No, Yes, No, Yes, Yes, No, No, Yes, No, No, No, N~
Selanjutnya kita akan memeriksa apakah adanya Missing Value pada data
anyNA(telco)
## [1] TRUE
colSums(is.na(telco))
## gender SeniorCitizen Partner Dependents
## 0 0 0 0
## tenure PhoneService MultipleLines InternetService
## 0 0 0 0
## OnlineSecurity OnlineBackup DeviceProtection TechSupport
## 0 0 0 0
## StreamingTV StreamingMovies Contract PaperlessBilling
## 0 0 0 0
## PaymentMethod MonthlyCharges TotalCharges Churn
## 0 0 11 0
disini kita menemukan adanya Missing Value berjumlah 11 pada Total Charges, kita akan mengisi 11 NA dengan nilai rata2.
telco <- telco %>%
mutate(TotalCharges = replace_na(TotalCharges,
replace = mean(TotalCharges,
na.rm = T)))
colSums(is.na(telco))
## gender SeniorCitizen Partner Dependents
## 0 0 0 0
## tenure PhoneService MultipleLines InternetService
## 0 0 0 0
## OnlineSecurity OnlineBackup DeviceProtection TechSupport
## 0 0 0 0
## StreamingTV StreamingMovies Contract PaperlessBilling
## 0 0 0 0
## PaymentMethod MonthlyCharges TotalCharges Churn
## 0 0 0 0
dengan begini data yang akan kita gunakan sudah cocok dan tidak ada missing value.
kita terlebih dahulu memeriksa apakah proposi data sudah bagus (notes : target = churn)
prop.table(table(telco$Churn))
##
## No Yes
## 0.7346301 0.2653699
kita akan membagi data menjadi 2 bagian dimana data train akan berjumlah 70% dari total data
RNGkind(sample.kind = "Rounding")
set.seed(417)
idx <- sample(nrow(telco), nrow(telco)*0.7)
train_telco <- telco[idx,]
test_telco <- telco[-idx,]
prop.table(table(train_telco$Churn))
##
## No Yes
## 0.7375254 0.2624746
prop.table(table(test_telco$Churn))
##
## No Yes
## 0.7278751 0.2721249
Kita akan membuat model Naive Bayes dengan menggunakan data train
model_churn <- naiveBayes(Churn~., train_telco)
kita sudah membuat model dengan kode assign model_churn. sekarang kita akan melakukan prediksi terhadap 30% data test yang sudah kita sediakan.
pred <- predict(model_churn, test_telco, type = "class")
Disini kita akan melihat hasil yang kita dapat dari model dan prediksi yang sudah kita lakukan.
confusionMatrix(pred, test_telco$Churn, positive = "Yes")
## Confusion Matrix and Statistics
##
## Reference
## Prediction No Yes
## No 1225 161
## Yes 313 414
##
## Accuracy : 0.7757
## 95% CI : (0.7573, 0.7933)
## No Information Rate : 0.7279
## P-Value [Acc > NIR] : 0.000000275330597
##
## Kappa : 0.477
##
## Mcnemar's Test P-Value : 0.000000000004043
##
## Sensitivity : 0.7200
## Specificity : 0.7965
## Pos Pred Value : 0.5695
## Neg Pred Value : 0.8838
## Prevalence : 0.2721
## Detection Rate : 0.1959
## Detection Prevalence : 0.3441
## Balanced Accuracy : 0.7582
##
## 'Positive' Class : Yes
##
disini saya akan memakai ukuran Sensitivity/Recall. karena kita adalah layanan langganan dimana kita bisa memfokuskan untuk memberikan promo yang menarik sehingga para pelanggan bisa menjadi berlangganan lebih lama lagi.
confusion matrix bukanlah satu2nya tolak ukut seberapa bagus hasil prediksi kita. kita juga bisa menggunakan metode ROC/AUC
pred_prob <- predict(model_churn, newdata = test_telco, type = "raw")
head(pred_prob)
## No Yes
## [1,] 0.01451274 0.985487256379
## [2,] 0.01069848 0.989301515722
## [3,] 0.99060178 0.009398220017
## [4,] 0.65902921 0.340970790609
## [5,] 0.99999234 0.000007659987
## [6,] 0.99631363 0.003686371304
pred_rocr <- prediction(predictions = pred_prob[,2],
labels = as.numeric(ifelse(test = test_telco$Churn == "Yes", 1, 0)))
perf <- performance(prediction.obj = pred_rocr, measure = "tpr", x.measure = "fpr")
plot(perf)
auc <- performance(pred_rocr, "auc")
auc@y.values
## [[1]]
## [1] 0.8246452
kita mendapatkan hasil ROC/AUC values sebesar 82%. sehingga bisa disimpulkan kalau model bisa memprediksi dengan baik.
kita akan membuat model prediksi baru dengan menggunakan metode decision tree.
model_churn_tree <- ctree(Churn~ ., train_telco)
kita akan mencoba melihat visual dari decision tree yang sudah kita buat.
plot(model_churn_tree, type = "simple")
dengan menggunakan model churn tree, kita akan melakukan prediksi
pred_tree <- predict(model_churn_tree, newdata = test_telco, type = "response")
train_tree <- predict(model_churn_tree, newdata = train_telco, type = "response")
pred_tree_prob <- predict(model_churn_tree, newdata = test_telco, type = "prob")
kita memakai type = response yang hasilnya memberikan hasil kategori
confusionMatrix(pred_tree, reference = test_telco$Churn, positive = "Yes")
## Confusion Matrix and Statistics
##
## Reference
## Prediction No Yes
## No 1306 236
## Yes 232 339
##
## Accuracy : 0.7785
## 95% CI : (0.7602, 0.7961)
## No Information Rate : 0.7279
## P-Value [Acc > NIR] : 0.00000005364
##
## Kappa : 0.4397
##
## Mcnemar's Test P-Value : 0.8897
##
## Sensitivity : 0.5896
## Specificity : 0.8492
## Pos Pred Value : 0.5937
## Neg Pred Value : 0.8470
## Prevalence : 0.2721
## Detection Rate : 0.1604
## Detection Prevalence : 0.2702
## Balanced Accuracy : 0.7194
##
## 'Positive' Class : Yes
##
confusionMatrix(train_tree, reference = train_telco$Churn, positive = "Yes")
## Confusion Matrix and Statistics
##
## Reference
## Prediction No Yes
## No 3139 496
## Yes 497 798
##
## Accuracy : 0.7986
## 95% CI : (0.7871, 0.8097)
## No Information Rate : 0.7375
## P-Value [Acc > NIR] : <0.0000000000000002
##
## Kappa : 0.4799
##
## Mcnemar's Test P-Value : 1
##
## Sensitivity : 0.6167
## Specificity : 0.8633
## Pos Pred Value : 0.6162
## Neg Pred Value : 0.8635
## Prevalence : 0.2625
## Detection Rate : 0.1619
## Detection Prevalence : 0.2627
## Balanced Accuracy : 0.7400
##
## 'Positive' Class : Yes
##
selanjutnya kita akan memakai metode ROC/AUC untuk evaluasi model decision tree
pred_rocr_tree <- prediction(predictions = pred_tree_prob[,2],
labels = as.numeric(ifelse(test = test_telco$Churn == "Yes", 1, 0)))
perf_tree <- performance(prediction.obj = pred_rocr_tree, measure = "tpr", x.measure = "fpr")
plot(perf_tree)
auc <- performance(pred_rocr_tree, "auc")
auc@y.values
## [[1]]
## [1] 0.8229027
kita mendapatkan hasil dimana ROC/AUV value sebesar 82%.
disini kita mendapatkan hasil ROC/AUC untuk kedua metode adalah sama yaitu 82%. tapi disini saya lebih memilih untuk memakai metode Naive Bayes. karena model Naive bayes lebih ringan dalam komputerisasi dan memang cocok untuk kategorial. ditambah lagi decision tree cendrung overfitting jadi ada kemungkinan tidak bagus untuk data test selanjutnya.