/churn-analysis
▾churn-analysis
exploration.ipynb
model_training.ipynb
▾data
customers.csv
features.csv
utils.py
requirements.txt
exploration.ipynb×
model_training.ipynb×
Churn Analysis (Python 3.11 · scikit-learn 1.4)|Idle
[1]:
1import pandas as pd
2import numpy as np
3from sklearn.model_selection import train_test_split
4from sklearn.ensemble import RandomForestClassifier
5from sklearn.metrics import accuracy_score, classification_report
[2]:
1df = pd.read_csv("data/customers.csv")
2print(f"Dataset shape: {df.shape}")
3df.head()
| customer_id | tenure | monthly_charges | total_charges | churn | |
|---|---|---|---|---|---|
| 0 | 7590-VHVEG | 1 | 29.85 | 29.85 | No |
| 1 | 5575-GNVDE | 34 | 56.95 | 1889.50 | No |
| 2 | 3668-QPYBK | 2 | 53.85 | 108.15 | Yes |
| 3 | 7795-CFOCW | 45 | 42.30 | 1840.75 | No |
| 4 | 9237-HQITU | 2 | 70.70 | 151.65 | Yes |
[3]:
1# Feature engineering
2df["churn_label"] = (df["churn"] == "Yes").astype(int)
3df["avg_monthly"] = df["total_charges"] / df["tenure"].clip(lower=1)
4df["high_value"] = (df["monthly_charges"] > 60).astype(int)
5
6features = ["tenure", "monthly_charges", "total_charges", "avg_monthly", "high_value"]
7X = df[features].fillna(0)
8y = df["churn_label"]
9
10X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
[4]:
1# Train Random Forest model
2model = RandomForestClassifier(n_estimators=100, max_depth=10, random_state=42)
3model.fit(X_train, y_train)
4
5y_pred = model.predict(X_test)
6accuracy = accuracy_score(y_test, y_pred)
7print(f"Model Accuracy: {accuracy:.4f}")
8print(classification_report(y_test, y_pred, target_names=["Retained", "Churned"]))
Model Accuracy: 0.8147
precision recall f1-score support
Retained 0.85 0.90 0.87 762
Churned 0.72 0.62 0.67 347
accuracy 0.81 1109
macro avg 0.78 0.76 0.77 1109
weighted avg 0.81 0.81 0.81 1109