分類模型:預測客戶流失
在上一章中,我們學會了預測「數值」(房價)。但現實中還有一類非常重要的問題:預測「類別」。
- 這筆交易是詐騙嗎? → 是/否
- 這位客戶下個月會流失嗎? → 會流失/不會流失
- 這張 MRI 影像中的腫瘤是良性還是惡性? → 良性/惡性
這些都是分類問題 (Classification)。
業務場景:電商客戶流失預測
想像你經營一個月費訂閱制的電商平台,每個月都有客戶取消訂閱。如果能提前知道「哪些客戶快要流失了」,你就可以在他們取消之前,自動發送優惠券或關懷訊息給他們,大幅降低流失率。
載入客戶資料集
我們將使用一個模擬的電商客戶資料集:
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
# 建立模擬客戶資料
np.random.seed(42)
n_customers = 1000
df = pd.DataFrame({
'tenure_months': np.random.randint(1, 72, n_customers), # 使用月數
'monthly_charges': np.random.uniform(30, 120, n_customers), # 月費金額
'total_charges': np.random.uniform(100, 8000, n_customers), # 總消費金額
'num_support_tickets': np.random.randint(0, 10, n_customers), # 客服次數
'has_contract': np.random.choice([0, 1], n_customers), # 是否綁約
'avg_order_value': np.random.uniform(10, 200, n_customers), # 平均訂單金額
'num_complaints': np.random.randint(0, 5, n_customers), # 投訴次數
})
# 模擬流失標籤(越高的使用月數、綁約、越不容易流失)
churn_prob = (
0.4
- 0.005 * df['tenure_months']
+ 0.003 * df['num_support_tickets']
+ 0.05 * df['num_complaints']
- 0.15 * df['has_contract']
+ np.random.normal(0, 0.1, n_customers)
)
df['churn'] = (churn_prob > 0.5).astype(int)
print(f"資料集大小: {df.shape}")
print(f"流失客戶比例: {df['churn'].mean()*100:.1f}%")
邏輯迴歸 (Logistic Regression)
別被名字騙了!雖然叫做「迴歸」,但邏輯迴歸其實是用來做分類的。
它的概念是:先計算一個數值(像是迴歸),然後透過一個 Sigmoid 函數 將這個數值轉換為 0 到 1 之間的「機率」。
$$P(y=1) = \frac{1}{1 + e^{-(w_1x_1 + w_2x_2 + ... + b)}}$$
- 如果機率 $\geq 0.5$,預測為「流失」(1)
- 如果機率 $< 0.5$,預測為「不流失」(0)
訓練邏輯迴歸模型
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
# 分割資料
X = df.drop('churn', axis=1)
y = df['churn']
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 標準化特徵(邏輯迴歸需要)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 訓練模型
log_model = LogisticRegression()
log_model.fit(X_train_scaled, y_train)
# 預測
y_pred = log_model.predict(X_test_scaled)
y_pred_proba = log_model.predict_proba(X_test_scaled)[:, 1]
# 評估
accuracy = accuracy_score(y_test, y_pred)
print(f"準確率: {accuracy:.4f}")
分類模型的評估指標
分類模型的評估比迴歸複雜一些,因為我們不能只看「準確率」。
混淆矩陣 (Confusion Matrix)
混淆矩陣是分類評估的基礎,它告訴你模型在哪裡犯了錯:
cm = confusion_matrix(y_test, y_pred)
print("混淆矩陣:")
print(cm)
# 手動解讀
TN, FP, FN, TP = cm.ravel()
print(f"\n真負例 (TN): {TN} — 正確預測不會流失")
print(f"假正例 (FP): {FP} — 誤判為流失(白白送了優惠券)")
print(f"假負例 (FN): {FN} — 漏判流失(最嚴重!)")
print(f"真正例 (TP): {TP} — 正確預測會流失")
精準率 (Precision) vs 召回率 (Recall)
精準率 (Precision):預測「會流失」的客戶中,有多少真的流失了? $$Precision = \frac{TP}{TP + FP}$$
- 精準率低 → 太多誤判,浪費優惠券成本
召回率 (Recall):真正流失的客戶中,我們成功預測了多少? $$Recall = \frac{TP}{TP + FN}$$
- 召回率低 → 太多漏判,沒能挽留客戶
F1 分數:精準率與召回率的調和平均數 $$F1 = 2 \times \frac{Precision \times Recall}{Precision + Recall}$$
print("\n分類報告:")
print(classification_report(y_test, y_pred, target_names=['未流失', '流失']))
重點:不要只看準確率!
假設你的資料中只有 5% 的客戶會流失。如果模型「全部預測為不流失」,準確率仍然是 95%!但這個模型完全沒有用。
當資料不平衡時(流失客戶很少),請以召回率與精準率為主要評估指標。
決策樹 (Decision Tree)
決策樹是另一個非常直觀的分類演算法。它就像一個「如果...就...」的問答遊戲:
是否綁約?
├── 沒有綁約:是否經常投訴?
│ ├── 是:預測流失 ❌
│ └── 否:使用月數 > 12?
│ ├── 是:預測不流失 ✅
│ └── 否:預測流失 ❌
└── 有綁約:預測不流失 ✅
from sklearn.tree import DecisionTreeClassifier
# 決策樹不需要標準化
dt_model = DecisionTreeClassifier(max_depth=5, random_state=42)
dt_model.fit(X_train, y_train)
# 預測與評估
y_pred_dt = dt_model.predict(X_test)
print(f"決策樹準確率: {accuracy_score(y_test, y_pred_dt):.4f}")
print("\n決策樹分類報告:")
print(classification_report(y_test, y_pred_dt, target_names=['未流失', '流失']))
max_depth=5 限制樹的深度,避免過度擬合 (Overfitting)。
特徵重要性分析
決策樹有一個強大的功能:它可以告訴你「哪些特徵對預測最有幫助」:
feature_importance = pd.DataFrame({
'特徵': X.columns,
'重要性': dt_model.feature_importances_
}).sort_values('重要性', ascending=False)
print("特徵重要性:")
print(feature_importance)
# 畫出特徵重要性
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 6))
plt.barh(feature_importance['特徵'], feature_importance['重要性'])
plt.xlabel('重要性')
plt.title('特徵重要性分析')
plt.gca().invert_yaxis()
plt.show()
使用 Vibe Coding 做分類
🔥 【分類模型詠唱範例】
「我有一個 customer_data.csv,包含使用月數、月費、客服次數、是否綁約、投訴次數等欄位。請幫我:1. 使用 LogisticRegression 與 DecisionTreeClassifier 分別訓練流失預測模型。2. 比較兩者的準確率、精準率、召回率與 F1 分數。3. 畫出混淆矩陣。4. 輸出決策樹的特徵重要性排序。5. 判斷哪個模型更適合這個任務,並說明原因。」
本日總結
在本章中,你學到了:
- ✅ 分類問題:預測類別而非數值
- ✅ 邏輯迴歸:透過 Sigmoid 函數計算分類機率
- ✅ 混淆矩陣:了解模型在哪裡犯錯
- ✅ 精準率 vs 召回率:不同場景下該關注哪個指標
- ✅ 決策樹:直觀的 if-else 分類規則
- ✅ 特徵重要性:找出哪些因素最影響預測結果
下一章,我們將學習如何避免模型過度擬合,並使用更強大的隨機森林演算法!