🌝

【19日目】SHAPや特徴量の重要度を確認して解釈性をみる【2021アドベントカレンダー】

2021/12/19に公開

2021年1人アドベントカレンダー(機械学習)、19日目の記事になります。

https://qiita.com/advent-calendar/2021/solo_advent_calendar

テーマは 解釈性 になります。

Colab のコードはこちら Open In Colab

特徴量の重要度

基本形は以下になります。

なお、scikit-learn のように使える LightGBMRegressor() を前提としています。

plt.barh(
    df.columns, # カラム名
    model.feature_importances_, # 決定木
)

通常の LightGBM の場合は以下のサイトを参照ください。

https://potesara-tips.com/lightgbm-feature-importance/

.feature_importances_ は RandomForest のような決定木モデルに使用できます。

特徴量の重要度の考え方については以下のサイトをご参照ください。

https://nomoto-eriko.hatenablog.com/entry/2018/06/06/101729

SHAP

SHAP は協力ゲーム理論のシャープレイ値の考え方を応用して特徴量の貢献度を算出します。

詳しい理論については下記のサイトをご参照ください。

https://www.datarobot.com/jp/blog/explain-machine-learning-models-using-shap/

基本形は以下になります。

import shap

explainer = shap.TreeExplainer(model))
shap_values = explainer.shap_values(X_test)

shap.summary_plot(
            shap_values=shap_values,
            features=X_test,
            feature_names=columns # カラム名
            )
plt.show()

詳細

# 学習・推論
gkf = GroupKFold(n_splits=3)

groups = X_train["Genre"]

cv_result_lgbm = []

for i, (train_index, test_index) in enumerate(gkf.split(X_train, y_train, groups)):
    X_train_gkf, X_test_gkf = X_train.iloc[train_index], X_train.iloc[test_index]
    y_train_gkf, y_test_gkf = y_train.iloc[train_index], y_train.iloc[test_index]

    # 学習、推論
    pipe.fit(X_train_gkf, y_train_gkf)

    y_pred = pipe.predict(X_test_gkf)

    rmse = mean_squared_error(y_test_gkf, y_pred, squared=False)
    cv_result_lgbm.append(rmse)

    # shap
    X_train_gkf = columns_transformers.fit_transform(X_train_gkf)
    X_test_gkf = columns_transformers.fit_transform(X_test_gkf)

    # OneHotを考慮したの全カラム作成
    all_columns = number_columns + \
                            many_kinds_category_columns + \
                            pipe["columns_transformers"].transformers_[2][1]["onehot"].get_feature_names(few_kinds_category_columns).tolist()

    X_train_gkf = pd.DataFrame(
        X_train_gkf,
        columns=all_columns
        )

    X_test_gkf = pd.DataFrame(
        X_test_gkf,
        columns=all_columns
        )
    
    # 特徴量の重要性
    plt.figure(figsize=(8, 5))
    plt.title(f"fold {i} 特徴量の重要性")
    plt.barh(
        X_test_gkf.columns,
        pipe["model"].feature_importances_,
    )
    plt.show()


    # shap
    explainer = shap.TreeExplainer(pipe['model'])
    shap_values = explainer.shap_values(X_test_gkf)

    plt.title(f"fold {i} SHAP値")
    shap.summary_plot(
                shap_values=shap_values,
                features=X_test_gkf,
                feature_names=X_test_gkf.columns
                )
    plt.show()

19日目は以上になります、最後までお読みいただきありがとうございました。

Discussion