1 Pendahuluan

Customer churn (berhentinya pelanggan) merupakan ancaman utama bagi bisnis telekomunikasi, karena biaya mendapatkan pelanggan baru jauh lebih besar daripada biaya mempertahankan pelanggan yang ada. Laporan ini menganalisis dataset Telco Customer Churn dengan tujuan:

  1. Mengidentifikasi profil pelanggan yang berisiko churn melalui eksplorasi data.
  2. Membangun model klasifikasi churn dengan K-Nearest Neighbors (KNN) dan Naive Bayes, lalu memilih model yang paling sesuai untuk kebutuhan bisnis.
  3. Menemukan pola keterkaitan fitur yang mendorong churn maupun loyalitas dengan Association Rules (Apriori).
  4. Merumuskan rekomendasi strategi retensi beserta batasannya.

2 Persiapan Data

2.1 Pembersihan Data

data_raw <- read.csv("Telco-Customer-Churn.csv", stringsAsFactors = FALSE)

# TotalCharges bisa terbaca sebagai teks (berisi spasi) atau angka (berisi NA): tangkap keduanya
empty_idx  <- which(is.na(suppressWarnings(as.numeric(trimws(data_raw$TotalCharges)))))
empty_rows <- data_raw[empty_idx, c("customerID", "tenure", "MonthlyCharges", "TotalCharges", "Churn")]

kable(head(empty_rows, 5), row.names = FALSE,
      caption = paste0("Pelanggan dengan TotalCharges Kosong (5 dari ", nrow(empty_rows), " amatan)")) %>% tbl_style()
Pelanggan dengan TotalCharges Kosong (5 dari 11 amatan)
customerID tenure MonthlyCharges TotalCharges Churn
4472-LVYGI 0 52.55 NA No
3115-CZMZD 0 20.25 NA No
5709-LVOEQ 0 80.85 NA No
4367-NUYAO 0 25.75 NA No
1371-DWPAZ 0 56.05 NA No

Dataset awal terdiri dari 7043 baris dan 21 kolom. Kolom TotalCharges memiliki 11 amatan yang kosong (tidak terisi). Seluruhnya adalah pelanggan baru dengan tenure = 0 dan Churn = No yang belum melewati siklus penagihan pertama. Jumlahnya hanya 0,16% dari data, sehingga baris tersebut dihapus.

data_clean <- data_raw
data_clean$TotalCharges <- as.numeric(trimws(data_clean$TotalCharges))
data_clean <- data_clean[!is.na(data_clean$TotalCharges), ]
data_clean$customerID <- NULL
data_clean$SeniorCitizen <- factor(ifelse(data_clean$SeniorCitizen == 1, "Yes", "No"))

chr_cols <- sapply(data_clean, is.character)
data_clean[chr_cols] <- lapply(data_clean[chr_cols], as.factor)
data_clean$Churn <- factor(data_clean$Churn, levels = c("No", "Yes"))

Data bersih berisi 7032 amatan dengan 19 variabel prediktor dan satu variabel target (Churn).

2.2 Eksplorasi Data

  • Proporsi churn: 26,58% pelanggan (1869 orang) berhenti berlangganan, sedangkan 73,42% bertahan. Kelas yang tidak seimbang ini perlu diperhatikan saat membaca metrik evaluasi.
  • Tenure: median tenure pelanggan churn hanya 10 bulan dibanding 38 bulan pada pelanggan yang bertahan, sehingga risiko churn terkonsentrasi di awal masa berlangganan.
  • Biaya bulanan: median tagihan pelanggan churn ($79,7) lebih tinggi daripada pelanggan yang bertahan ($64,4).
  • Kontrak: churn pada kontrak month-to-month mencapai 42,7%, jauh di atas kontrak satu tahun (11,3%) dan dua tahun (2,8%).
  • Layanan internet: pengguna Fiber optic memiliki churn 41,9%, dibanding DSL (19,0%) dan tanpa internet (7,4%).

2.3 Pembagian Data Latih dan Uji

Data dibagi secara stratified dengan rasio 80:20 menggunakan set.seed(0013).

set.seed(0013)
train_index <- createDataPartition(data_clean$Churn, p = 0.8, list = FALSE)
train_raw <- data_clean[train_index, ]
test_raw  <- data_clean[-train_index, ]
train_y <- train_raw$Churn
test_y  <- test_raw$Churn

cat("Data latih:", nrow(train_raw), "amatan\n")
Data latih: 5627 amatan
cat("Data uji  :", nrow(test_raw), "amatan\n")
Data uji  : 1405 amatan

3 Klasifikasi K-Nearest Neighbors (KNN)

3.1 Normalisasi Data

KNN mengklasifikasikan data berdasarkan jarak Euclidean ke tetangga terdekat. Pada data ini, TotalCharges berkisar hingga 8.685, sedangkan tenure hanya hingga 72 dan variabel dummy hanya bernilai 0 atau 1. Tanpa normalisasi, TotalCharges akan mendominasi perhitungan jarak, sehingga seluruh fitur dinormalisasi dengan Min-Max ke rentang \([0, 1]\). Nilai minimum dan maksimum diambil dari data latih saja agar tidak terjadi kebocoran data.

# One-hot encoding
dummies     <- dummyVars(Churn ~ ., data = train_raw)
train_dummy <- predict(dummies, newdata = train_raw)
test_dummy  <- predict(dummies, newdata = test_raw)

# Min-Max scaling berdasarkan data latih
col_min   <- apply(train_dummy, 2, min)
col_range <- apply(train_dummy, 2, max) - col_min
col_range[col_range == 0] <- 1

train_x <- as.data.frame(scale(train_dummy, center = col_min, scale = col_range))
test_x  <- as.data.frame(scale(test_dummy,  center = col_min, scale = col_range))

3.2 Pemilihan Nilai k

Nilai \(k\) dipilih dari \(\{1, 3, 5, \dots, 41\}\) menggunakan 5-fold cross-validation pada data latih, berdasarkan akurasi rata-rata.

k_candidates <- seq(1, 41, by = 2)
set.seed(0013)
folds <- createFolds(train_y, k = 5)

cv_acc <- sapply(k_candidates, function(k) {
  mean(sapply(folds, function(idx) {
    pred <- knn(train_x[-idx, ], train_x[idx, ], cl = train_y[-idx], k = k)
    mean(pred == train_y[idx])
  }))
})

cv_results <- data.frame(k = k_candidates, Accuracy = cv_acc)
best_k <- cv_results$k[which.max(cv_results$Accuracy)]

Nilai \(k\) terbaik adalah \(k = 33\) dengan akurasi validasi silang 78,85%.

3.3 Evaluasi pada Data Uji

knn_pred <- knn(train_x, test_x, cl = train_y, k = best_k)
cm_knn   <- confusionMatrix(knn_pred, test_y, positive = "Yes")
cm_knn$table
          Reference
Prediction  No Yes
       No  863 143
       Yes 169 230

4 Klasifikasi Naive Bayes

4.1 Asumsi Independensi Bersyarat

Naive Bayes menghitung peluang kelas berdasarkan Teorema Bayes dengan asumsi bahwa antar fitur saling independen jika kelas diketahui:

\[P(Y = c \mid \mathbf{X}) \propto P(Y = c) \prod_{j=1}^{p} P(X_j \mid Y = c)\]

Asumsi ini dilanggar pada beberapa fitur dalam dataset:

  1. MonthlyCharges dan TotalCharges: \(TotalCharges \approx tenure \times MonthlyCharges\), dengan korelasi 0,65. Keduanya membawa informasi biaya yang sama.
  2. PhoneService dan MultipleLines: pelanggan tanpa layanan telepon otomatis bernilai “No phone service” pada MultipleLines.
  3. InternetService dan layanan tambahan (OnlineSecurity, OnlineBackup, DeviceProtection, TechSupport, StreamingTV, StreamingMovies): tanpa internet, keenam fitur ini otomatis bernilai “No internet service”.
  4. tenure dan Contract: pelanggan dengan tenure panjang cenderung memiliki kontrak 1 atau 2 tahun.

Pelanggaran ini membuat probabilitas posterior cenderung terlalu ekstrem (overconfident), tetapi untuk klasifikasi biner Naive Bayes umumnya tetap bekerja baik.

4.2 Evaluasi pada Data Uji

nb_model <- naiveBayes(Churn ~ ., data = train_raw)
nb_pred  <- predict(nb_model, newdata = test_raw)
cm_nb    <- confusionMatrix(nb_pred, test_y, positive = "Yes")
cm_nb$table
          Reference
Prediction  No Yes
       No  688  67
       Yes 344 306

5 Perbandingan Model

Kinerja Model pada Data Uji (kelas positif: Churn = Yes)
Metrik KNN (k = 33) Naive Bayes
Akurasi 0,7779 0,7075
Presisi 0,5764 0,4708
Recall 0,6166 0,8204
Spesifisitas 0,8362 0,6667
F1-Score 0,5959 0,5982

5.1 Pertimbangan Bisnis dan Rekomendasi Model

Dalam konteks retensi pelanggan, kedua jenis kesalahan memiliki biaya yang berbeda:

  • False Negative (churn tidak terdeteksi): perusahaan kehilangan pendapatan berulang dan harus menanggung biaya akuisisi pelanggan pengganti.
  • False Positive (pelanggan setia diprediksi churn): perusahaan hanya mengeluarkan biaya kecil untuk promosi atau layanan retensi.

Dari 373 pelanggan yang benar-benar churn pada data uji, KNN melewatkan 143 pelanggan (FP = 169), sedangkan Naive Bayes melewatkan 67 pelanggan (FP = 344).

Model yang direkomendasikan: Naive Bayes. Karena biaya false negative jauh lebih besar daripada false positive, model dengan recall tertinggi dipilih. Naive Bayes memiliki recall 82,04% dan hanya melewatkan 67 dari 373 pelanggan churn.

6 Analisis Asosiasi (Association Rules)

6.1 Diskritisasi dan Pembentukan Transaksi

Apriori membutuhkan data kategorik, sehingga tiga fitur numerik dikelompokkan sebagai berikut:

Fitur Kategori
tenure Short (0–12 bulan), Medium (13–48 bulan), Long (49–72 bulan)
MonthlyCharges Low (< 35), Med (35–70), High (> 70)
TotalCharges Low (< 1.000), Med (1.000–4.000), High (> 4.000)
data_arules <- data_clean

data_arules$tenure_cat <- cut(data_arules$tenure, breaks = c(-1, 12, 48, 72),
  labels = c("Tenure_Short(0-12m)", "Tenure_Medium(13-48m)", "Tenure_Long(49-72m)"))
data_arules$MonthlyCharges_cat <- cut(data_arules$MonthlyCharges, breaks = c(0, 35, 70, 150),
  labels = c("Charge_Low(<35)", "Charge_Med(35-70)", "Charge_High(>70)"))
data_arules$TotalCharges_cat <- cut(data_arules$TotalCharges, breaks = c(-1, 1000, 4000, 10000),
  labels = c("Total_Low(<1k)", "Total_Med(1k-4k)", "Total_High(>4k)"))

data_arules <- data_arules[, !(names(data_arules) %in% c("tenure", "MonthlyCharges", "TotalCharges"))]
trans <- as(data_arules, "transactions")

6.2 Metrik Evaluasi Aturan

Untuk aturan \(X \Rightarrow Y\) dengan \(N\) transaksi:

Metrik Rumus Makna
Support \(P(X \cap Y)\) Seberapa sering \(X\) dan \(Y\) muncul bersama
Confidence \(P(Y \mid X)\) Peluang \(Y\) muncul jika \(X\) muncul
Lift \(\dfrac{Conf(X \Rightarrow Y)}{P(Y)}\) Lift > 1 berarti asosiasi positif
Leverage \(P(X \cap Y) - P(X)P(Y)\) Selisih kemunculan bersama dari yang diharapkan jika independen
Conviction \(\dfrac{1 - P(Y)}{1 - Conf(X \Rightarrow Y)}\) Semakin besar, semakin kuat ketergantungan aturan

