進階技巧:隨機森林與過度擬合

在前一章中,我們使用了決策樹來預測客戶流失。決策樹雖然直觀,但它有一個嚴重的問題:很容易過度擬合 (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 個普通人的意見然後投票。

隨機森林的運作原理

  1. 隨機抽樣:從原始資料中隨機抽取多份樣本(Bootstrapping)
  2. 訓練多棵樹:在每份樣本上訓練一棵決策樹
  3. 隨機特徵選擇:每棵樹分裂時,只隨機考慮一部分特徵(防止所有樹長得一模一樣)
  4. 投票決定:預測時,所有樹投票決定結果
原始資料
    │
    ├── 隨機抽樣 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. 輸出特徵重要性排序。」

本日總結

在本章中,你學到了:

  1. 過度擬合 (Overfitting):模型記住雜訊而非規律
  2. 解決方法:限制深度、交叉驗證
  3. 隨機森林原理:多棵樹投票,比單一決策樹更穩定
  4. 隨機森林實戰:n_estimators、max_depth 等關鍵參數
  5. 模型比較:評估不同演算法的優劣

下一章,我們將學習如何保存模型並將其整合到真實應用中!

解鎖完整教學內容

本章為付費內容。加入專案即可解鎖超過 5000 字的深度解析,包含 10 個以上神級 Prompt 與真實 Source Code 範例!