1 Project Proposal : Customer Churn Prediction

2 Background

Kesetiaan pelanggan memiliki makna yang signifikan dalam konteks bisnis. Kesetiaan pelanggan tidak hanya mengindikasikan bahwa pelanggan menikmati produk atau layanan yang ditawarkan, tetapi juga menunjukkan upaya untuk membangun hubungan dengan pelanggan. Pelanggan setia cenderung terus mendukung bisnis dan memilihnya dibandingkan pesaing, serta merekomendasikan bisnis tersebut kepada rekan dan kolega mereka.

Akan lebih mudah mempertahankan pelanggan yang sudah ada daripada mendapatkan pelanggan baru. Sebagai pemilik bisnis, hal ini dapat mengimplikasikan perlunya fokus yang tertuju dalam menjalin hubungan dengan pelanggan yang sudah ada daripada berupaya untuk memperluas audiens melalui perekrutan pelanggan baru. Inilah sebabnya mengapa penting untuk memantau tingkat perpindahan pelanggan (churn rate).

Customer churn adalah tingkat di mana sebuah bisnis kehilangan pelanggan. Tingkat churn pelanggan yang tinggi mengindikasikan bahwa sebagian besar pelanggan tidak lagi ingin membeli produk atau layanan yang dapat disebabkan oleh berbagai faktor. Faktor-faktor tersebut dapat menjadi tanda bahwa bisnis teradapat kekurangan pada beberapa bagian tertentu.

Tingkat churn yang tinggi tentu merupakan sesuatu yang ingin dihindari oleh semua bisnis. Tingkat churn yang tinggi mengindikasikan bahwa pelanggan tidak puas dengan produk atau layanan yang ditawarkan. Penyebabnya dapat berupa pemasaran kepada audiens yang tidak tepat atau tidak adanya pertimbangan umpan balik dari pelanggan atau lainnya. Jika melihat bahwa bisnis memiliki tingkat churn pelanggan yang tinggi, dapat berarti saatnya melakukan beberapa perubahan agar dapat meningkatkan retensi pelanggan dan mengurangi tingkat churn secepat mungkin.

Melihat hal tersebut, project ini hadir dengan tujuan dapat melakukan prediksi terhadap kemungkinan akan terjadi churn terhadap sebuah bisnis. Prediksi akan dilakukan dengan menggunakan model machine learning seperti logistic regression, decission tree, random forest, atau model machine learning yang relevan lainnya terhadap data historis perilaku pelanggan dari sebuah bisnis. Salah satu insight yang dapat diberikan dari prediksi oleh project ini dapat memberikan sebuah peringatan awal untuk sebuah bisnis agar segera melakukan penyesuaian pada bisnisnya jika diprediksi akan adanya penurun churn,

3 Problem Statement

Masalah yang dihadapi adalah mengembangkan model prediktif yang dapat dengan akurat mengidentifikasi pelanggan yang cenderung berpindah (atau berhenti) dari layanan sebuah perusahaan. Dengan menganalisis data historis tentang perilaku pelanggan, pola penggunaan, dan faktor-faktor relevan lainnya, tujuan project ini adalah menciptakan model yang membantu dalam secara proaktif menargetkan pelanggan yang berisiko tinggi melakukan churn untuk dilakukan strategi retensi atau pencegahan terjadinya churn.

4 Project Idea

Project ini melibatkan pembangunan model machine learning, khususnya dengan memanfaatkan algoritma logistic regression, decission tree, dan random forest untuk memprediksi churn pelanggan pada data historis pelanggan. Model ini akan dilatih menggunakan dataset yang berisi berbagai fitur seperti demografi pelanggan, frekuensi penggunaan, detail kontrak, dan riwayat pembayaran. Dengan menganalisis data ini, model akan belajar pola untuk memprediksi pelanggan yang tetap berlangganan dan yang berpindah atau berhenti (churn). Dengan informasi yang telah diperoleh, diharapkan dapat membantu sebuah bisnis untuk melakukan customer retention, atau upaya yang dapat dilakukan untuk mempertahankan pelanggan yang berfokus pada pelanggan yang memiliki kemungkinan churn yang tinggi.

5 Problem Scope

Pada project ini akan digunakan sebuah dataset customer churn yang dari situs Kaggle dengan judul “Telco Customer Churn”. Dataset ini mengandung informasi sebagai berikut:

