モデルの説明可能性¶
学習の過程で、機械学習モデルは、入力と出力の間の関係を事前に明示的に記述することを要求するのではなく、入力と出力の関係を推論します。これによって、 ML 技術は、多くの変数を含む複雑なシナリオに、大規模なセットアップなしに取り組むことができます。特に、特定の結果の因果関係が複雑であったり、不明確であったりする場合には、結果として得られるモデルはブラックボックスのようなものになりかねません。あるモデルのパフォーマンスが低い場合、その理由を理解し、さらにパフォーマンスを改善する方法を理解するのが難しい場合があります。ブラックボックスモデルはまた、暗黙的なバイアスを隠し、意思決定の明確な理由を確立できない可能性もあります。金融やヘルスケアのように、信頼できるシステムに関する規制がある業界では、モデルが正しい理由で正しい結果を出しているという、より強力なエビデンスが必要になるかもしれません。
このような懸念に対応するため、Snowflake Model Registryには、 Shapley値 に基づく説明可能性関数が含まれています。Shapley値は、機械学習モデルの出力をその入力特徴量に帰着させる方法です。特徴量のすべての可能な組み合わせを考慮することで、Shapley値はモデルの予測に対する各特徴量の平均限界寄与度を測定します。このアプローチは、重要性の帰属における公平性を保証し、複雑なモデルを理解するための強固な基礎を提供します。計算量は多いですが、Shapley値から得られる洞察は、モデルの解釈可能性とデバッグにおいて非常に貴重です。
例えば、家の大きさ、立地、ベッドルームの数、ペットの可否について学習させた、家の価格を予測するモデルがあるとします。この例では、住宅の平均価格は10万ドルで、モデルの最終予測は、2000平方フィート、ビーチサイド、3ベッドルーム、ペット不可の住宅で25万ドルでした。これらの各特徴値は、以下の表に示すように、最終的なモデル予測に寄与する可能性があります。
機能 |
値 |
寄与度と平均的な家の比較 |
---|---|---|
サイズ |
2000 |
+$50,000 |
場所 |
ビーチサイド |
+$75,000 |
ベッドルーム |
3 |
+$50,000 |
ペット |
無し |
-$25,000 |
これらの寄与度が相まって、この家が平均的な住宅より15万ドルも高い価格設定になっています。Shapley値は、最終的な結果にプラスにもマイナスにも影響し、平均と比べた結果の差に加算されます。この例では、ペットを飼えない家に住むことはあまり好ましくないので、その特徴量の寄与度は-25,000ドルになります。
平均値は、データセット全体の代表的なサンプルであるバックグラウンドデータを用いて計算されます。詳細については、 背景データによるログ・モデル をご参照ください。
サポートされているモデルのタイプ¶
このプレビューリリースでは、以下のPythonネイティブモデルパッケージをサポートしています。
XGBoost
CatBoost
LightGBM
Scikit-learn
snowflake.ml.modeling
の以下の Snowpark ML モデリングクラスがサポートされています。
XGBoost
LightGBM
Scikit-learn (パイプラインモデルを除く)
説明可能性は、Snowpark ML 1.6.2以降を使用してログに記録された上記のモデルでデフォルトで利用可能です。実装には SHAP ライブラリ を使用します。
背景データによるログ・モデル¶
背景データ(通常、代表的なデータのサンプル)は、Shapley値に基づく説明の重要な要素です。背景データは、Shapley・アルゴリズムが個々の説明を比較できる「平均的な」入力がどのようなものかを示します。
Shapley値は、入力特徴を系統的に摂動させ、背景データと置き換えることによって計算されます。背景データからの偏差を報告するため、複数のデータセットのShapley値を比較する際には、一貫性のある背景データを使用することが重要です。
ツリーベースのモデルの中には、学習中に暗黙的に背景データを構造内にエンコードするものもあり、明示的な背景データを必要としない場合もあります。しかし、ほとんどのモデルでは、有益な説明をするために背景データを別途提供する必要があり、背景データを提供した方が、すべてのモデル(ツリーベースのモデルを含む)をより正確に説明することができます。
以下のように、 sample_input_data
パラメータに渡すことで、モデルのログ時に最大1,000行のバックグラウンドデータを提供することができます。
注釈
モデルがShapley値を計算するために明示的な背景データを必要とするモデルである場合、このデータがなければ説明可能性は有効になりません。
mv = reg.log_model(
catboost_model,
model_name="diamond_catboost_explain_enabled",
version_name="explain_v0",
conda_dependencies=["snowflake-ml-python"],
sample_input_data = xs, # xs will be used as background data
)
また、以下のようにシグネチャーでモデルをログに記録しながら、バックグラウンドデータを提供することもできます。
mv = reg.log_model(
catboost_model,
model_name="diamond_catboost_explain_enabled",
version_name="explain_v0",
conda_dependencies=["snowflake-ml-python"],
signatures={"predict": predict_signature, "predict_proba": predict_proba_signature},
sample_input_data = xs, # xs will be used as background data
options= {"enable_explainability": True} # you will need to set this flag in order to pass both signatures and background data
)
説明可能性の値の取得¶
説明可能性を持つモデルには、 explain
というメソッドがあり、モデルの特徴量のShapley値を返します。
Shapley値は特定の入力から作られる予測の説明であるため、説明される予測を生成するために入力データを explain
に渡す必要があります。
Snowflakeのモデルバージョンオブジェクトには explain
というメソッドがあり、Pythonの ModelVersion.run
を使って呼び出します。
reg = Registry(...)
mv = reg.get_model("Explainable_Catboost_Model").default
explanations = mv.run(input_data, function_name="explain")
以下は、 SQL の説明を取得する例です。
WITH MV_ALIAS AS MODEL DATABASE.SCHEMA.DIAMOND_CATBOOST_MODEL VERSION EXPLAIN_V0
SELECT *,
FROM DATABASE.SCHEMA.DIAMOND_DATA,
TABLE(MV_ALIAS!EXPLAIN(CUT, COLOR, CLARITY, CARAT, DEPTH, TABLE_PCT, X, Y, Z));
重要
バージョン1.7.0より前の snowflake-ml-python
を使用している場合、 XGBoost モデルでエラー UnicodeDecodeError: 'utf-8' codec can't decode byte
が表示されることがあります。これは、 SHAP ライブラリ のバージョン 0.42.1 と、Snowflake がサポートする XGBoost の最新バージョン(2.1.1)との間に互換性がないためです。 snowflake-ml-python
をバージョン1.7.0以降にアップグレードできない場合は、 XGBoost のバージョンを2.0.3にダウングレードし、次の例に示すように、 relax_version
オプションを False
に設定してモデルをログに記録します。
mv_new = reg.log_model(
model,
model_name="model_with_explain_enabled",
version_name="explain_v0",
conda_dependencies=["snowflake-ml-python"],
sample_input_data = xs,
options={"relax_version": False}
)
既存のモデルに説明可能性を加える¶
1.6.2より古いバージョンのSnowpark ML を使用してレジストリにログに記録されたモデルには、説明可能性の機能がありません。モデルのバージョンは不変なので、既存のモデルに説明可能性を追加するには、新しいモデルのバージョンを作成しなければなりません。 ModelVersion.load
を使ってモデルの実装を表す Python オブジェクトを取得し、それを新しいモデルのバージョンとしてレジストリのログに記録することができます。背景データは必ず sample_input_data
として渡してください。このアプローチを以下に示します。
重要
モデルをロードするPython環境は、モデルがデプロイされる環境とまったく同じ(つまり、Pythonとすべてのライブラリのバージョンが同じ)でなければなりません。詳細については、 モデルバージョンの読み込み をご参照ください。
mv_old = reg.get_model("model_without_explain_enabled").default
model = mv_old.load()
mv_new = reg.log_model(
model,
model_name="model_with_explain_enabled",
version_name="explain_v0",
conda_dependencies=["snowflake-ml-python"],
sample_input_data = xs
)
説明可能性のないログ・モデル¶
モデルがサポートしていれば、説明可能性はデフォルトで有効になります。説明可能性のないモデルのバージョンをレジストリに記録するには、ここに示されているように、モデルにログをする時に enable_explainability
オプションに False
を渡します。
mv = reg.log_model(
catboost_model,
model_name="diamond_catboost_explain_enabled",
version_name="explain_v0",
conda_dependencies=["snowflake-ml-python"],
sample_input_data = xs,
options= {"enable_explainability": False}
)