成功訓練100棵決策樹構成的隨機森林模型,完成測試集推論,並透過雙子圖呈現混淆矩陣結構改善與特徵貢獻分佈。
一、實作前情境:為什麼隨機森林能救回邊界預測?
在 Day 19 的實測中,邏輯回歸因為受限於線性超平面,無法捕捉複雜的條件判斷,最終退化為「預測93筆中度風險」的保守策略,使低度風險與高度風險的召回率幾近於0。
隨機森林作為 Bagging 集成學習的代表,具備以下對應優勢:
二、撰寫隨機森林訓練、評估與重要度可視化腳本
在Colab中新增儲存格,建立隨機森林分類器,並同步繪製測試集混淆矩陣與特徵重要度長條圖:
# ==========================================
# Day 20:隨機森林分類器與非線性特徵重要度分析
# ==========================================
import warnings
warnings.filterwarnings('ignore')
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib.font_manager as fm
import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score
# 1. 引用中文字型
font_path = 'NotoSansTC-Regular.otf'
my_font = fm.FontProperties(fname=font_path)
# 2. 建立並訓練隨機森林分類器
# 設定 n_estimators=100, max_depth=6 避免小樣本過度擬合 (Overfitting)
rf_clf = RandomForestClassifier(
n_estimators=100,
max_depth=6,
min_samples_split=5,
min_samples_leaf=2,
random_state=42,
class_weight='balanced' # 平衡各類別權重,打破多數類偏差
)
rf_clf.fit(X_train, y_train)
# 3. 測試集預測與性能指標
y_pred_rf = rf_clf.predict(X_test)
y_prob_rf = rf_clf.predict_proba(X_test)
acc_rf = accuracy_score(y_test, y_pred_rf)
print(f"=== 隨機森林測試集整體準確率 (Accuracy): {acc_rf * 100:.2f}% ===\n")
# 4. 輸出分類評估報告 (Precision, Recall, F1-score)
target_names = ['低度風險 (Low)', '中度風險 (Medium)', '高度風險 (High)']
report_dict_rf = classification_report(y_test, y_pred_rf, target_names=target_names, output_dict=True)
report_df_rf = pd.DataFrame(report_dict_rf).transpose()
print("=== 隨機森林分類性能評估報告 (Classification Report) ===")
display(report_df_rf.round(3))
# 5. 繪製 1x2 畫布:混淆矩陣熱力圖 + 特徵重要度排序圖
fig, axes = plt.subplots(1, 2, figsize=(16, 6))
sns.set_theme(style="white")
# --- 圖 1:隨機森林混淆矩陣 (Confusion Matrix) ---
cm_rf = confusion_matrix(y_test, y_pred_rf)
sns.heatmap(
cm_rf,
annot=True,
fmt='d',
cmap='Greens',
xticklabels=target_names,
yticklabels=target_names,
cbar=False,
ax=axes[0]
)
axes[0].set_title('隨機森林測試集混淆矩陣 (Confusion Matrix)', fontproperties=my_font, fontsize=14, fontweight='bold')
axes[0].set_xlabel('模型預測等級 (Predicted Label)', fontproperties=my_font, fontsize=12)
axes[0].set_ylabel('真實風險等級 (True Label)', fontproperties=my_font, fontsize=12)
axes[0].set_xticklabels(target_names, fontproperties=my_font, fontsize=10)
axes[0].set_yticklabels(target_names, fontproperties=my_font, fontsize=10)
# --- 圖 2:隨機森林特徵重要度 (MDI Feature Importance) ---
importances = pd.Series(rf_clf.feature_importances_, index=X_train.columns).sort_values(ascending=True)
importances.plot(
kind='barh',
ax=axes[1],
color='#27ae60',
edgecolor='none',
alpha=0.85
)
axes[1].set_title('隨機森林特徵重要度排序 (Feature Importance)', fontproperties=my_font, fontsize=14, fontweight='bold')
axes[1].set_xlabel('不純度減少貢獻度 (Mean Decrease in Impurity)', fontproperties=my_font, fontsize=12)
axes[1].set_ylabel('輸入特徵項目', fontproperties=my_font, fontsize=12)
plt.tight_layout()
plt.show()
# 6. 輸出詳細特徵重要度數值表
feat_imp_df = pd.DataFrame({
'特徵項目': importances.index,
'貢獻佔比 (%)': (importances.values * 100).round(2)
}).sort_values(by='貢獻佔比 (%)', ascending=False).reset_index(drop=True)
print("=== 特徵重要度完整排序表 ===")
display(feat_imp_df)


三、圖表解讀與客觀數據分析
本實作以100棵決策樹構成的隨機森林分類器進行預測建模,並加入 class_weight='balanced' 嘗試修復多數類偏差。結合分類報告、測試集混淆矩陣與特徵重要度排序表,可得出以下深度的機器學習實務洞察:
1.混淆矩陣結構改善:成功打破「全判中度」的單一垂直牆
對比Day 19多元邏輯回歸(將93筆全判為中度、低/高風險預測為0的極端崩塌),隨機森林在預測分佈上展現了非線性樹模型的結構修復能力:
a.分類分佈展開:
低度風險(Low,真實24筆):模型預測了25筆,精準命中7筆(召回率從邏輯回歸的0.0%大幅回升至29.2%,F1-score 達 0.286)。
中度風險(Medium,真實47筆):命中26筆,召回率為55.3%,Precision為0.448。
高度風險(High,真實29筆):模型打破了邏輯回歸命中0筆的死局,成功預測出2筆真實高風險樣本。
b.效能瓶頸評估:
b.第二梯隊:生理年齡與自覺症狀(次要調節層,貢獻度約 7%~13%)
c.第三梯隊:二元標籤與特定行為(微弱邊際層,貢獻度 < 3%)