Dataset ini mencakup berbagai kategori informasi terkait pelanggan perusahaan telekomunikasi, perilaku mereka, dan penggunaan layanan. Kategori-kategori ini meliputi:

  1. Demografi:
    • CustomerID: Identifikasi unik pelanggan.

    • Gender: Jenis kelamin pelanggan (Pria, Wanita).

    • Age: Usia pelanggan saat akhir kuartal fiskal.

    • Senior Citizen: Apakah pelanggan berusia 65 tahun atau lebih (Ya, Tidak).

    • Married: Apakah pelanggan menikah (Ya, Tidak).

    • Dependents: Apakah pelanggan memiliki tanggungan (Ya, Tidak).

    • Number of Dependents: Jumlah tanggungan yang tinggal bersama pelanggan.

  2. Lokasi:
    • CustomerID: Identifikasi unik pelanggan.

    • Country, State, City: Detail lokasi tempat tinggal utama pelanggan.

    • Zip Code: Kode pos tempat tinggal utama pelanggan.

    • Lat Long, Latitude, Longitude: Koordinat geografis tempat tinggal utama pelanggan.

  3. Populasi:
    • ID: Identifikasi unik untuk setiap baris.

    • Zip Code: Kode pos tempat tinggal utama pelanggan.

    • Population: Estimasi populasi untuk area kode pos yang sesuai.

  4. Layanan:
    • CustomerID: Identifikasi unik pelanggan.

    • Quarter: Kuartal fiskal dari data yang diperoleh.

    • Referred a Friend: Apakah pelanggan merekomendasikan seseorang (Ya, Tidak).

    • Number of Referrals: Jumlah rekomendasi yang dibuat oleh pelanggan.

    • Tenure in Months: Total bulan pelanggan telah menggunakan layanan perusahaan.

    • Offer: Tawaran pemasaran terakhir yang diterima oleh pelanggan.

    • Phone Service: Apakah pelanggan memiliki layanan telepon rumah (Ya, Tidak).

    • … (Banyak atribut terkait layanan lainnya)

  5. Status:
    • CustomerID: Identifikasi unik pelanggan.

    • Quarter: Kuartal fiskal dari data yang diperoleh.

    • Satisfaction Score: Penilaian kepuasan pelanggan dari 1 (Sangat Tidak Puas) hingga 5 (Sangat Puas).

    • Satisfaction Score Label: Representasi teks dari skor kepuasan.

    • Customer Status: Status pelanggan pada akhir kuartal (Churned, Stayed, Joined).

    • Churn Label: Apakah pelanggan keluar dari perusahaan pada kuartal tersebut (Ya, Tidak).

    • Churn Value: Representasi biner dari label perpindahan (1 = keluar, 0 = tetap).

    • Churn Score: Skor perpindahan berdasarkan berbagai faktor.

Dataset komprehensif ini memberikan wawasan beragam mengenai perilaku pelanggan, demografi, penggunaan layanan, dan kecenderungan churn. Dataset menjadi sumber daya berharga untuk membangun model prediktif yang bertujuan meningkatkan strategi retensi pelanggan.

6 Output

Hasil utama dari proyek ini akan berupa model logistic regression, decission tree, dan random forest yang telah dilatih dan dilihat mana yang memiliki performa terbaik, yang mampu memprediksi apakah seorang pelanggan cenderung melakukan churn. Selain itu, proyek ini akan memberikan insigth mengenai faktor-faktor signifikan yang memengaruhi keputusan churn berdasarkan fitur-fitur yang diambil dari model.

7 Bussines Impact

Implementasi model prediksi churn dapat memiliki dampak bisnis yang signifikan. Dengan mengidentifikasi potensi pelanggan yang akan berpindah (churn) secara akurat, perusahaan dapat secara proaktif mengambil langkah-langkah retensi, seperti menawarkan insentif yang disesuaikan, komunikasi personalisasi, atau peningkatan layanan, atau strategi lainnya guna untuk mempertahankan pelanggan. Pendekatan prediktif ini dapat mengakibatkan penurunan tingkat churn pelanggan, dengan demikian meningkatkan retensi pelanggan, pendapatan, dan profitabilitas bisnis. Selain itu, insight yang diperoleh dari analisis pentingnya fitur-fitur model dapat membimbing pengambilan keputusan strategis yang bertujuan untuk meningkatkan kepuasan dan loyalitas pelanggan.

8 Data Preparation

8.1 Melakukan input data

churn <- read.csv("churn/WA_Fn-UseC_-Telco-Customer-Churn.csv")
churn