6.3 Penambangan Aturan

Aturan ditambang secara terpisah untuk Churn=Yes dan Churn=No. Aturan untuk Churn=No memakai ambang yang lebih ketat karena kelas ini jauh lebih dominan.

mine_rules <- function(rhs, supp, conf) {
  r <- apriori(trans,
               parameter  = list(supp = supp, conf = conf, minlen = 2, maxlen = 4),
               appearance = list(rhs = rhs, default = "lhs"),
               control    = list(verbose = FALSE))
  quality(r) <- cbind(quality(r), interestMeasure(r, c("leverage", "conviction"), transactions = trans))
  r
}

rules_yes <- mine_rules("Churn=Yes", supp = 0.05, conf = 0.65)
rules_no  <- mine_rules("Churn=No",  supp = 0.15, conf = 0.90)

# Ambil aturan dengan LHS tertentu
pick_rule <- function(rules, lhs_items, target) {
  lhs_list <- as(lhs(rules), "list")
  idx <- which(sapply(lhs_list, setequal, lhs_items))
  q <- quality(rules[idx[1]])
  data.frame(Target = target,
             Rule = labels(rules[idx[1]]),
             Support = q$support, Count = q$count, Confidence = q$confidence,
             Lift = q$lift, Leverage = q$leverage, Conviction = q$conviction)
}

rule_tbl <- rbind(
  pick_rule(rules_yes, c("InternetService=Fiber optic", "PaperlessBilling=Yes", "tenure_cat=Tenure_Short(0-12m)"), "Churn=Yes"),
  pick_rule(rules_yes, c("InternetService=Fiber optic", "OnlineSecurity=No", "tenure_cat=Tenure_Short(0-12m)"), "Churn=Yes"),
  pick_rule(rules_no,  "Contract=Two year", "Churn=No")
)
Tiga Aturan Asosiasi Utama
Aturan Support Confidence Lift Leverage Conviction
Rule 1: {InternetService=Fiber optic, PaperlessBilling=Yes, tenure_cat=Tenure_Short(0-12m)} => {Churn=Yes} 0,0745 0,7228 2,7193 0,0471 2,6483
Rule 2: {InternetService=Fiber optic, OnlineSecurity=No, tenure_cat=Tenure_Short(0-12m)} => {Churn=Yes} 0,0853 0,7168 2,6971 0,0537 2,5930
Rule 3: {Contract=Two year} => {Churn=No} 0,2328 0,9715 1,3232 0,0569 9,3302

6.4 Interpretasi Aturan

Rule 1: Pelanggan baru Fiber optic dengan tagihan digital \(\Rightarrow\) Churn

  • Support 0,0745 (524 pelanggan), confidence 72,28%, lift 2,72.
  • Pelanggan fiber optik di tahun pertama dengan tagihan digital 2,72 kali lebih berisiko churn dibanding rata-rata. Hal ini mengindikasikan kekecewaan terhadap biaya awal atau kualitas layanan saat onboarding.

Rule 2: Pelanggan baru Fiber optic tanpa Online Security \(\Rightarrow\) Churn

  • Support 0,0853 (600 pelanggan), confidence 71,68%, lift 2,70.
  • Tanpa layanan tambahan seperti keamanan internet, pelanggan merasa membayar tarif tinggi tanpa dukungan produk yang lengkap sehingga lebih mudah berpindah.

Rule 3: Kontrak dua tahun \(\Rightarrow\) Tidak churn

  • Support 0,2328 (1637 pelanggan), confidence 97,15%, lift 1,32, conviction 9,33.
  • Kontrak jangka panjang menjadi pengunci loyalitas terkuat: hanya sekitar 2,8% pelanggan kontrak dua tahun yang berhenti.

7 Rekomendasi Manajemen

7.1 Keterkaitan Hasil Klasifikasi dan Asosiasi

