import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import confusion_matrix, classification_report
import pickle
from pathlib import Path
DQLab Telco merupakan perusahaan Telco yang sudah mempunyai banyak cabang tersebar dimana-mana. Sejak berdiri pada tahun 2019, DQLab Telco konsisten untuk memperhatikan customer experience nya sehingga tidak akan di tinggalkan pelanggan.
Walaupun baru berumur 1 tahun lebih sedikit, DQLab Telco sudah mempunyai banyak pelanggan yang beralih langganan ke kompetitior. Pihak management ingin mengurangi jumlah pelanggan yang beralih (churn) dengan menggunakan machine learning.
Setelah kemarin kita mempersiapkan data sekaligus melakukan Cleansing, maka sekarang saatnya kita untuk membuat model yang tepat untuk memprediksi churn pelanggan.
Langkah yang akan dilakukan adalah,
Untuk Dataset yang digunakan sudah disediakan dalam format csv, silahkan baca melalui fungsi pandas di python df_load = pd.read_csv('https://storage.googleapis.com/dqlab-dataset/dqlab_telco_final.csv')
Untuk detil datanya adalah sebagai berikut:
UpdatedAt
Periode of Data takencustomerID
Customer IDgender
Whether the customer is a male or a female (Male, Female)SeniorCitizen
Whether the customer is a senior citizen or not (Yes, No)Partner
Whether the customer has a partner or not (Yes, No)tenure
Number of months the customer has stayed with the companyPhoneService
Whether the customer has a phone service or not (Yes, No)InternetService
Customer’s internet service provider (Yes, No)StreamingTV
Whether the customer has streaming TV or not (Yes, No)PaperlessBilling
Whether the customer has paperless billing or not (Yes, No)MonthlyCharges
The amount charged to the customer monthlyTotalCharges
The total amount charged to the customerChurn
Whether the customer churned or not (Yes, No)df_load = pd.read_csv("../Datasets/dqlab_telco_final.csv")
df_load.head()
UpdatedAt | customerID | gender | SeniorCitizen | Partner | tenure | PhoneService | StreamingTV | InternetService | PaperlessBilling | MonthlyCharges | TotalCharges | Churn | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 202006 | 45759018157 | Female | No | Yes | 1 | No | No | Yes | Yes | 29.85 | 29.85 | No |
1 | 202006 | 45315483266 | Male | No | Yes | 60 | Yes | No | No | Yes | 20.50 | 1198.80 | No |
2 | 202006 | 45236961615 | Male | No | No | 5 | Yes | Yes | Yes | No | 104.10 | 541.90 | Yes |
3 | 202006 | 45929827382 | Female | No | Yes | 72 | Yes | Yes | Yes | Yes | 115.50 | 8312.75 | No |
4 | 202006 | 45305082233 | Female | No | Yes | 56 | Yes | Yes | Yes | No | 81.25 | 4620.40 | No |
#Tampilkan bentuk dari dataset
df_load.shape
(6950, 13)
#Tampilkan jumlah ID yang unik
print(df_load.customerID.nunique())
6950
Exploratory Data Analysis memungkinkan analyst memahami isi data yang digunakan, mulai dari distribusi, frekuensi, korelasi dan lainnya. Pada umumnya EDA dilakukan dengan beberapa cara:
Kita ingin melihat visualisasi data secara univariat terkait prosentase data churn dari pelanggan.
fig = plt.figure(figsize=(3,3))
ax = fig.add_axes([0,0,1,1])
ax.axis('equal')
labels = ['Yes','No']
churn = df_load.Churn.value_counts()
ax.pie(churn, labels=labels, autopct='%.0f%%')
plt.show()
Hal yang akan kita lakukan selanjutnya adalah memilih variable predictor yang bersifat numerik dan membuat plot secara bivariat, kemudian menginterpretasikannya
#creating bin in chart
numerical_features = ['MonthlyCharges','TotalCharges','tenure']
fig, ax = plt.subplots(1, 3, figsize=(15, 4))
# Use the following code to plot two overlays of histogram per each numerical_features,
# use a color of blue and orange, respectively
df_load[df_load.Churn == 'No'][numerical_features].hist(bins=20, color='blue', alpha=0.5, ax=ax)
df_load[df_load.Churn == 'Yes'][numerical_features].hist(bins=20, color='orange', alpha=0.5, ax=ax)
plt.show()
Berdasarkan hasil di atas, dapat kita ketahui bahwa untuk MonthlyCharges
ada kecenderungan semakin kecil nilai biaya bulanan yang dikenakan, semakin kecil juga kecenderungan untuk melakukan Churn. Untuk TotalCharges
terlihat tidak ada kecenderungan apapun terhadap Churn customers. Untuk tenure
ada kecenderungan semakin lama berlangganan customer, semakin kecil kecenderungan untuk melakukan Churn.
Setelah itu, kita akan melakukan pemilihan variable predictor yang bersifat kategorik dan membuat plot secara bivariat, kemudian menginterpretasikannya
sns.set(style='darkgrid')
fig, ax = plt.subplots(3, 3, figsize=(14, 12))
sns.countplot(data=df_load, x='gender', hue='Churn', ax=ax[0][0])
sns.countplot(data=df_load, x='Partner', hue='Churn', ax=ax[0][1])
sns.countplot(data=df_load, x='SeniorCitizen', hue='Churn', ax=ax[0][2])
sns.countplot(data=df_load, x='PhoneService', hue='Churn', ax=ax[1][0])
sns.countplot(data=df_load, x='StreamingTV', hue='Churn', ax=ax[1][1])
sns.countplot(data=df_load, x='InternetService', hue='Churn', ax=ax[1][2])
sns.countplot(data=df_load, x='PaperlessBilling', hue='Churn', ax=ax[2][1])
plt.tight_layout()
plt.show()
Berdasarkan hasil di atas, dapat kita ketahui bahwa tidak ada perbedaan yang signifikan untuk orang melakukan churn
dilihat dari faktor jenis kelamin gender
dan layanan telfonnya PhoneService
. Akan tetapi ada kecenderungan bahwa orang yang melakukan churn
adalah orang-orang yang tidak memiliki partner partner: No
, orang-orang yang statusnya adalah senior citizen SeniorCitizen: Yes
, orang-orang yang mempunyai layanan streaming TV StreamingTV: Yes
, orang-orang yang mempunyai layanan Internet internetService: Yes
dan orang-orang yang tagihannya paperless PaperlessBilling: Yes
.
#Remove the unnecessary columns customerID & UpdatedAt
cleaned_df = df_load.drop(['customerID','UpdatedAt'], axis=1)
cleaned_df.head()
gender | SeniorCitizen | Partner | tenure | PhoneService | StreamingTV | InternetService | PaperlessBilling | MonthlyCharges | TotalCharges | Churn | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | Female | No | Yes | 1 | No | No | Yes | Yes | 29.85 | 29.85 | No |
1 | Male | No | Yes | 60 | Yes | No | No | Yes | 20.50 | 1198.80 | No |
2 | Male | No | No | 5 | Yes | Yes | Yes | No | 104.10 | 541.90 | Yes |
3 | Female | No | Yes | 72 | Yes | Yes | Yes | Yes | 115.50 | 8312.75 | No |
4 | Female | No | Yes | 56 | Yes | Yes | Yes | No | 81.25 | 4620.40 | No |
#Convert all the non-numeric columns to numerical data types
for column in cleaned_df.columns:
if cleaned_df[column].dtype == np.number: continue
# Perform encoding for each non-numeric column
cleaned_df[column] = LabelEncoder().fit_transform(cleaned_df[column])
C:\Users\iwanXone\AppData\Local\Temp\ipykernel_2060\2073380793.py:3: DeprecationWarning: Converting `np.inexact` or `np.floating` to a dtype is deprecated. The current result is `float64` which is not strictly correct. if cleaned_df[column].dtype == np.number: continue
cleaned_df.head()
gender | SeniorCitizen | Partner | tenure | PhoneService | StreamingTV | InternetService | PaperlessBilling | MonthlyCharges | TotalCharges | Churn | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 29.85 | 29.85 | 0 |
1 | 1 | 0 | 1 | 60 | 1 | 0 | 0 | 1 | 20.50 | 1198.80 | 0 |
2 | 1 | 0 | 0 | 5 | 1 | 1 | 1 | 0 | 104.10 | 541.90 | 1 |
3 | 0 | 0 | 1 | 72 | 1 | 1 | 1 | 1 | 115.50 | 8312.75 | 0 |
4 | 0 | 0 | 1 | 56 | 1 | 1 | 1 | 0 | 81.25 | 4620.40 | 0 |
cleaned_df.describe()
gender | SeniorCitizen | Partner | tenure | PhoneService | StreamingTV | InternetService | PaperlessBilling | MonthlyCharges | TotalCharges | Churn | |
---|---|---|---|---|---|---|---|---|---|---|---|
count | 6950.000000 | 6950.000000 | 6950.000000 | 6950.000000 | 6950.000000 | 6950.000000 | 6950.000000 | 6950.000000 | 6950.000000 | 6950.000000 | 6950.000000 |
mean | 0.504317 | 0.162302 | 0.483309 | 32.415827 | 0.903741 | 0.384317 | 0.783453 | 0.591942 | 64.992201 | 2286.058750 | 0.264173 |
std | 0.500017 | 0.368754 | 0.499757 | 24.561336 | 0.294967 | 0.486468 | 0.411921 | 0.491509 | 30.032040 | 2265.702553 | 0.440923 |
min | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 19.000000 | 0.000000 |
25% | 0.000000 | 0.000000 | 0.000000 | 9.000000 | 1.000000 | 0.000000 | 1.000000 | 0.000000 | 36.462500 | 406.975000 | 0.000000 |
50% | 1.000000 | 0.000000 | 0.000000 | 29.000000 | 1.000000 | 0.000000 | 1.000000 | 1.000000 | 70.450000 | 1400.850000 | 0.000000 |
75% | 1.000000 | 0.000000 | 1.000000 | 55.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 89.850000 | 3799.837500 | 1.000000 |
max | 1.000000 | 1.000000 | 1.000000 | 73.000000 | 1.000000 | 1.000000 | 1.000000 | 1.000000 | 169.931250 | 8889.131250 | 1.000000 |
# Predictor dan target
X = cleaned_df.drop('Churn', axis=1)
y = cleaned_df['Churn']
# Splitting train and test
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# Print according to the expected result
print(x_train.shape, x_test.shape)
# Prosentase Churn di data Training dan Testing
print(y_train.value_counts(normalize=True))
print(y_test.value_counts(normalize=True))
(4865, 10) (2085, 10) 0 0.734841 1 0.265159 Name: Churn, dtype: float64 0 0.738129 1 0.261871 Name: Churn, dtype: float64
Setelah kita analisis lebih lanjut, ternyata ada kolom yang tidak dibutuhkuan dalam model, yaitu Id Number pelanggannya (customerID) & periode pengambilan datanya (UpdatedAt), maka hal ini perlu dihapus. Kemudian kita lanjut mengubah value dari data yang masih berbentuk string menjadi numeric melalui encoding, setelah dilakukan terlihat di persebaran datanya khususnya kolom min dan max dari masing masing variable sudah berubah menjadi 0 & 1. Tahap terakhir adalah membagi data menjadi 2 bagian untuk keperluan modelling, setelah dilakukan terlihat dari jumlah baris dan kolom masing-masing data sudah sesuai & prosentase kolom churn juga sama dengan data di awal, hal ini mengindikasikan bahwasannya data terpisah dengan baik dan benar.
Selanjutnya kita akan membuat model dengan menggunakan Algoritma Logistic Regression.
Gunakan LogisticRegression() memanggil algoritma tersebut, fit ke data train dan simpan sebagai log_model
log_model = LogisticRegression(max_iter=1000)
log_model.fit(x_train, y_train)
LogisticRegression(max_iter=1000)In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
LogisticRegression(max_iter=1000)
Setelah kita membuat modelnya, maka lakukan perhitungan untuk memperoleh classification reportnya dan confusion matrixnya di data training seperti hasil di bawah ini. Gunakan classification_report() & confusion_matrix().
# Predict
y_train_pred = log_model.predict(x_train)
# Print classification report
print('Classification Report Training Model (Logistic Regression) :')
print(classification_report(y_train, y_train_pred))
Classification Report Training Model (Logistic Regression) : precision recall f1-score support 0 0.83 0.90 0.87 3575 1 0.65 0.50 0.56 1290 accuracy 0.80 4865 macro avg 0.74 0.70 0.72 4865 weighted avg 0.78 0.80 0.79 4865
Setelah mendapatkan hasil classification report pada tahap sebelumnya, sekarang kita akan melakukan visualisasi terhadap report tersebut.
# Form confusion matrix as a DataFrame
confusion_matrix_df = pd.DataFrame((confusion_matrix(y_train, y_train_pred)), ('No churn', 'Churn'), ('No churn', 'Churn'))
# Plot confusion matrix
plt.figure()
heatmap = sns.heatmap(confusion_matrix_df, annot=True, annot_kws={'size': 14}, fmt='d', cmap='YlGnBu')
heatmap.yaxis.set_ticklabels(heatmap.yaxis.get_ticklabels(), rotation=0, ha='right', fontsize=14)
heatmap.xaxis.set_ticklabels(heatmap.xaxis.get_ticklabels(), rotation=0, ha='right', fontsize=14)
plt.title('Confusion Matrix for Training Model\n(Logistic Regression)', fontsize=18, color='darkblue')
plt.ylabel('True label', fontsize=14)
plt.xlabel('Predicted label', fontsize=14)
plt.tight_layout()
plt.show()
Setelah kita membuat modelnya, maka lakukan perhitungan untuk memperoleh classification reportnya dan confusion matrixnya di data testing seperti hasil di bawah ini. Gunakan classification_report() & confusion_matrix().
# Predict
y_test_pred = log_model.predict(x_test)
# Print classification report
print('Classification Report Testing Model (Logistic Regression):')
print(classification_report(y_test, y_test_pred))
Classification Report Testing Model (Logistic Regression): precision recall f1-score support 0 0.83 0.90 0.87 1539 1 0.64 0.48 0.55 546 accuracy 0.79 2085 macro avg 0.73 0.69 0.71 2085 weighted avg 0.78 0.79 0.78 2085
Setelah menampilkan metrics pada tahap sebelumnya, sekarang kita akan melakukan visualisasi dari metrics yang sudah dihasilkan sebelumnya.
# Form confusion matrix as a DataFrame
confusion_matrix_df = pd.DataFrame((confusion_matrix(y_test, y_test_pred)),('No churn','Churn'),('No churn','Churn'))
# Plot confusion matrix
plt.figure()
heatmap = sns.heatmap(confusion_matrix_df, annot=True, annot_kws={'size': 14}, fmt='d', cmap='YlGnBu')
heatmap.yaxis.set_ticklabels(heatmap.yaxis.get_ticklabels(), rotation=0, ha='right', fontsize=14)
heatmap.xaxis.set_ticklabels(heatmap.xaxis.get_ticklabels(), rotation=0, ha='right', fontsize=14)
plt.title('Confusion Matrix for Testing Model\n(Logistic Regression)\n', fontsize=18, color='darkblue')
plt.ylabel('True label', fontsize=14)
plt.xlabel('Predicted label', fontsize=14)
plt.tight_layout()
plt.show()
Dari hasil dan analisa di atas, maka:
LogisticRegression()
dari sklearn tanpa menambahi parameter apapun, maka yang dihasilkan adalah model dengan seting default dari sklearn, untuk detilnya bisa dilihat di dokumentasinya.churn
yang sebenernya benar churn
adalah 262, tebakan tidak churn
yang sebenernya tidak churn
adalah 1390, tebakan tidak churn
yang sebenernya benar churn
adalah 284 dan tebakan churn
yang sebenernya tidak churn
adalah 149.Selanjutnya kita akan membuat model dengan menggunakan Algoritma Random Forest Classifier.
Gunakan RandomForestClassifier() memanggil algoritma tersebut, fit ke data train dan simpan sebagai rdf_model
#Train the model
rdf_model = RandomForestClassifier()
rdf_model.fit(x_train, y_train)
RandomForestClassifier()In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
RandomForestClassifier()
Setelah kita membuat modelnya, maka lakukan perhitungan untuk memperoleh classification reportnya dan confusion matrixnya di data training seperti hasil di bawah ini. Gunakan classification_report() & confusion_matrix().
y_train_pred = rdf_model.predict(x_train)
print('Classification Report Training Model (Random Forest) :')
print(classification_report(y_train, y_train_pred))
Classification Report Training Model (Random Forest) : precision recall f1-score support 0 1.00 1.00 1.00 3575 1 1.00 0.99 0.99 1290 accuracy 1.00 4865 macro avg 1.00 0.99 0.99 4865 weighted avg 1.00 1.00 1.00 4865
Setelah menampilkan metrics pada tahap sebelumnya, selanjutnya kita akan melakukan visualisasi terhadap metrics tersebut
# Form confusion matrix as a DataFrame
confusion_matrix_df = pd.DataFrame((confusion_matrix(y_train, y_train_pred)), ('No churn', 'Churn'), ('No churn', 'Churn'))
# Plot confusion matrix
plt.figure()
heatmap = sns.heatmap(confusion_matrix_df, annot=True, annot_kws={'size': 14}, fmt='d', cmap='YlGnBu')
heatmap.yaxis.set_ticklabels(heatmap.yaxis.get_ticklabels(), rotation=0, ha='right', fontsize=14)
heatmap.xaxis.set_ticklabels(heatmap.xaxis.get_ticklabels(), rotation=0, ha='right', fontsize=14)
plt.title('Confusion Matrix for Training Model\n(Random Forest)', fontsize=18, color='darkblue')
plt.ylabel('True label', fontsize=14)
plt.xlabel('Predicted label', fontsize=14)
plt.tight_layout()
plt.show()
Setelah kita membuat modelnya, maka lakukan perhitungan untuk memperoleh classification reportnya dan confusion matrixnya di data testing seperti hasil di bawah ini. Gunakan classification_report() & confusion_matrix().
# Predict
y_test_pred = rdf_model.predict(x_test)
# Print classification report
print('Classification Report Testing Model (Random Forest Classifier):')
print(classification_report(y_test, y_test_pred))
Classification Report Testing Model (Random Forest Classifier): precision recall f1-score support 0 0.82 0.89 0.85 1539 1 0.59 0.47 0.52 546 accuracy 0.78 2085 macro avg 0.71 0.68 0.69 2085 weighted avg 0.76 0.78 0.77 2085
Tampilkan visualisasi dari hasil metrics yang sudah diperoleh pada tahap sebelumnya
# Form confusion matrix as a DataFrame
confusion_matrix_df = pd.DataFrame((confusion_matrix(y_test, y_test_pred)), ('No churn', 'Churn'), ('No churn', 'Churn'))
# Plot confusion matrix
plt.figure()
heatmap = sns.heatmap(confusion_matrix_df, annot=True, annot_kws={'size': 14}, fmt='d', cmap='YlGnBu')
heatmap.yaxis.set_ticklabels(heatmap.yaxis.get_ticklabels(), rotation=0, ha='right', fontsize = 14)
heatmap.xaxis.set_ticklabels(heatmap.xaxis.get_ticklabels(), rotation=0, ha='right', fontsize = 14)
plt.title('Confusion Matrix for Testing Model\n(Random Forest)\n', fontsize = 18, color = 'darkblue')
plt.ylabel('True label', fontsize = 14)
plt.xlabel('Predicted label', fontsize = 14)
plt.show()
Dari hasil dan analisa di atas, maka:
RandomForestClassifier()
dari sklearn tanpa menambahi parameter apapun, maka yang dihasilkan adalah model dengan seting default dari sklearn, untuk detilnya bisa dilihat di dokumentasinya.churn
yang sebenernya benar churn
adalah 1278, tebakan tidak churn
yang sebenernya tidak churn
adalah 3566, tebakan tidak churn
yang sebenernya benar churn
adalah 12 dan tebakan churn
yang sebenernya tidak churn
adalah 9.churn
yang sebenernya benar churn
adalah 262, tebakan tidak churn
yang sebenernya tidak churn
adalah 1360, tebakan tidak churn
yang sebenernya benar churn
adalah 284 dan tebakan churn yang sebenernya tidak churn
adalah 179.Selanjutnya kita akan membuat model dengan menggunakan Algoritma Gradient Boosting Classifier.
Gunakan GradientBoostingClassifier() memanggil algoritma tersebut, fit ke data train dan simpan sebagai gbt_model
#Train the model
gbt_model = GradientBoostingClassifier()
gbt_model.fit(x_train, y_train)
GradientBoostingClassifier()In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
GradientBoostingClassifier()
Setelah kita membuat modelnya, maka lakukan perhitungan untuk memperoleh classification reportnya dan confusion matrixnya di data training seperti hasil di bawah ini. Gunakan classification_report() & confusion_matrix().
from sklearn.metrics import classification_report
# Predict
y_train_pred = gbt_model.predict(x_train)
# Print classification report
print('Classification Report Training Model (Gradient Boosting):')
print(classification_report(y_train, y_train_pred))
Classification Report Training Model (Gradient Boosting): precision recall f1-score support 0 0.84 0.92 0.88 3575 1 0.70 0.53 0.60 1290 accuracy 0.82 4865 macro avg 0.77 0.72 0.74 4865 weighted avg 0.81 0.82 0.81 4865
Tampilkan visualisasi dari metrics yang sudah dihasilkan sebelumnya
# Form confusion matrix as a DataFrame
confusion_matrix_df = pd.DataFrame((confusion_matrix(y_train, y_train_pred)), ('No churn', 'Churn'), ('No churn', 'Churn'))
# Plot confusion matrix
plt.figure()
heatmap = sns.heatmap(confusion_matrix_df, annot=True, annot_kws={'size': 14}, fmt='d', cmap='YlGnBu')
heatmap.yaxis.set_ticklabels(heatmap.yaxis.get_ticklabels(), rotation=0, ha='right', fontsize = 14)
heatmap.xaxis.set_ticklabels(heatmap.xaxis.get_ticklabels(), rotation=0, ha='right', fontsize = 14)
plt.title('Confusion Matrix for Training Model\n(Gradient Boosting)', fontsize = 18, color = 'darkblue')
plt.ylabel('True label', fontsize = 14)
plt.xlabel('Predicted label', fontsize = 14)
plt.tight_layout()
plt.show()
Setelah kita membuat modelnya, maka lakukan perhitungan untuk memperoleh classification reportnya dan confusion matrixnya di data testing seperti hasil di bawah ini. Gunakan classification_report() & confusion_matrix().
# Predict
y_test_pred = gbt_model.predict(x_test)
# Print classification report
print('Classification Report Testing Model (Gradient Boosting):')
print(classification_report(y_test, y_test_pred))
Classification Report Testing Model (Gradient Boosting): precision recall f1-score support 0 0.83 0.91 0.87 1539 1 0.64 0.48 0.55 546 accuracy 0.79 2085 macro avg 0.74 0.69 0.71 2085 weighted avg 0.78 0.79 0.78 2085
Buatlah visualisasi dari metrics yang sudah dihasilkan sebelumnya
# Form confusion matrix as a DataFrame
confusion_matrix_df = pd.DataFrame((confusion_matrix(y_test, y_test_pred)), ('No churn', 'Churn'), ('No churn', 'Churn'))
# Plot confusion matrix
plt.figure()
heatmap = sns.heatmap(confusion_matrix_df, annot=True, annot_kws={'size': 14}, fmt='d', cmap='YlGnBu')
heatmap.yaxis.set_ticklabels(heatmap.yaxis.get_ticklabels(), rotation=0, ha='right', fontsize=14)
heatmap.xaxis.set_ticklabels(heatmap.xaxis.get_ticklabels(), rotation=0, ha='right', fontsize=14)
plt.title('Confusion Matrix for Testing Model\n(Gradient Boosting)', fontsize=18, color='darkblue')
plt.ylabel('True label', fontsize=14)
plt.xlabel('Predicted label', fontsize=14)
plt.tight_layout()
plt.show()
Dari hasil dan analisa di atas, maka:
Jika kita menggunakan menggunakan algoritma Gradient Boosting dengan memanggil GradientBoostingClassifier()
dari package sklearn tanpa menambahi parameter apapun, maka yang dihasilkan adalah model dengan seting default dari sklearn, untuk detilnya bisa dilihat di dokumentasinya.
Dari data training terlihat bahwasannya model mampu memprediksi data dengan menghasilkan akurasi sebesar 82%, dengan detil tebakan churn
yang sebenernya benar churn
adalah 684, tebakan tidak churn
yang sebenernya tidak churn
adalah 3286, tebakan tidak churn
yang sebenernya benar churn
adalah 606 dan tebakan churn
yang sebenernya tidak churn
adalah 289.
Dari data testing terlihat bahwasannya model mampu memprediksi data dengan menghasilkan akurasi sebesar 79%, dengan detil tebakan churn
yang sebenernya benar churn
adalah 261, tebakan tidak churn
yang sebenernya tidak churn
adalah 1394, tebakan tidak churn
yang sebenernya benar churn
adalah 285 dan tebakan churn
yang sebenernya tidak churn
adalah 145.
Model yang baik adalah model yang mampu memberikan performa bagus di fase training dan testing model.
print(log_model)
LogisticRegression(max_iter=1000)
#Save Model
pickle.dump(log_model, open('best_model_churn.pkl', 'wb'))
Berdasarkan pemodelan yang telah dilakukan dengan menggunakan Logistic Regression
, Random Forest
dan Extreme Gradiant Boost
, maka dapat disimpulkan untuk memprediksi churn dari pelanggan telco dengan menggunakan dataset ini model terbaiknya adalah menggunakan algortima Logistic Regression
. Hal ini dikarenakan performa dari model Logistic Regression
cenderung mampu memprediksi sama baiknya di fase training maupun testing (akurasi training 80%, akurasi testing 79%), dilain sisi algoritma lainnya cenderung Over-Fitting performanya. Akan tetapi hal ini tidak menjadikan kita untuk menarik kesimpulan bahwsannya jika untuk melakukan pemodelan apapun maka digunakan Logistic Regression
, kita tetap harus melakukan banyak percobaan model untuk menentukan mana yang terbaik.