Dataset ini mencakup berbagai kategori informasi terkait pelanggan perusahaan telekomunikasi, perilaku mereka, dan penggunaan layanan. Kategori-kategori ini meliputi:

  1. Demografi:
    • CustomerID: Identifikasi unik pelanggan.

    • Gender: Jenis kelamin pelanggan (Pria, Wanita).

    • Age: Usia pelanggan saat akhir kuartal fiskal.

    • Senior Citizen: Apakah pelanggan berusia 65 tahun atau lebih (Ya, Tidak).

    • Married: Apakah pelanggan menikah (Ya, Tidak).

    • Dependents: Apakah pelanggan memiliki tanggungan (Ya, Tidak).

    • Number of Dependents: Jumlah tanggungan yang tinggal bersama pelanggan.

  2. Lokasi:
    • CustomerID: Identifikasi unik pelanggan.

    • Country, State, City: Detail lokasi tempat tinggal utama pelanggan.

    • Zip Code: Kode pos tempat tinggal utama pelanggan.

    • Lat Long, Latitude, Longitude: Koordinat geografis tempat tinggal utama pelanggan.

  3. Populasi:
    • ID: Identifikasi unik untuk setiap baris.

    • Zip Code: Kode pos tempat tinggal utama pelanggan.

    • Population: Estimasi populasi untuk area kode pos yang sesuai.

  4. Layanan:
    • CustomerID: Identifikasi unik pelanggan.

    • Quarter: Kuartal fiskal dari data yang diperoleh.

    • Referred a Friend: Apakah pelanggan merekomendasikan seseorang (Ya, Tidak).

    • Number of Referrals: Jumlah rekomendasi yang dibuat oleh pelanggan.

    • Tenure in Months: Total bulan pelanggan telah menggunakan layanan perusahaan.

    • Offer: Tawaran pemasaran terakhir yang diterima oleh pelanggan.

    • Phone Service: Apakah pelanggan memiliki layanan telepon rumah (Ya, Tidak).

    • … (Banyak atribut terkait layanan lainnya)

  5. Status:
    • CustomerID: Identifikasi unik pelanggan.

    • Quarter: Kuartal fiskal dari data yang diperoleh.

    • Satisfaction Score: Penilaian kepuasan pelanggan dari 1 (Sangat Tidak Puas) hingga 5 (Sangat Puas).

    • Satisfaction Score Label: Representasi teks dari skor kepuasan.

    • Customer Status: Status pelanggan pada akhir kuartal (Churned, Stayed, Joined).

    • Churn Label: Apakah pelanggan keluar dari perusahaan pada kuartal tersebut (Ya, Tidak).

    • Churn Value: Representasi biner dari label perpindahan (1 = keluar, 0 = tetap).

    • Churn Score: Skor perpindahan berdasarkan berbagai faktor.

8.2 Data Structure

library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
glimpse(churn)
## Rows: 7,043
## Columns: 21
## $ customerID       <chr> "7590-VHVEG", "5575-GNVDE", "3668-QPYBK", "7795-CFOCW…
## $ gender           <chr> "Female", "Male", "Male", "Male", "Female", "Female",…
## $ SeniorCitizen    <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ Partner          <chr> "Yes", "No", "No", "No", "No", "No", "No", "No", "Yes…
## $ Dependents       <chr> "No", "No", "No", "No", "No", "No", "Yes", "No", "No"…
## $ tenure           <int> 1, 34, 2, 45, 2, 8, 22, 10, 28, 62, 13, 16, 58, 49, 2…
## $ PhoneService     <chr> "No", "Yes", "Yes", "No", "Yes", "Yes", "Yes", "No", …
## $ MultipleLines    <chr> "No phone service", "No", "No", "No phone service", "…
## $ InternetService  <chr> "DSL", "DSL", "DSL", "DSL", "Fiber optic", "Fiber opt…
## $ OnlineSecurity   <chr> "No", "Yes", "Yes", "Yes", "No", "No", "No", "Yes", "…
## $ OnlineBackup     <chr> "Yes", "No", "Yes", "No", "No", "No", "Yes", "No", "N…
## $ DeviceProtection <chr> "No", "Yes", "No", "Yes", "No", "Yes", "No", "No", "Y…
## $ TechSupport      <chr> "No", "No", "No", "Yes", "No", "No", "No", "No", "Yes…
## $ StreamingTV      <chr> "No", "No", "No", "No", "No", "Yes", "Yes", "No", "Ye…
## $ StreamingMovies  <chr> "No", "No", "No", "No", "No", "Yes", "No", "No", "Yes…
## $ Contract         <chr> "Month-to-month", "One year", "Month-to-month", "One …
## $ PaperlessBilling <chr> "Yes", "No", "Yes", "No", "Yes", "Yes", "Yes", "No", …
## $ PaymentMethod    <chr> "Electronic check", "Mailed check", "Mailed check", "…
## $ 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            <chr> "No", "No", "Yes", "No", "Yes", "Yes", "No", "No", "Y…

Dataset memiliki 7,043 baris dan 21 kolom. Kolom Churn dalam dataset menunjukkan status pelanggan yang telah melakukan churn (yes) atau tidak (no)

