利用在 Day 23 表現最為優異的 LightGBM 冠軍模型,導入源自合作賽局理論的 SHAP(SHapley Additive exPlanations) 框架。擺脫傳統特徵重要度僅能給出相對排序的局限,計算各特徵對「高度疲勞風險(High Risk)」預測機率的真實邊際貢獻值(Shapley Value),繪製全局摘要蜂群圖(Summary Beeswarm Plot)與特徵交互作用相依圖(Dependence Plot),達成醫療級的可解釋性 AI(XAI)標準。
一、實作前情境:為什麼有了特徵重要度,還需要SHAP?
在 Day 20、22 與 23 中,我們分別探討了隨機森林的 MDI、XGBoost 的 Gain 與 LightGBM 的 Split 分裂次數:
1.傳統特徵重要度的致命盲區:
今天我們聚焦於臨床與健康管理最關心的目標——「高度疲勞風險(High Risk,類別 2)」的預測歸因機制。
二、撰寫SHAP歸因分析與視覺化腳本
在 Colab 中新增儲存格,使用 shap 套件建立 TreeExplainer,產出全局蜂群圖與 CESI 指數特徵相依圖:
# ==========================================
# Day 25:LightGBM 模型之 SHAP 可解釋性分析
# ==========================================
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
import shap
# 1. 引用中文字型
font_path = 'NotoSansTC-Regular.otf'
my_font = fm.FontProperties(fname=font_path)
# 2. 建立適用於樹模型的 SHAP TreeExplainer
# 使用在 Day 23 訓練完成的 lgb_clf
explainer = shap.TreeExplainer(lgb_clf)
# 3. 計算測試集 (X_test) 的 SHAP 數值
# 對於多分類模型,shap_values 形狀為 (樣本數, 特徵數, 類別數)
shap_values = explainer(X_test)
# 提取針對「高度疲勞風險 (Class 2: High)」的 SHAP 值
shap_values_high = shap_values[:, :, 2]
# 4. 繪製 SHAP 全局摘要蜂群圖 (Summary Beeswarm Plot)
plt.figure(figsize=(12, 7))
plt.title('特徵對預測「高度疲勞風險 (High)」的 SHAP 邊際貢獻分佈', fontproperties=my_font, fontsize=14, fontweight='bold', pad=15)
# 繪製蜂群圖 (每個點代表測試集的一位受試者)
shap.plots.beeswarm(shap_values_high, max_display=11, show=False)
# 調整坐標軸字型
plt.xlabel('SHAP 值 (推升預測為高度風險的邊際貢獻)', fontproperties=my_font, fontsize=12)
plt.ylabel('輸入特徵項目', fontproperties=my_font, fontsize=12)
plt.tight_layout()
plt.show()
# 5. 繪製核心特徵相依圖 (Dependence Plot):CESI_Score vs. Sleep_Hours
# 觀察合成指數在不同睡眠時數下的邊際效應演變
fig, ax = plt.subplots(figsize=(10, 6))
shap.plots.scatter(
shap_values_high[:, 'CESI_Score'],
color=shap_values_high[:, 'Sleep_Hours'],
ax=ax,
show=False
)
ax.set_title('CESI 綜合疲勞指數與睡眠時數對高度風險的非線性交互 SHAP 相依圖', fontproperties=my_font, fontsize=13, fontweight='bold')
ax.set_xlabel('CESI 綜合疲勞指數 (標準化後)', fontproperties=my_font, fontsize=12)
ax.set_ylabel('CESI_Score 之 SHAP 貢獻值', fontproperties=my_font, fontsize=12)
plt.tight_layout()
plt.show()
# 6. 計算平均絕對 SHAP 值總表 (全局邊際影響力排名)
mean_abs_shap = np.abs(shap_values_high.values).mean(axis=0)
shap_ranking_df = pd.DataFrame({
'特徵項目': X_test.columns,
'平均絕對 SHAP 貢獻值': mean_abs_shap.round(4)
}).sort_values(by='平均絕對 SHAP 貢獻值', ascending=False).reset_index(drop=True)
print("=== 預測高風險之 SHAP 特徵全局影響力排行榜 ===")
display(shap_ranking_df)



三、圖表解讀與客觀數據分析
b.特徵工程指標成功驗證:CESI_Score 穩坐第二(平均絕對 SHAP 達 0.1642):
c.作息暴露的拉鋸:Sleep_Hours (0.1589) vs. Daily_Screen_Hours (0.1493):
d.無效特徵的幾何收斂:底層邊界完全凍結:
b.睡眠時數(Sleep_Hours)的非線性調節: