使用 Python 可解譯性套件說明 ML 模型與預測 (預覽)
在本操作指南中,您將了解如何使用 Azure Machine Learning Python SDK 的可解譯性套件來執行下列工作:
說明整個模型行為或您個人電腦本機的個別預測。
為工程設計特徵啟用可解譯性技術。
說明整個模型的行為及 Azure 中的個別預測。
將說明上傳至 Azure Machine Learning 執行歷程記錄。
在 Jupyter Notebook 和 Azure Machine Learning 工作室中,使用視覺效果儀表板與您的模型說明互動。
將評分說明程式與您的模型一起部署,以觀察推斷期間的說明。
重要
此功能目前處於公開預覽。 此預覽版本沒有服務等級協定,不建議用於處理生產工作負載。 可能不支援特定功能,或可能已經限制功能。
如需詳細資訊,請參閱 Microsoft Azure 預覽版增補使用條款。
如需支援的可解譯性技術和機器學習模型詳細資訊,請參閱 Azure Machine Learning 中的模型可解譯性和範例筆記本 (英文)。
如需如何為使用自動化機器學習訓練的模型啟用可解譯性的指引,請參閱可解譯性:自動化機器學習模型的模型說明 (預覽)。
在個人電腦上產生特徵重要度值
下列範例顯示如何在個人電腦上使用可解譯性套件,而不需要連絡 Azure 服務。
安裝
azureml-interpret
套件。pip install azureml-interpret
在本機 Jupyter Notebook 中訓練範例模型。
# load breast cancer dataset, a well-known small dataset that comes with scikit-learn from sklearn.datasets import load_breast_cancer from sklearn import svm from sklearn.model_selection import train_test_split breast_cancer_data = load_breast_cancer() classes = breast_cancer_data.target_names.tolist() # split data into train and test from sklearn.model_selection import train_test_split x_train, x_test, y_train, y_test = train_test_split(breast_cancer_data.data, breast_cancer_data.target, test_size=0.2, random_state=0) clf = svm.SVC(gamma=0.001, C=100., probability=True) model = clf.fit(x_train, y_train)
在本機呼叫說明程式。
- 若要初始化說明程式物件,請將模型和一些訓練資料傳遞給說明程式的建構函式。
- 為了讓說明和視覺效果更具資訊性,您可以選擇在執行分類時傳遞特徵名稱和輸出類別名稱。
下列程式碼區塊顯示如何在本機使用
TabularExplainer
、MimicExplainer
和PFIExplainer
將說明程式物件具現化。TabularExplainer
呼叫底下三個 SHAP 說明程式的其中一個 (TreeExplainer
、DeepExplainer
或KernelExplainer
)。TabularExplainer
會自動為您的使用案例選取最適當的說明程式,但您可以直接個別呼叫這三個基礎說明程式。
from interpret.ext.blackbox import TabularExplainer # "features" and "classes" fields are optional explainer = TabularExplainer(model, x_train, features=breast_cancer_data.feature_names, classes=classes)
或
from interpret.ext.blackbox import MimicExplainer # you can use one of the following four interpretable models as a global surrogate to the black box model from interpret.ext.glassbox import LGBMExplainableModel from interpret.ext.glassbox import LinearExplainableModel from interpret.ext.glassbox import SGDExplainableModel from interpret.ext.glassbox import DecisionTreeExplainableModel # "features" and "classes" fields are optional # augment_data is optional and if true, oversamples the initialization examples to improve surrogate model accuracy to fit original model. Useful for high-dimensional data where the number of rows is less than the number of columns. # max_num_of_augmentations is optional and defines max number of times we can increase the input data size. # LGBMExplainableModel can be replaced with LinearExplainableModel, SGDExplainableModel, or DecisionTreeExplainableModel explainer = MimicExplainer(model, x_train, LGBMExplainableModel, augment_data=True, max_num_of_augmentations=10, features=breast_cancer_data.feature_names, classes=classes)
或
from interpret.ext.blackbox import PFIExplainer # "features" and "classes" fields are optional explainer = PFIExplainer(model, features=breast_cancer_data.feature_names, classes=classes)
說明整個模型行為 (全域說明)
請參閱下列範例,以協助您取得彙總 (全域) 特徵重要度值。
# you can use the training data or the test data here, but test data would allow you to use Explanation Exploration
global_explanation = explainer.explain_global(x_test)
# if you used the PFIExplainer in the previous step, use the next line of code instead
# global_explanation = explainer.explain_global(x_train, true_labels=y_train)
# sorted feature importance values and feature names
sorted_global_importance_values = global_explanation.get_ranked_global_values()
sorted_global_importance_names = global_explanation.get_ranked_global_names()
dict(zip(sorted_global_importance_names, sorted_global_importance_values))
# alternatively, you can print out a dictionary that holds the top K feature names and values
global_explanation.get_feature_importance_dict()
說明個別預測 (本機說明)
呼叫一個執行個體或一組執行個體的說明,以取得不同資料點的個別特徵重要度值。
注意
PFIExplainer
不支援本機說明。
# get explanation for the first data point in the test set
local_explanation = explainer.explain_local(x_test[0:5])
# sorted feature importance values and feature names
sorted_local_importance_names = local_explanation.get_ranked_local_names()
sorted_local_importance_values = local_explanation.get_ranked_local_values()
原始特徵轉換
您可以選擇取得原始未轉換特徵的說明,而不是工程設計特徵。 如需此選項,請將特徵轉換管線傳遞至 train_explain.py
中的說明程式。 否則,說明程式會提供工程設計特徵的說明。
支援的轉換格式與 sklearn-pandas 中所述的格式相同。 一般而言,支援任何轉換,只要這些轉換是在單一資料行上運作,因此明確是一對多。
使用 sklearn.compose.ColumnTransformer
或透過擬合轉換器 Tuple 清單來取得原始特徵的說明。 下列範例會使用 sklearn.compose.ColumnTransformer
。
from sklearn.compose import ColumnTransformer
numeric_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='median')),
('scaler', StandardScaler())])
categorical_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='constant', fill_value='missing')),
('onehot', OneHotEncoder(handle_unknown='ignore'))])
preprocessor = ColumnTransformer(
transformers=[
('num', numeric_transformer, numeric_features),
('cat', categorical_transformer, categorical_features)])
# append classifier to preprocessing pipeline.
# now we have a full prediction pipeline.
clf = Pipeline(steps=[('preprocessor', preprocessor),
('classifier', LogisticRegression(solver='lbfgs'))])
# clf.steps[-1][1] returns the trained classification model
# pass transformation as an input to create the explanation object
# "features" and "classes" fields are optional
tabular_explainer = TabularExplainer(clf.steps[-1][1],
initialization_examples=x_train,
features=dataset_feature_names,
classes=dataset_classes,
transformations=preprocessor)
如果您想要透過擬合轉換器 Tuple 清單來執行此範例,請使用下列程式碼:
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.linear_model import LogisticRegression
from sklearn_pandas import DataFrameMapper
# assume that we have created two arrays, numerical and categorical, which holds the numerical and categorical feature names
numeric_transformations = [([f], Pipeline(steps=[('imputer', SimpleImputer(
strategy='median')), ('scaler', StandardScaler())])) for f in numerical]
categorical_transformations = [([f], OneHotEncoder(
handle_unknown='ignore', sparse=False)) for f in categorical]
transformations = numeric_transformations + categorical_transformations
# append model to preprocessing pipeline.
# now we have a full prediction pipeline.
clf = Pipeline(steps=[('preprocessor', DataFrameMapper(transformations)),
('classifier', LogisticRegression(solver='lbfgs'))])
# clf.steps[-1][1] returns the trained classification model
# pass transformation as an input to create the explanation object
# "features" and "classes" fields are optional
tabular_explainer = TabularExplainer(clf.steps[-1][1],
initialization_examples=x_train,
features=dataset_feature_names,
classes=dataset_classes,
transformations=transformations)
透過遠端執行產生特徵重要度值
下列範例顯示如何使用 ExplanationClient
類別,為遠端執行啟用模型可解譯性。 其在概念上類似於本機處理序,但您需要執行下列動作:
- 在遠端執行中使用
ExplanationClient
來上傳可解譯性內容。 - 稍後在本機環境中下載內容。
安裝
azureml-interpret
套件。pip install azureml-interpret
在本機 Jupyter Notebook 中建立訓練指令碼。 例如:
train_explain.py
。from azureml.interpret import ExplanationClient from azureml.core.run import Run from interpret.ext.blackbox import TabularExplainer run = Run.get_context() client = ExplanationClient.from_run(run) # write code to get and split your data into train and test sets here # write code to train your model here # explain predictions on your local machine # "features" and "classes" fields are optional explainer = TabularExplainer(model, x_train, features=feature_names, classes=classes) # explain overall model predictions (global explanation) global_explanation = explainer.explain_global(x_test) # uploading global model explanation data for storage or visualization in webUX # the explanation can then be downloaded on any compute # multiple explanations can be uploaded client.upload_model_explanation(global_explanation, comment='global explanation: all features') # or you can only upload the explanation object with the top k feature info #client.upload_model_explanation(global_explanation, top_k=2, comment='global explanation: Only top 2 features')
將 Azure Machine Learning Compute 設定為您的計算目標,並提交訓練執行。 如需指示,請參閱建立和管理 Azure Machine Learning 計算叢集。 您也可能會發現範例筆記本很有幫助。
在本機 Jupyter Notebook 中下載說明。
from azureml.interpret import ExplanationClient client = ExplanationClient.from_run(run) # get model explanation data explanation = client.download_model_explanation() # or only get the top k (e.g., 4) most important features with their importance values explanation = client.download_model_explanation(top_k=4) global_importance_values = explanation.get_ranked_global_values() global_importance_names = explanation.get_ranked_global_names() print('global importance values: {}'.format(global_importance_values)) print('global importance names: {}'.format(global_importance_names))
視覺效果
當在本機 Jupyter Notebook 中下載說明之後,您可以使用說明儀表板中的視覺效果來了解及解譯模型。 若要在 Jupyter Notebook 中載入說明儀表板 Widget,請使用下列程式碼:
from raiwidgets import ExplanationDashboard
ExplanationDashboard(global_explanation, model, datasetX=x_test)
視覺效果同時支援工程設計特徵和原始特徵的說明。 原始說明是根據原始資料集中的特徵,而工程設計說明則是根據資料集中已套用特徵工程的特徵。
當嘗試根據原始資料集解譯模型時,建議使用原始說明,因為每個特徵重要度會對應至原始資料集中的一個資料行。 一個工程設計說明可能很有用的案例,就是在查看一項類別特徵中個別類別的影響時。 如果對一項類別特徵套用了 One-hot 編碼,則產生的工程設計說明針對每個類別會包含不同的重要度值,而且每個 One-hot 工程特徵會有一個值。 當縮小資料集對模型最具資訊性的部分時,這種編碼可能會很有用。
注意
工程設計說明和原始說明會依序計算。 首先會根據模型和特徵化管線建立工程設計說明。 然後會透過彙總來自相同原始特徵的工程設計特徵重要度,根據該工程設計說明來建立原始說明。
建立、編輯和檢視資料集世代
頂端功能區會顯示模型和資料的整體統計資料。 您可以將資料分割成資料集世代或子群組,以便在這些定義的子群組之間調查或比較模型的效能和說明。 透過在這些子群組之間比較資料集統計資料和說明,您即可了解為什麼在某個群組中可能發生錯誤,而不是另一個群組。
了解整個模型行為 (全域說明)
說明儀表板的前三個索引標籤會提供訓練模型的整體分析,以及其預測和說明。
模型效能
透過探索預測值和模型效能計量值的分佈來評估模型的效能。 您可以在資料集的不同世代或子群組之間查看模型效能的比較分析,進一步調查您的模型。 在 Y 值和 X 值上選取篩選,以依不同的維度進行切割。 您可以檢視準確度、精確度、重新叫用、誤判為真率 (FPR) 和誤判為否率 (FNR) 等計量。
資料集總管
在 X、Y 和色軸上選取不同的篩選來探索資料集統計資料,以依不同的維度分割資料。 在上方建立資料集世代,以使用篩選 (例如預測的結果、資料集特徵和錯誤群組) 來分析資料集統計資料。 使用圖表右上角的齒輪圖示即可變更圖表類型。
彙總特徵重要度
探索影響整體模型預測 (也稱為全域說明) 的前 K 個重要特徵。 使用滑桿以遞減順序顯示特徵重要度值。 最多可選取三個世代來並排查看其特徵重要度值。 選取圖表中的任何特徵列,即可查看所選特徵的值如何影響下列相依性關係圖中的模型預測值。
了解個別預測 (本機說明)
[說明] 索引標籤的第四個索引標籤可讓您切入個別資料點及其個別特徵重要度。 您可以按一下主要散佈圖中的任何個別資料點,或在右側面板精靈中選取特定點,針對任何資料點載入個別特徵重要度圖。
繪圖 | 描述 |
---|---|
個別特徵重要度 | 顯示個別預測的前 K 個重要特徵。 這有助於說明特定資料點上基礎模型的本機行為。 |
假設狀況分析 | 允許對所選實際資料點的特徵值進行變更,並透過使用新特徵值產生假設的資料點來觀察對預測值所產生的變更。 |
個體條件期望 (ICE) | 允許將特徵值從最小值變更為最大值。 這有助於說明資料點的預測如何隨著特徵變更而變更。 |
注意
這些是根據許多近似值的說明,而不是預測的「原因」。 由於沒有原因推斷的嚴格數學強大功能,因此不建議使用者根據模擬分析工具的特徵擾動做出實際的決策。 這項工具主要是用來了解模型和進行偵錯。
Azure Machine Learning 工作室中的視覺效果
如果您完成了遠端可解譯性步驟 (將產生的說明上傳至 Azure Machine Learning 執行歷程記錄),即可在 Azure Machine Learning 工作室中的說明儀表板上檢視視覺效果。 此儀表板是在 Jupyter Notebook 中所產生較簡單的儀表板 Widget 版本。 模擬分析資料點產生和 ICE 圖已停用,因為 Azure Machine Learning 工作室中沒有可執行即時計算的使用中計算。
如果有可用的資料集、全域和本機說明,資料就會填入所有的索引標籤。 不過,如果只有全域說明可用,則會停用 [個別特徵重要度] 索引標籤。
透過下列其中一個路徑存取 Azure Machine Learning 工作室中的說明儀表板:
[實驗] 窗格 (預覽)
- 在左窗格中選取 [實驗],以查看您在 Azure Machine Learning 上執行的實驗清單。
- 選取特定實驗,即可檢視該實驗中的所有執行。
- 選取某個執行,然後選取 [說明] 索引標籤,以檢視說明視覺效果儀表板。
[模型] 窗格
- 如果您已遵循使用 Azure Machine Learning 部署模型中的步驟註冊原始模型,則可以在左窗格中選取 [模型] 進行檢視。
- 選取一個模型,然後選取 [說明] 索引標籤以檢視說明儀表板。
推斷階段的可解譯性
您可以將說明程式與原始模型一起部署,並在推斷階段用來為任何新資料點提供個別特徵重要度值 (本機說明)。 我們也提供較輕量型的評分說明程式來提升推斷階段的可解譯性效能。目前只有在 Azure Machine Learning SDK 中才提供支援。 部署較輕量型評分說明程式的程序類似於部署模型,並包含下列步驟:
建立說明物件。 例如,您可以使用
TabularExplainer
:from interpret.ext.blackbox import TabularExplainer explainer = TabularExplainer(model, initialization_examples=x_train, features=dataset_feature_names, classes=dataset_classes, transformations=transformations)
使用說明物件建立評分說明程式。
from azureml.interpret.scoring.scoring_explainer import KernelScoringExplainer, save # create a lightweight explainer at scoring time scoring_explainer = KernelScoringExplainer(explainer) # pickle scoring explainer # pickle scoring explainer locally OUTPUT_DIR = 'my_directory' save(scoring_explainer, directory=OUTPUT_DIR, exist_ok=True)
設定並註冊使用評分說明程式模型的映像。
# register explainer model using the path from ScoringExplainer.save - could be done on remote compute # scoring_explainer.pkl is the filename on disk, while my_scoring_explainer.pkl will be the filename in cloud storage run.upload_file('my_scoring_explainer.pkl', os.path.join(OUTPUT_DIR, 'scoring_explainer.pkl')) scoring_explainer_model = run.register_model(model_name='my_scoring_explainer', model_path='my_scoring_explainer.pkl') print(scoring_explainer_model.name, scoring_explainer_model.id, scoring_explainer_model.version, sep = '\t')
(選擇性步驟) 您可以從雲端擷取評分說明程式並測試說明。
from azureml.interpret.scoring.scoring_explainer import load # retrieve the scoring explainer model from cloud" scoring_explainer_model = Model(ws, 'my_scoring_explainer') scoring_explainer_model_path = scoring_explainer_model.download(target_dir=os.getcwd(), exist_ok=True) # load scoring explainer from disk scoring_explainer = load(scoring_explainer_model_path) # test scoring explainer locally preds = scoring_explainer.explain(x_test) print(preds)
遵循下列步驟,將映像部署到計算目標:
如有需要,請遵循使用 Azure Machine Learning 部署模型中的步驟來註冊您的原始預測模型。
建立評分檔案。
%%writefile score.py import json import numpy as np import pandas as pd import os import pickle from sklearn.externals import joblib from sklearn.linear_model import LogisticRegression from azureml.core.model import Model def init(): global original_model global scoring_model # retrieve the path to the model file using the model name # assume original model is named original_prediction_model original_model_path = Model.get_model_path('original_prediction_model') scoring_explainer_path = Model.get_model_path('my_scoring_explainer') original_model = joblib.load(original_model_path) scoring_explainer = joblib.load(scoring_explainer_path) def run(raw_data): # get predictions and explanations for each data point data = pd.read_json(raw_data) # make prediction predictions = original_model.predict(data) # retrieve model explanations local_importance_values = scoring_explainer.explain(data) # you can return any data type as long as it is JSON-serializable return {'predictions': predictions.tolist(), 'local_importance_values': local_importance_values}
定義部署設定。
此設定取決於您模型的需求。 下列範例會定義一個設定來使用一個 CPU 核心和 1 GB 的記憶體。
from azureml.core.webservice import AciWebservice aciconfig = AciWebservice.deploy_configuration(cpu_cores=1, memory_gb=1, tags={"data": "NAME_OF_THE_DATASET", "method" : "local_explanation"}, description='Get local explanations for NAME_OF_THE_PROBLEM')
建立具有環境相依性的檔案。
from azureml.core.conda_dependencies import CondaDependencies # WARNING: to install this, g++ needs to be available on the Docker image and is not by default (look at the next cell) azureml_pip_packages = ['azureml-defaults', 'azureml-core', 'azureml-telemetry', 'azureml-interpret'] # specify CondaDependencies obj myenv = CondaDependencies.create(conda_packages=['scikit-learn', 'pandas'], pip_packages=['sklearn-pandas'] + azureml_pip_packages, pin_sdk_version=False) with open("myenv.yml","w") as f: f.write(myenv.serialize_to_string()) with open("myenv.yml","r") as f: print(f.read())
建立已安裝 g++ 的自訂 Dockerfile。
%%writefile dockerfile RUN apt-get update && apt-get install -y g++
部署建立的映像。
此程序需要大約五分鐘才能完成。
from azureml.core.webservice import Webservice from azureml.core.image import ContainerImage # use the custom scoring, docker, and conda files we created above image_config = ContainerImage.image_configuration(execution_script="score.py", docker_file="dockerfile", runtime="python", conda_file="myenv.yml") # use configs and models generated above service = Webservice.deploy_from_model(workspace=ws, name='model-scoring-service', deployment_config=aciconfig, models=[scoring_explainer_model, original_model], image_config=image_config) service.wait_for_deployment(show_output=True)
測試部署。
import requests # create data to test service with examples = x_list[:4] input_data = examples.to_json() headers = {'Content-Type':'application/json'} # send request to service resp = requests.post(service.scoring_uri, input_data, headers=headers) print("POST to url", service.scoring_uri) # can covert back to Python objects from json string if desired print("prediction:", resp.text)
清除。
若要刪除已部署的 Web 服務,請使用
service.delete()
。
疑難排解
不支援疏鬆資料:具有大量特徵的模型說明儀表板會中斷/大幅變慢,因此我們目前不支援疏鬆資料格式。 此外,大型資料集和大量特徵也會發生一般記憶體問題。
支援的說明特徵矩陣
支援的說明索引標籤 | 原始特徵 (密集) | 原始特徵 (疏鬆) | 工程設計特徵 (密集) | 工程設計特徵 (疏鬆) |
---|---|---|---|---|
模型效能 | 支援 (不會預測) | 支援 (不會預測) | 支援 | 支援 |
資料集總管 | 支援 (不會預測) | 不支援。 因為未上傳稀疏資料,而且 UI 在轉譯疏鬆資料時發生問題。 | 支援 | 不支援。 因為未上傳稀疏資料,而且 UI 在轉譯疏鬆資料時發生問題。 |
彙總特徵重要度 | 支援 | 支援 | 支援 | 支援 |
個別特徵重要度 | 支援 (不會預測) | 不支援。 因為未上傳稀疏資料,而且 UI 在轉譯疏鬆資料時發生問題。 | 支援 | 不支援。 因為未上傳稀疏資料,而且 UI 在轉譯疏鬆資料時發生問題。 |
不支援具有模型說明的預測模型:AutoML 預測演算法無法使用可解譯性、最佳模型說明來建議下列演算法作為最佳模型:TCNForecaster、AutoArima、Prophet、ExponentialSmoothing、Average、Naive、Seasonal Average 和 Seasonal Naive。 AutoML 預測迴歸模型支援說明。 不過,在說明儀表板中,由於資料管線中的複雜性,因此不支援使用 [個別特徵重要度] 索引標籤進行預測。
資料索引的本機說明:當儀表板隨機縮小資料取樣時,如果資料集超過 5000 個資料點,則說明儀表板不支援將本機重要度值與原始驗證資料集中的資料列識別碼相關聯。 不過,儀表板會顯示每個傳入儀表板之 [個別特徵重要性] 索引標籤下之資料點的原始資料集特徵值。使用者可以透過比對原始資料集特徵值,將本機重要性對應回原始資料集。 如果驗證資料集大小小於 5000 個樣本,則 Azure Machine Learning 工作室中的
index
特徵會對應至驗證資料集中的索引。工作室不支援模擬分析/ICE 圖:Azure Machine Learning 工作室的 [說明] 索引標籤下不支援模擬分析和個體條件期望 (ICE) 圖,因為上傳的說明需要使用中計算才能重新計算預測和受干擾的特徵機率。 目前支援使用 SDK 作為 Widget 執行的 Jupyter 筆記本。