進階技巧:隨機森林與過度擬合
在前一章中,我們使用了決策樹來預測客戶流失。決策樹雖然直觀,但它有一個嚴重的問題:很容易過度擬合 (Overfitting)。
什麼是過度擬合 (Overfitting)?
過度擬合就像是一個學生「把課本答案全部背下來,但完全不懂背後的原理」。
- 訓練集考試:100 分(完美記住所有題目)
- 測試集考試:40 分(題目一變就不會了)
過度擬合的症狀:
- 訓練集準確率非常高(接近 100%)
- 測試集準確率明顯低很多
- 模型對雜訊(outliers)過度敏感
視覺化理解
左圖是「正常的擬合」:
- 線條平滑,抓住了資料的整體趨勢
- 訓練集與測試集的表現接近
右圖是「過度擬合」:
- 線條彎彎曲曲,試圖穿過每一個資料點
- 訓練集表現極佳,但測試集表現很差
正常擬合 過度擬合
▲ ▲
│ ○ ○ │ ○ ╱╲ ○
│ ○ ○ ○ ○ │ ╱ ○╲○ ○╲
│ ○ ○ ○ ○ ○ │○ ○──╲─○ ○
│___╱╲___○_____ │_____╱╲______
└───────────► └───────────►
解決過度擬合的方法
1. 限制模型複雜度 (Regularization)
在決策樹中,可以透過限制 max_depth(最大深度)來防止過度擬合:
# 太淺 → 欠擬合 (Underfitting):沒學到足夠的規律
shallow_tree = DecisionTreeClassifier(max_depth=2)
# 適中 → 剛剛好
good_tree = DecisionTreeClassifier(max_depth=5)
# 太深 → 過度擬合:連雜訊都記住了
deep_tree = DecisionTreeClassifier(max_depth=20)
2. 交叉驗證 (Cross Validation)
不要把全部資料一次分割,而是分成 K 份輪流當測試集,取平均分數:
from sklearn.model_selection import cross_val_score
# 5 折交叉驗證
scores = cross_val_score(dt_model, X_train, y_train, cv=5)
print(f"每折分數: {scores}")
print(f"平均分數: {scores.mean():.4f}")
print(f"標準差: {scores.std():.4f}")
如果標準差很大(例如 > 0.05),代表模型在不同資料子集上表現不穩定,可能是過度擬合的徵兆。
隨機森林 (Random Forest)
隨機森林是「一群決策樹的集合」。它的概念是:與其依賴一個專家的判斷,不如問 100 個普通人的意見然後投票。
隨機森林的運作原理
- 隨機抽樣:從原始資料中隨機抽取多份樣本(Bootstrapping)
- 訓練多棵樹:在每份樣本上訓練一棵決策樹
- 隨機特徵選擇:每棵樹分裂時,只隨機考慮一部分特徵(防止所有樹長得一模一樣)
- 投票決定:預測時,所有樹投票決定結果
原始資料
│
├── 隨機抽樣 1 → 決策樹 1 → 投票 ┐
├── 隨機抽樣 2 → 決策樹 2 → 投票 ┼── 多數決 → 最終預測
├── 隨機抽樣 3 → 決策樹 3 → 投票 ┘
└── ...(通常 100-500 棵樹)
訓練隨機森林
from sklearn.ensemble import RandomForestClassifier
# 建立隨機森林模型
rf_model = RandomForestClassifier(
n_estimators=100, # 100 棵樹
max_depth=10, # 每棵樹最大深度
min_samples_split=5, # 內部節點再分裂所需的最小樣本數
random_state=42,
n_jobs=-1 # 使用所有 CPU 核心加速
)
# 訓練
rf_model.fit(X_train, y_train)
# 預測
y_pred_rf = rf_model.predict(X_test)
# 評估
from sklearn.metrics import classification_report
print("隨機森林分類報告:")
print(classification_report(y_test, y_pred_rf, target_names=['未流失', '流失']))
比較:決策樹 vs 隨機森林
# 比較兩者的準確率
print(f"決策樹準確率: {accuracy_score(y_test, y_pred_dt):.4f}")
print(f"隨機森林準確率: {accuracy_score(y_test, y_pred_rf):.4f}")
# 比較兩者的 F1 分數
from sklearn.metrics import f1_score
print(f"決策樹 F1: {f1_score(y_test, y_pred_dt):.4f}")
print(f"隨機森林 F1: {f1_score(y_test, y_pred_rf):.4f}")
隨機森林通常比單一決策樹的準確率高 3-10%,而且不容易過度擬合。
隨機森林的特徵重要性
隨機森林也支援特徵重要性分析,而且比單一決策樹更可靠:
feature_importance_rf = pd.DataFrame({
'特徵': X.columns,
'重要性': rf_model.feature_importances_
}).sort_values('重要性', ascending=False)
print("隨機森林特徵重要性:")
print(feature_importance_rf)
# 畫圖
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 6))
plt.barh(feature_importance_rf['特徵'], feature_importance_rf['重要性'])
plt.xlabel('重要性')
plt.title('隨機森林特徵重要性分析')
plt.gca().invert_yaxis()
plt.show()
使用 Vibe Coding 訓練隨機森林
🔥 【隨機森林詠唱範例】
「請幫我使用 RandomForestClassifier 訓練一個客戶流失預測模型:1. 使用 200 棵樹,max_depth=8,min_samples_leaf=4。2. 計算並輸出訓練集與測試集的準確率(檢查是否過度擬合)。3. 輸出分類報告(精準率、召回率、F1)。4. 使用 5 折交叉驗證確認模型穩定性。5. 畫出 ROC 曲線並計算 AUC 分數。6. 輸出特徵重要性排序。」
本日總結
在本章中,你學到了:
- ✅ 過度擬合 (Overfitting):模型記住雜訊而非規律
- ✅ 解決方法:限制深度、交叉驗證
- ✅ 隨機森林原理:多棵樹投票,比單一決策樹更穩定
- ✅ 隨機森林實戰:n_estimators、max_depth 等關鍵參數
- ✅ 模型比較:評估不同演算法的優劣
下一章,我們將學習如何保存模型並將其整合到真實應用中!