Hasil eksplorasi data, model klasifikasi, dan aturan asosiasi saling menguatkan: risiko churn tertinggi ada pada pelanggan baru (0–12 bulan) berkontrak month-to-month, menggunakan Fiber optic, dan tanpa layanan tambahan. Segmen ini dapat dijaring lebih awal dengan model Naive Bayes (recall 82,04%).

7.2 Strategi yang Disarankan

  1. Program First-Year Care untuk pelanggan fiber optik baru. Dampingi pelanggan selama 90 hari pertama melalui pengecekan kestabilan jaringan pascapemasangan dan penjelasan rincian tagihan, guna mengurangi churn dini (Rule 1).
  2. Bundling layanan tambahan dengan migrasi kontrak. Berikan Online Security dan Tech Support gratis selama 6–12 bulan bagi pelanggan month-to-month yang beralih ke kontrak minimal 1 tahun (Rule 2 dan 3).
  3. Insentif metode pembayaran otomatis. Pelanggan Electronic check memiliki churn 45,3%, jauh di atas rata-rata keseluruhan (26,6%). Potongan tagihan kecil untuk pendaftar autodebet dapat mengurangi risiko ini.

7.3 Batasan Rekomendasi

  • Margin keuntungan: layanan gratis dan diskon menekan pendapatan per pelanggan (ARPU) jangka pendek, sehingga perlu dihitung terhadap Customer Lifetime Value.
  • Penerimaan pelanggan: dorongan kontrak jangka panjang yang terlalu agresif dapat menurunkan minat pendaftaran pelanggan baru.
  • Kapasitas operasional: program pendampingan membutuhkan tambahan tim dukungan dan teknisi, terutama di wilayah dengan pengguna fiber optik yang banyak.
  • Keterbatasan data: aturan asosiasi menunjukkan keterkaitan, bukan sebab-akibat, sehingga efektivitas strategi sebaiknya diuji lewat percobaan terbatas sebelum diterapkan penuh.

8 Lampiran: Perhitungan Manual

Lampiran ini memverifikasi logika masing-masing algoritma menggunakan data mini.

8.1 Lampiran 1: Prediksi KNN

Data latih mini (5 pelanggan) dengan fitur Tenure (\(X_1\)) dan MonthlyCharges (\(X_2\)):

Data Latih Mini KNN
ID Tenure MonthlyCharges Churn
1 2 75 Yes
2 6 85 Yes
3 24 30 No
4 48 90 No
5 60 20 No

Akan diprediksi pelanggan baru \((\text{Tenure} = 4, \text{MonthlyCharges} = 80)\) dengan \(k = 3\).

Langkah 1: Normalisasi Min-Max. Rentang Tenure \(= 60 - 2 = 58\) dan rentang MonthlyCharges \(= 90 - 20 = 70\).

  • Titik baru: \(\left(\frac{4-2}{58}, \frac{80-20}{70}\right) = (0{,}0345;\ 0{,}8571)\)
  • \(P_1 = (0{,}0000;\ 0{,}7857)\), \(P_2 = (0{,}0690;\ 0{,}9286)\), \(P_3 = (0{,}3793;\ 0{,}1429)\), \(P_4 = (0{,}7931;\ 1{,}0000)\), \(P_5 = (1{,}0000;\ 0{,}0000)\)

Langkah 2: Jarak Euclidean ke titik baru.

Titik Perhitungan Jarak Kelas
\(P_1\) \(\sqrt{0{,}0345^2 + 0{,}0714^2}\) 0,0793 Yes
\(P_2\) \(\sqrt{0{,}0345^2 + 0{,}0715^2}\) 0,0794 Yes
\(P_3\) \(\sqrt{0{,}3448^2 + 0{,}7142^2}\) 0,7931 No
\(P_4\) \(\sqrt{0{,}7586^2 + 0{,}1429^2}\) 0,7719 No
\(P_5\) \(\sqrt{0{,}9655^2 + 0{,}8571^2}\) 1,2911 No

Langkah 3: Voting. Tiga tetangga terdekat adalah \(P_1\) (Yes), \(P_2\) (Yes), dan \(P_4\) (No). Suara Yes = 2 dan No = 1, sehingga prediksi: \(\hat{Y} = \textbf{Yes}\).

8.2 Lampiran 2: Prediksi Naive Bayes

Data latih mini (6 pelanggan) dengan fitur Contract, InternetService, TechSupport:

Data Latih Mini Naive Bayes
ID Contract InternetService TechSupport Churn
1 Month-to-month Fiber optic No Yes
2 Month-to-month DSL Yes No
3 One year DSL Yes No
4 Two year No No internet service No
5 Month-to-month Fiber optic No Yes
6 Two year Fiber optic Yes No

Akan diprediksi pelanggan baru (Contract = Month-to-month, InternetService = Fiber optic, TechSupport = No).

Langkah 1: Prior. \(P(\text{Yes}) = \frac{2}{6} = 0{,}3333\) dan \(P(\text{No}) = \frac{4}{6} = 0{,}6667\).

Langkah 2: Likelihood dengan Laplace smoothing \(\left(\frac{n + 1}{N_{\text{kelas}} + K}\right)\), dengan \(K = 3\) kategori pada setiap fitur.

Likelihood Kelas Yes (\(N = 2\)) Kelas No (\(N = 4\))
\(P(\text{Contract = Month-to-month} \mid \cdot)\) \(\frac{2+1}{2+3} = 0{,}6000\) \(\frac{1+1}{4+3} = 0{,}2857\)
\(P(\text{InternetService = Fiber optic} \mid \cdot)\) \(\frac{2+1}{2+3} = 0{,}6000\) \(\frac{1+1}{4+3} = 0{,}2857\)
\(P(\text{TechSupport = No} \mid \cdot)\) \(\frac{2+1}{2+3} = 0{,}6000\) \(\frac{0+1}{4+3} = 0{,}1429\)

Langkah 3: Skor posterior tak ternormalisasi.

\[\text{Skor}(\text{Yes}) = \frac{1}{3} \times 0{,}6^3 = \mathbf{0{,}0720}\] \[\text{Skor}(\text{No}) = \frac{2}{3} \times 0{,}2857 \times 0{,}2857 \times 0{,}1429 \approx \mathbf{0{,}00777}\]

Langkah 4: Normalisasi dan keputusan.

\[P(\text{Yes} \mid \mathbf{x}) = \frac{0{,}0720}{0{,}0720 + 0{,}00777} \approx 90{,}26\%, \qquad P(\text{No} \mid \mathbf{x}) \approx 9{,}74\%\]

Karena \(P(\text{Yes} \mid \mathbf{x}) > P(\text{No} \mid \mathbf{x})\), prediksi: \(\hat{Y} = \textbf{Yes}\).

8.3 Lampiran 3: Metrik Association Rules

Dari \(N = 10\) transaksi dengan atribut \(A\) = Contract = Month-to-month dan \(B\) = Churn = Yes:

Tabel Kontingensi 10 Transaksi
Churn=Yes (B) Churn=No
Month-to-month (A) 5 1
Bukan Month-to-month 2 2

Diperoleh \(n(A \cap B) = 5\), \(n(A) = 6\), dan \(n(B) = 7\), sehingga \(Supp(A) = 0{,}60\) dan \(Supp(B) = 0{,}70\). Metrik untuk aturan \(A \Rightarrow B\):

Metrik Perhitungan Hasil
Support \(\frac{5}{10}\) 0,5000
Confidence \(\frac{0{,}50}{0{,}60}\) 0,8333
Lift \(\frac{0{,}8333}{0{,}70}\) 1,1905
Leverage \(0{,}50 - (0{,}60 \times 0{,}70)\) +0,0800
Conviction \(\frac{1 - 0{,}70}{1 - 0{,}8333}\) 1,8000

Lift > 1, leverage positif, dan conviction > 1 menunjukkan bahwa kontrak month-to-month berasosiasi positif dengan churn, dengan risiko 1,19 kali lebih tinggi dari rata-rata.