Selanjutnya, kita perlu mengkonversi semua variabel ke tipe data yang diinginkan dalam data latih dan menghapus variabel yang tidak relevan :

churn_clean <- churn %>%
  mutate(gender = as.factor(gender),
         SeniorCitizen = as.factor(SeniorCitizen),
         Partner = as.factor(Partner),
         Dependents = as.factor(Dependents),
          PhoneService = as.factor(PhoneService),
         MultipleLines = as.factor(MultipleLines),
         InternetService = as.factor(InternetService),
         OnlineSecurity = as.factor(OnlineSecurity),
         OnlineBackup = as.factor(OnlineBackup),
         DeviceProtection = as.factor(DeviceProtection),
         TechSupport = as.factor(TechSupport),
         StreamingTV = as.factor(StreamingTV),
         StreamingMovies = as.factor(StreamingMovies),
         Contract = as.factor(Contract),
         PaperlessBilling = as.factor(PaperlessBilling),
         PaymentMethod = as.factor(PaymentMethod),
         Churn = as.factor(Churn)
         ) %>%
  select(-customerID)
glimpse(churn_clean)
## Rows: 7,043
## Columns: 20
## $ gender           <fct> Female, Male, Male, Male, Female, Female, Male, Femal…
## $ SeniorCitizen    <fct> 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 phone service, No, No, No phone service, No, Yes, …
## $ 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 in…
## $ DeviceProtection <fct> No, Yes, No, Yes, No, Yes, No, No, Yes, No, No, No in…
## $ TechSupport      <fct> No, No, No, Yes, No, No, No, No, Yes, No, No, No inte…
## $ StreamingTV      <fct> No, No, No, No, No, Yes, Yes, No, Yes, No, No, No int…
## $ StreamingMovies  <fct> No, No, No, No, No, Yes, No, No, Yes, No, No, No inte…
## $ 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…

8.3 Missing Value

Selanjutnya melakukan cek apakah pada data terdapat missing value atau tidak :

colSums(is.na(churn_clean))
##           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

Terdapat sedikit missing value pada variable TotalCharges, selanjutnya baris yang terdapat missing value akan dihilangkan :

churn_clean <- na.omit(churn_clean)
glimpse(churn_clean)
## Rows: 7,032
## Columns: 20
## $ gender           <fct> Female, Male, Male, Male, Female, Female, Male, Femal…
## $ SeniorCitizen    <fct> 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 phone service, No, No, No phone service, No, Yes, …
## $ 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 in…
## $ DeviceProtection <fct> No, Yes, No, Yes, No, Yes, No, No, Yes, No, No, No in…
## $ TechSupport      <fct> No, No, No, Yes, No, No, No, No, Yes, No, No, No inte…
## $ StreamingTV      <fct> No, No, No, No, No, Yes, Yes, No, Yes, No, No, No int…
## $ StreamingMovies  <fct> No, No, No, No, No, Yes, No, No, Yes, No, No, No inte…
## $ 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…
colSums(is.na(churn_clean))
##           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

8.4 Data Splitting

Pada bagian ini, akan membagi kumpulan data menjadi data train dan data test. Data latih akan digunakan untuk melatih model, sedangkan data test akan digunakan untuk mengevaluasi kinerja model yang telah dilatih. Sebanyak 80% dari kumpulan data akan digunakan untuk data latih, dan sisanya adalah data test.

RNGkind(sample.kind = "Rounding")
## Warning in RNGkind(sample.kind = "Rounding"): non-uniform 'Rounding' sampler
## used
set.seed(123)

samplesize <- round(0.8 * nrow(churn_clean), 0)
index <- sample(seq_len(nrow(churn_clean)), size = samplesize)

data_train <- churn_clean[index, ]
data_test <- churn_clean[-index, ]

8.5 Data Pre-processing

Melihat proporsi variable target

prop.table(table(data_train$Churn))
## 
##        No       Yes 
## 0.7381799 0.2618201

Terlihat bahwa terdapat kondisi imbalance pada variable target, dimana proporsi label “no” lebih besar dari label “yes”, sehingga akan dilakukan downsampling untuk membuat kedua label memiliki proporsi yang seimbang :

library(caret)
## Loading required package: ggplot2
## Loading required package: lattice
RNGkind(sample.kind = "Rounding")
## Warning in RNGkind(sample.kind = "Rounding"): non-uniform 'Rounding' sampler
## used
set.seed(123)
train_down <- downSample(
  x = data_train %>% select(-Churn),
  y = data_train$Churn,
  yname = "Churn"
)
prop.table(table(train_down$Churn))
## 
##  No Yes 
## 0.5 0.5