Classification Modeling
Overview
Classification modeling predicts categorical target values, assigning observations to discrete classes or categories based on input features.
When to Use
- Predicting binary outcomes like customer churn, loan default, or email spam
- Classifying items into multiple categories such as product types or sentiment
- Building credit scoring models or risk assessment systems
- Identifying disease diagnosis or medical condition from patient data
- Predicting customer purchase likelihood or response to marketing
- Detecting fraud, anomalies, or quality defects in production systems
Classification Types
- Binary Classification: Two classes (yes/no, success/failure)
- Multiclass: More than two classes
- Multi-label: Multiple classes per observation
Common Algorithms
- Logistic Regression: Linear classification
- Decision Trees: Rule-based non-linear
- Random Forest: Ensemble of decision trees
- Gradient Boosting: Sequential tree building
- SVM: Support Vector Machines
- Naive Bayes: Probabilistic classifier
Key Metrics
- Accuracy: Overall correct predictions
- Precision: True positives / (true + false positives)
- Recall: True positives / (true + false negatives)
- F1-Score: Harmonic mean of precision/recall
- AUC-ROC: Area under receiver operating characteristic curve
Implementation with Python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.metrics import (
confusion_matrix, classification_report, roc_auc_score, roc_curve,
precision_recall_curve, f1_score, accuracy_score
)
import seaborn as sns
# Generate sample binary classification data
np.random.seed(42)
from sklearn.datasets import make_classification
X, y = make_classification(
n_samples=1000, n_features=20, n_informative=10,
n_redundant=5, random_state=42
)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# Standardize features
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# Logistic Regression
lr_model = LogisticRegression(max_iter=1000)
lr_model.fit(X_train_scaled, y_train)
y_pred_lr = lr_model.predict(X_test_scaled)
y_proba_lr = lr_model.predict_proba(X_test_scaled)[:, 1]
print("Logistic Regression:")
print(classification_report(y_test, y_pred_lr))
print(f"AUC-ROC: {roc_auc_score(y_test, y_proba_lr):.4f}\n")
# Decision Tree
dt_model = DecisionTreeClassifier(max_depth=10, random_state=42)
dt_model.fit(X_train, y_train)
y_pred_dt = dt_model.predict(X_test)
y_proba_dt = dt_model.predict_proba(X_test)[:, 1]
print("Decision Tree:")
print(classification_report(y_test, y_pred_dt))
print(f"AUC-ROC: {roc_auc_score(y_test, y_proba_dt):.4f}\n")
# Random Forest
rf_model = RandomForestClassifier(n_estimators=100, max_depth=10, random_state=42)
rf_model.fit(X_train, y_train)
y_pred_rf = rf_model.predict(X_test)
y_proba_rf = rf_model.predict_proba(X_test)[:, 1]
print("Random Forest:")
print(classification_report(y_test, y_pred_rf))
print(f"AUC-ROC: {roc_auc_score(y_test, y_proba_rf):.4f}\n")
# Gradient Boosting
gb_model = GradientBoostingClassifier(n_estimators=100, max_depth=5, random_state=42)
gb_model.fit(X_train, y_train)
y_pred_gb = gb_model.predict(X_test)
y_proba_gb = gb_model.predict_proba(X_test)[:, 1]
print("Gradient Boosting:")
print(classification_report(y_test, y_pred_gb))
print(f"AUC-ROC: {roc_auc_score(y_test, y_proba_gb):.4f}\n")
# Confusion matrices
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
models = [
(y_pred_lr, 'Logistic Regression'),
(y_pred_dt, 'Decision Tree'),
(y_pred_rf, 'Random Forest'),
(y_pred_gb, 'Gradient Boosting'),
]
for idx, (y_pred, title) in enumerate(models):
cm = confusion_matrix(y_test, y_pred)
ax = axes[idx // 2, idx % 2]
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', ax=ax)
ax.set_title(title)
ax.set_ylabel('True Label')
ax.set_xlabel('Predicted Label')
plt.tight_layout()
plt.show()
# ROC Curves
plt.figure(figsize=(10, 8))
probas = [
(y_proba_lr, 'Logistic Regression'),
(y_proba_dt, 'Decision Tree'),
(y_proba_rf, 'Random Forest'),
(y_proba_gb, 'Gradient Boosting'),
]
for y_proba, label in probas:
fpr, tpr, _ = roc_curve(y_test, y_proba)
auc = roc_auc_score(y_test, y_proba)
plt.plot(fpr, tpr, label=f'{label} (AUC={auc:.4f})')
plt.plot([0, 1], [0, 1], 'k--', label='Random Classifier')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC Curves Comparison')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
# Precision-Recall Curves
plt.figure(figsize=(10, 8))
for y_proba, label in probas:
precision, recall, _ = precision_recall_curve(y_test, y_proba)
f1 = f1_score(y_test, (y_proba > 0.5).astype(int))
plt.plot(recall, precision, label=f'{label} (F1={f1:.4f})')
plt.xlabel('Recall')
plt.ylabel('Precision')
plt.title('Precision-Recall Curves')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
# Feature importance
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# Tree-based feature importance
feature_importance_rf = pd.Series(
rf_model.feature_importances_, index=range(X.shape[1])
).sort_values(ascending=False)
axes[0].barh(range(10), feature_importance_rf.values[:10])
axes[0].set_yticks(range(10))
axes[0].set_yticklabels([f'Feature {i}' for i in feature_importance_rf.index[:10]])
axes[0].set_title('Random Forest - Top 10 Features')
axes[0].set_xlabel('Importance')
# Logistic regression coefficients
lr_coef = pd.Series(lr_model.coef_[0], index=range(X.shape[1])).abs().sort_values(ascending=False)
axes[1].barh(range(10), lr_coef.values[:10])
axes[1].set_yticks(range(10))
axes[1].set_yticklabels([f'Feature {i}' for i in lr_coef.index[:10]])
axes[1].set_title('Logistic Regression - Top 10 Features (abs coef)')
axes[1].set_xlabel('Absolute Coefficient')
plt.tight_layout()
plt.show()
# Model comparison
results = pd.DataFrame({
'Model': ['Logistic Regression', 'Decision Tree', 'Random Forest', 'Gradient Boosting'],
'Accuracy': [
accuracy_score(y_test, y_pred_lr),
accuracy_score(y_test, y_pred_dt),
accuracy_score(y_test, y_pred_rf),
accuracy_score(y_test, y_pred_gb),
],
'AUC-ROC': [
roc_auc_score(y_test, y_proba_lr),
roc_auc_score(y_test, y_proba_dt),
roc_auc_score(y_test, y_proba_rf),
roc_auc_score(y_test, y_proba_gb),
],
'F1-Score': [
f1_score(y_test, y_pred_lr),
f1_score(y_test, y_pred_dt),
f1_score(y_test, y_pred_rf),
f1_score(y_test, y_pred_gb),
]
})
print("Model Comparison:")
print(results)
# Cross-validation
cv_scores = cross_val_score(
RandomForestClassifier(n_estimators=100, random_state=42),
X_train, y_train, cv=5, scoring='roc_auc'
)
print(f"\nCross-validation AUC scores: {cv_scores}")
print(f"Mean CV AUC: {cv_scores.mean():.4f} (+/- {cv_scores.std():.4f})")
# Probability calibration
from sklearn.calibration import calibration_curve
prob_true, prob_pred = calibration_curve(y_test, y_proba_rf, n_bins=10)
plt.figure(figsize=(8, 6))
plt.plot(prob_pred, prob_true, 'o-', label='Random Forest')
plt.plot([0, 1], [0, 1], 'k--', label='Perfect Calibration')
plt.xlabel('Mean Predicted Probability')
plt.ylabel('Fraction of Positives')
plt.title('Calibration Curve')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
Class Imbalance Handling
- Oversampling: Increase minority class samples
- Undersampling: Reduce majority class samples
- SMOTE: Synthetic minority oversampling
- Class weights: Penalize misclassifying minority class
Threshold Selection
- Default (0.5): Equal misclassification cost
- Custom threshold: Based on business requirements
- Optimal: Maximizing F1-score or AUC
Deliverables
- Classification metrics (accuracy, precision, recall, F1)
- Confusion matrices for all models
- ROC and Precision-Recall curves
- Feature importance analysis
- Model comparison table
- Recommendations for best model
- Probability calibration plots
1---2name: classification-modeling3description: Build binary and multiclass classification models using logistic regression, decision trees, and ensemble methods for categorical prediction and classification4---5
6# Classification Modeling
7
8## Overview
9
10Classification modeling predicts categorical target values, assigning observations to discrete classes or categories based on input features.
11
12## When to Use
13
14- Predicting binary outcomes like customer churn, loan default, or email spam
15- Classifying items into multiple categories such as product types or sentiment
16- Building credit scoring models or risk assessment systems
17- Identifying disease diagnosis or medical condition from patient data
18- Predicting customer purchase likelihood or response to marketing
19- Detecting fraud, anomalies, or quality defects in production systems
20
21## Classification Types
22
23- **Binary Classification**: Two classes (yes/no, success/failure)
24- **Multiclass**: More than two classes
25- **Multi-label**: Multiple classes per observation
26
27## Common Algorithms
28
29- **Logistic Regression**: Linear classification
30- **Decision Trees**: Rule-based non-linear
31- **Random Forest**: Ensemble of decision trees
32- **Gradient Boosting**: Sequential tree building
33- **SVM**: Support Vector Machines
34- **Naive Bayes**: Probabilistic classifier
35
36## Key Metrics
37
38- **Accuracy**: Overall correct predictions
39- **Precision**: True positives / (true + false positives)
40- **Recall**: True positives / (true + false negatives)
41- **F1-Score**: Harmonic mean of precision/recall
42- **AUC-ROC**: Area under receiver operating characteristic curve
43
44## Implementation with Python
45
46```python
47import pandas as pd
48import numpy as np
49import matplotlib.pyplot as plt
50from sklearn.model_selection import train_test_split, cross_val_score
51from sklearn.preprocessing import StandardScaler
52from sklearn.linear_model import LogisticRegression
53from sklearn.tree import DecisionTreeClassifier
54from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
55from sklearn.metrics import (
56 confusion_matrix, classification_report, roc_auc_score, roc_curve,
57 precision_recall_curve, f1_score, accuracy_score
58)
59import seaborn as sns
60
61# Generate sample binary classification data
62np.random.seed(42)
63from sklearn.datasets import make_classification
64
65X, y = make_classification(
66 n_samples=1000, n_features=20, n_informative=10,
67 n_redundant=5, random_state=42
68)
69
70X_train, X_test, y_train, y_test = train_test_split(
71 X, y, test_size=0.2, random_state=42
72)
73
74# Standardize features
75scaler = StandardScaler()
76X_train_scaled = scaler.fit_transform(X_train)
77X_test_scaled = scaler.transform(X_test)
78
79# Logistic Regression
80lr_model = LogisticRegression(max_iter=1000)
81lr_model.fit(X_train_scaled, y_train)
82y_pred_lr = lr_model.predict(X_test_scaled)
83y_proba_lr = lr_model.predict_proba(X_test_scaled)[:, 1]
84
85print("Logistic Regression:")
86print(classification_report(y_test, y_pred_lr))
87print(f"AUC-ROC: {roc_auc_score(y_test, y_proba_lr):.4f}\n")
88
89# Decision Tree
90dt_model = DecisionTreeClassifier(max_depth=10, random_state=42)
91dt_model.fit(X_train, y_train)
92y_pred_dt = dt_model.predict(X_test)
93y_proba_dt = dt_model.predict_proba(X_test)[:, 1]
94
95print("Decision Tree:")
96print(classification_report(y_test, y_pred_dt))
97print(f"AUC-ROC: {roc_auc_score(y_test, y_proba_dt):.4f}\n")
98
99# Random Forest
100rf_model = RandomForestClassifier(n_estimators=100, max_depth=10, random_state=42)
101rf_model.fit(X_train, y_train)
102y_pred_rf = rf_model.predict(X_test)
103y_proba_rf = rf_model.predict_proba(X_test)[:, 1]
104
105print("Random Forest:")
106print(classification_report(y_test, y_pred_rf))
107print(f"AUC-ROC: {roc_auc_score(y_test, y_proba_rf):.4f}\n")
108
109# Gradient Boosting
110gb_model = GradientBoostingClassifier(n_estimators=100, max_depth=5, random_state=42)
111gb_model.fit(X_train, y_train)
112y_pred_gb = gb_model.predict(X_test)
113y_proba_gb = gb_model.predict_proba(X_test)[:, 1]
114
115print("Gradient Boosting:")
116print(classification_report(y_test, y_pred_gb))
117print(f"AUC-ROC: {roc_auc_score(y_test, y_proba_gb):.4f}\n")
118
119# Confusion matrices
120fig, axes = plt.subplots(2, 2, figsize=(12, 10))
121
122models = [
123 (y_pred_lr, 'Logistic Regression'),
124 (y_pred_dt, 'Decision Tree'),
125 (y_pred_rf, 'Random Forest'),
126 (y_pred_gb, 'Gradient Boosting'),
127]
128
129for idx, (y_pred, title) in enumerate(models):
130 cm = confusion_matrix(y_test, y_pred)
131 ax = axes[idx // 2, idx % 2]
132 sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', ax=ax)
133 ax.set_title(title)
134 ax.set_ylabel('True Label')
135 ax.set_xlabel('Predicted Label')
136
137plt.tight_layout()
138plt.show()
139
140# ROC Curves
141plt.figure(figsize=(10, 8))
142
143probas = [
144 (y_proba_lr, 'Logistic Regression'),
145 (y_proba_dt, 'Decision Tree'),
146 (y_proba_rf, 'Random Forest'),
147 (y_proba_gb, 'Gradient Boosting'),
148]
149
150for y_proba, label in probas:
151 fpr, tpr, _ = roc_curve(y_test, y_proba)
152 auc = roc_auc_score(y_test, y_proba)
153 plt.plot(fpr, tpr, label=f'{label} (AUC={auc:.4f})')
154
155plt.plot([0, 1], [0, 1], 'k--', label='Random Classifier')
156plt.xlabel('False Positive Rate')
157plt.ylabel('True Positive Rate')
158plt.title('ROC Curves Comparison')
159plt.legend()
160plt.grid(True, alpha=0.3)
161plt.show()
162
163# Precision-Recall Curves
164plt.figure(figsize=(10, 8))
165
166for y_proba, label in probas:
167 precision, recall, _ = precision_recall_curve(y_test, y_proba)
168 f1 = f1_score(y_test, (y_proba > 0.5).astype(int))
169 plt.plot(recall, precision, label=f'{label} (F1={f1:.4f})')
170
171plt.xlabel('Recall')
172plt.ylabel('Precision')
173plt.title('Precision-Recall Curves')
174plt.legend()
175plt.grid(True, alpha=0.3)
176plt.show()
177
178# Feature importance
179fig, axes = plt.subplots(1, 2, figsize=(14, 5))
180
181# Tree-based feature importance
182feature_importance_rf = pd.Series(
183 rf_model.feature_importances_, index=range(X.shape[1])
184).sort_values(ascending=False)
185
186axes[0].barh(range(10), feature_importance_rf.values[:10])
187axes[0].set_yticks(range(10))
188axes[0].set_yticklabels([f'Feature {i}' for i in feature_importance_rf.index[:10]])
189axes[0].set_title('Random Forest - Top 10 Features')
190axes[0].set_xlabel('Importance')
191
192# Logistic regression coefficients
193lr_coef = pd.Series(lr_model.coef_[0], index=range(X.shape[1])).abs().sort_values(ascending=False)
194axes[1].barh(range(10), lr_coef.values[:10])
195axes[1].set_yticks(range(10))
196axes[1].set_yticklabels([f'Feature {i}' for i in lr_coef.index[:10]])
197axes[1].set_title('Logistic Regression - Top 10 Features (abs coef)')
198axes[1].set_xlabel('Absolute Coefficient')
199
200plt.tight_layout()
201plt.show()
202
203# Model comparison
204results = pd.DataFrame({
205 'Model': ['Logistic Regression', 'Decision Tree', 'Random Forest', 'Gradient Boosting'],
206 'Accuracy': [
207 accuracy_score(y_test, y_pred_lr),
208 accuracy_score(y_test, y_pred_dt),
209 accuracy_score(y_test, y_pred_rf),
210 accuracy_score(y_test, y_pred_gb),
211 ],
212 'AUC-ROC': [
213 roc_auc_score(y_test, y_proba_lr),
214 roc_auc_score(y_test, y_proba_dt),
215 roc_auc_score(y_test, y_proba_rf),
216 roc_auc_score(y_test, y_proba_gb),
217 ],
218 'F1-Score': [
219 f1_score(y_test, y_pred_lr),
220 f1_score(y_test, y_pred_dt),
221 f1_score(y_test, y_pred_rf),
222 f1_score(y_test, y_pred_gb),
223 ]
224})
225
226print("Model Comparison:")
227print(results)
228
229# Cross-validation
230cv_scores = cross_val_score(
231 RandomForestClassifier(n_estimators=100, random_state=42),
232 X_train, y_train, cv=5, scoring='roc_auc'
233)
234print(f"\nCross-validation AUC scores: {cv_scores}")
235print(f"Mean CV AUC: {cv_scores.mean():.4f} (+/- {cv_scores.std():.4f})")
236
237# Probability calibration
238from sklearn.calibration import calibration_curve
239
240prob_true, prob_pred = calibration_curve(y_test, y_proba_rf, n_bins=10)
241
242plt.figure(figsize=(8, 6))
243plt.plot(prob_pred, prob_true, 'o-', label='Random Forest')
244plt.plot([0, 1], [0, 1], 'k--', label='Perfect Calibration')
245plt.xlabel('Mean Predicted Probability')
246plt.ylabel('Fraction of Positives')
247plt.title('Calibration Curve')
248plt.legend()
249plt.grid(True, alpha=0.3)
250plt.show()
251```
252
253## Class Imbalance Handling
254
255- **Oversampling**: Increase minority class samples
256- **Undersampling**: Reduce majority class samples
257- **SMOTE**: Synthetic minority oversampling
258- **Class weights**: Penalize misclassifying minority class
259
260## Threshold Selection
261
262- **Default (0.5)**: Equal misclassification cost
263- **Custom threshold**: Based on business requirements
264- **Optimal**: Maximizing F1-score or AUC
265
266## Deliverables
267
268- Classification metrics (accuracy, precision, recall, F1)
269- Confusion matrices for all models
270- ROC and Precision-Recall curves
271- Feature importance analysis
272- Model comparison table
273- Recommendations for best model
274- Probability calibration plots