使用shap解釋預測結果

變量解釋

  • explainer.excepted_value
    • 預測結果的預期,有時候是一批數據預測結果的均值??
    • 分標籤,如果是多分類,每一個類別都會有一個預期值,分析shap value時候選擇對應標籤的excepted_value
    • 解釋預測結果時候,從這個值出發,每個特徵對預測結果有一個影響,最終決定模型的輸出
    • 這個結果應該也是 log odds, 因爲它會出現負數
  • log odds: 對數機率 = log p / (1-p)
    • 假設預測爲正樣本的概率爲0.01,那麼對數機率(以10爲底) = log 0.01 / 0.99 = -3.9
    • 假設預測爲正樣本的概率爲0.99,那麼對數機率(以10爲底) = log 99 = 1.9
  • shap_values
    • shape=(n_labels, n_rows, n_cols)
    • 包含的信息是對每個標籤,每一行,每個特徵都有一個值
    • 實際上我們分析時候,會單獨看每一個標籤的預測分析,二分類的就取label爲1的shap value,也就是shap_values[1]
    • 單獨分析每一行的時候就是 shap_values[1].iloc[index]

KernelExplainer原理

以計算一條記錄其中一個特徵特徵shap_values爲例,說明計算過程:

  1. 把樣本特徵轉換成數字
  2. 隨意生成n個隨機數作爲mask,將原始的特徵與這個mask計算得到新的n個特徵
  3. 新的n個特徵帶入模型預測獲取預測結果,觀察預測結果的變化與那個特徵的規律得到shap_value

使用shap解釋預測結果例子

訓練lightgbm模型:

import lightgbm as lgb
import shap
from sklearn.model_selection import train_test_split, StratifiedKFold
import warnings

X, y = shap.datasets.adult()
X_display, y_display = shap.datasets.adult(display=True)

# create a train/test split
random_state = 7
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=random_state)
d_train = lgb.Dataset(X_train, label=y_train)
d_test = lgb.Dataset(X_test, label=y_test)

params = {
    "max_bin": 512,
    "learning_rate": 0.05,
    "boosting_type": "gbdt",
    "objective": "binary",
    "metric": "binary_logloss",
    "num_leaves": 10,
    "verbose": -1,
    "min_data": 100,
    "boost_from_average": True,
    "random_state": random_state
}

model = lgb.train(params, d_train, 10000, valid_sets=[d_test], early_stopping_rounds=50, verbose_eval=1000)
model
# <lightgbm.basic.Booster object at 0x000001B96CBFAD48>

構建解釋器並獲取預期值:

explainer = shap.TreeExplainer(model)  #  使用樹模型解釋器
explainer
# Out[5]: <shap.explainers._tree.Tree at 0x1b96cca5e48>
expected_value = explainer.expected_value  
expected_value
# Out[7]: array([-2.43266725])

構建解釋器並獲取預期值:

features.shape
# Out[17]: (20, 12)
shap_values = explainer.shap_values(features)  # 計算shap_values
len(shap_values)
# Out[12]: 2
shap_values[0].shape
# Out[13]: (20, 12)

繪製決策圖:

shap.decision_plot(base_value=expected_value, shap_values=shap_values[1][:1], features=features_display[:1])

輸出:

decision_plot 解釋:

  1. x軸是模型的輸出,y軸是特徵名稱,線表示預測的過程
  2. 模型的輸出通常是一個概率,對這個概率取對數機率就是模型的輸出
  3. shap_values: 要解釋的數據的shap_values
  4. features: 估計是用來提取列名的,可以不傳或者用feautues_names 代替
  5. 特徵牽拉的幅度越大表示對預測結果的影響越大,影響分成正面影響和負面影響
  6. 找到那些對正面影響較大的特徵以及其取值來解釋預測結果

還可以使用力圖來解釋預測結果:

shap.force_plot(explainer.expected_value[0], shap_values[1][:1], features[:1], matplotlib=True)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章