Customer Churn Prediction (Part-1)
In this machine learning project, my primary goal was to identify customers who are likely to discontinue service using a telecommunication dataset. As we know, customer churning is one of the biggest challenges for various industries, including telecommunications and entertainment. Hence, I found this topic interesting and decided to learn more about it by working on a dataset.
About the data:
I obtained the dataset from Kaggle:
- There were 7043 rows and 21 columns, with each column and data type given below
2. The range and mean of numerical columns:
Tenure: 0 – 72 months, 32.37
Monthly Charges: 18.25 — 118.75, 64.76
Total Charges: 18.8 — 8684.8, 2283.30
Data cleaning and preprocessing:
As the majority of the data was already clean, therefore, only a few steps had to be performed
1. Out of all columns, there were 11 null values found in total charges, which I replaced with their mean value.
2. There were no duplicate values found in any column.
Get syssoni’s stories in your inbox
Join Medium for free to get updates from this writer.
3. The senior citizen column was converted to an object, while the total charges column was changed to a float for further analysis.
Exploratory Data Analysis:
In order to determine the relationships between churn rate and various columns, I created a few graphs using the matplotlib and scikit-learn libraries. It also helped me to find out insights about the data, which are written below
- Out of 7043 people, the majority of people left the service, as the number of people who churned was 5174, and the number of people who didn’t was 1869.
- The percentage of people who churned by contract type (month-to-month, one-year, or two-year) was the highest in month-to-month (42.71%) and was the lowest in two-year (2.83%). Therefore, it tells us that the people having a two-year contract are least likely to churn, followed by one year, and lastly, month to month.
- Out of males and females, the number of people churning is almost the same, that is, 26.92 % in females and 26.16 % in males. Therefore, there is no such significant difference.
- We can observe that a greater number of senior citizens (41.68%) are churning as compared to non-senior citizens (23.61%).
- Out of 3 types of internet services, i.e., DSL, fiber optics, and none, most people are churning from fiber optics (41.89%) and least in no internet service (7.4%).
- In payment methods, the highest number of people are churning in electronic check (45.29%), and the lowest in credit card (15.24%).
- The people who opted for paperless billing were more likely to churn, with the percentage being 33.57%.
- For finding the number of people churning in different columns like tenure, monthly charges, and total charges, I divided them into groups having equal bin size and stored the groups as a dataframe (tenure group, monthly group, and total group).
- For the tenure group, I chose a bin size of 12. The largest number of people churned between 0 and 12 months, which is 47.7%, and the least number of people churned between 61 and 72 months. Hence, newer users were more likely to leave as compared to older ones, as the trend found among different bins showed the drop percentages decreasing as the tenure increased.
- For monthly charges, I chose bin size = 35. The number of people in the category of 71–100 were most likely to churn, amounting to 37.8%, and the least likely were in the category < 35 (only 10.9%).
- For total charges, the bin size was 2k. Most number of people churned in 0k-1k, while the least did in 6k-9k.
- There was a high correlation between total charges and tenure found using a heatmap.
Machine Learning Model
Before applying any machine learning algorithm, I created a new data frame in which I applied one-hot encoding on columns like gender, partner, dependents, and label encoding on churn.
from sklearn.preprocessing import OneHotEncoder
categorical_col = ['gender','Partner', 'Dependents', 'PhoneService', 'MultipleLines', 'InternetService', 'OnlineSecurity', 'OnlineBackup', 'DeviceProtection', 'TechSupport', 'StreamingTV', 'StreamingMovies','Contract', 'PaperlessBilling', 'PaymentMethod', 'SeniorCitizen']
encoder = OneHotEncoder(sparse_output=False)
one_hot_encoded = encoder.fit_transform(df[categorical_col])
one_hot_df = pd.DataFrame(one_hot_encoded, columns=encoder.get_feature_names_out(categorical_col))
df_encoded = pd.concat([df, one_hot_df], axis=1)
df_encoded = df_encoded.drop(categorical_col, axis=1)
df_encoded[0:5]from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
df_encoded['Churn'] = le.fit_transform(df_encoded['Churn'])- Logistic Regression
It is a supervised machine learning algorithm that helps in predicting binary outcomes; therefore, I used this to predict customer churning rate, where the target/dependent variable was the “Churn” column, while the rest (excluding customerid, tenure group, monthly group, and total_group) were independent variables.
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
X = df_encoded.drop(['Churn'], axis=1)
y = df_encoded['Churn']
X_train, X_test, y_train, y_test = train_test_split(X,y, test_size=0.5)
lr = LogisticRegression(solver='lbfgs', penalty='l2' ,max_iter=1000)
lr.fit(X_train, y_train)
y_pred = lr.predict(X_test)
print(y_pred[15:20])lbfgs is an algorithm used for optimization(solver)
I used L2 regularisation (penalty)
I used 1000 as the maximum no of iterations for the solver to converge(max_iter)
And the results:
80 % of people were correctly predicted out of all churned and not churned
65 % of customers predicted as “will churn” actually churned.
The model correctly identified 54% of all customers who actually churned
The confusion matrix:
These results indicate that the model effectively distinguishes loyal customers but struggles to capture all churners — a common challenge in imbalanced classification problems.
Feel free to check out the code at Kaggle:
https://www.kaggle.com/code/syssoni/customer-churn-prediction
Furthermore, I will write part 2 for other algorithms applied to this dataset
Thanks a lot for reading :)






