SHAP值:解释机器学习模型的有效方法
许多人说机器学习模型是“黑匣子”,从某种意义上说它们可以做出很好的预测,但你无法理解这些预测背后的逻辑。在大多数数据科学家不知道如何从机器学习模型中提取见解的意义上,这种说法是正确的。
要理解为什么这很重要,我们需要仔细研究机器学习模型准确性和可解释性的概念。直到最近,我们总是必须在难以解释的精确模型(深度学习模型)或易于解释但牺牲一些准确性(逻辑回归模型)的简单模型之间进行选择。
在准确性和可解释性之间取得正确的权衡可能是一个困难的平衡行为。有了SHAP值,我们终于可以同时得到这两者了!
SHAP值(SHapley Additive exPlanations)分解预测以显示每个特征的影响。游戏理论中使用的一种技术,用于确定协作游戏中每个玩家对其成功的贡献程度。换句话说,每个SHAP值测量我们模型中每个特征对每个预测的正面或负面贡献的程度。
SHAP值实践
为了更好地理解我们正在谈论的内容,我们将按照上图并将SHAP值应用于FIFA 2018 Statistics(https://www.kaggle.com/mathan/fifa-2018-match-statistics#FIFA%202018%20Statistics.csv),并尝试通过使用诸如'Ball Possession'和'Distance Covered'之类的特征来了解哪支球队的球员有更多的机会赢得比赛中的最佳球员。
首先,我们将导入Python库,加载数据并拟合林随机回归器。
import numpy as np import pandas as pd from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier data = pd.read_csv('FIFA 2018 Statistics.csv') y = (data['Man of the Match'] == "Yes") # Convert from string "Yes"/"No" to binary feature_names = [i for i in data.columns if data[i].dtype in [np.int64, np.int64]] X = data[feature_names] train_X, val_X, train_y, val_y = train_test_split(X, y, random_state=1) model = RandomForestClassifier(random_state=0).fit(train_X, train_y)
然后我们将计算SHAP值和两个球队的预测概率:Team_A和Team_B。Python代码如下:
import shap # package used to calculate Shap values Team_A = 5 Team_B = 7 data_for_prediction_A = val_X.iloc[Team_A] data_for_prediction_array_A = data_for_prediction_A.values.reshape(1, -1) data_for_prediction_B = val_X.iloc[Team_B] data_for_prediction_array_B = data_for_prediction_B.values.reshape(1, -1) # Create object that can calculate shap values explainer = shap.TreeExplainer(model) # Calculate Shap values for team_A and team_B shap_values_A = explainer.shap_values(data_for_prediction_A) shap_values_B = explainer.shap_values(data_for_prediction_B) # predicted probabilities for each outcome prob_A = my_model.predict_proba(data_for_prediction_array_A) prob_B = my_model.predict_proba(data_for_prediction_array_B) print('prob to choose the man of the match from Team_A: ',prob_A) print('prob to choose the man of the match from Team_B: ',prob_B) ################################################## prob to choose the man of the match from Team_A: [[ 0.3 0.7]] prob to choose the man of the match from Team_B: [[ 0.4 0.6]]
A队和B队都有可能有一名球员获得该奖。因为他们都有很高的概率70%和60%来赢得比赛。
现在让我们看看它们是否具有导致上述结果的相同features_importance。shap包有一个很好的方法来可视化结果。Python代码如下:
# SHAP Value visualization for team A shap.initjs() shap.force_plot(explainer.expected_value[1], shap_values_A[1], data_for_prediction_A) # SHAP Value visualization for team B shap.force_plot(explainer.expected_value[1], shap_values_B[1], data_for_prediction_B)
上图显示了每个特征将模型输出从base value(我们传递的训练数据集上的平均模型输出)push到模型输出的贡献。促使预测更高的特征以红色显示,促使预测更低的特征以蓝色显示。
让我们比较两个图:
对于Team_A(第一张图)来说,推动比赛获胜的主要因素是“Ball Possession”和“Offsides”。因此,推动比赛获胜机会的球员是“Goal Scored”和“‘On-Target’”。
对于Team_B(第二张图)来说,推动比赛获胜机会下降的主要驱动因素是“Goal Scored”和“Distance Covered”。因此,推动比赛获胜机会的球员是“Ball Possession”和“Attempts”。
我们现在可以看到“Ball Possession”这个特征扮演不同的角色,在Team_A中增加了机会,而在Team_B中减少了赢得比赛的机会。
这意味着每个球队都有自己的一组SHAP值。传统的特征重要性算法将告诉我们哪些特征在整个种群中最重要,但这种一刀切的方法并不总是适用于每个球队。一个特征对于一个团队来说是增加或减少进球机会的一个重要的特征,对于另一个团队来说可能不是。