可解释性机器学习:从入门到实战
文章目录
- 一、可解释的特性:
- 1.1 可解释的重要性:
- 1.2 可解释性的范围:
- 1.2.1. 算法透明度(Algorithm Transparency):*
- 1.2.2 全局可解释(Global Interpretability):
- 1.2.3 局部可解释(Local Interpretability):
- 二、与模型无关的方法:
- 2.1 Permutation Feature Importance:
- 2.1.1 实例:
- 2.2 Partial Dependency Plots:
- 2.2.1 优缺点:
- 2.2.2 实例:
- 2.3 ICE(Individual Conditional Expectation):
- 2.4 LIME:
- 2.4.1 可解释性和性能的平衡:
- 2.4.2 LIME分析步骤:
- 2.4.3 优缺点:
- 2.4.4 实例:
- 2.5 SHAP(SHapley Additive exPlanation):
- 2.5.1 shapley值:
- 2.5.2 优缺点:
- 2.5.3 实例:
- 三、其他方法:
- 3.1 Interpret:
- 3.1.1 GAMS:
- 3.2 非事实解释(Counterfactual Explanations):
- 参考资料
一、可解释的特性:
目前人工智能应用已经渗透到我们生活的方方面面,成为我们生活中重要的一部分。我们相信,随着机器学习技术的不断进步,未来,有望产生一个能够感知,学习,做出决策和采取独立行动自主系统。 但是,如果这些系统无法向人类解释为何作出这样的决策,那么它们的有效性将会受到限制。用户要理解,信任和管理这些人工智能”合作伙伴“,可解释AI则至关重要。
1.1 可解释的重要性:
模型改进:
通过可解释分析,可以指导特征工程。一般我们会根据一些专业知识和经验来做特征,同构分析特征重要性,可以挖掘更多有用的特征,尤其是在交互特征方面。当原始特征众多时,可解释性分析将特别重要。
在做机器学习任务时,我们一般会选择一个指标,比如准确率,然后尽可能优化。假设在一个文本分类任务中,判断文章是与“基督教”(Christianity)有关还是“无神论教”(Atheism)”,模型准确率,90%多,很高了。但是用LIME进行可解释分析发现,Posting(邮件标头的一部分)这个词重要性很高,但这个词汇与无神论本身并没有太多的联系,只是因为在无神论文章中出现的频次很高。这意味着尽管模型准确率很高,但所使用的原因是错误的。我们可以借此来改进模型,是否捕捉到了有意义的特征,以提高泛化性。
模型的可信和透明度:
在我们做型的时候,需要在两个方面之间进行权衡,仅仅想要知道预测是什么,还是要知道模型为什么要给出这样的预测。在一些低风险的情况下,不一定要知道决策是如何做出的,比如推荐系统,广告、视频或者商品推荐等。但是在其他领域,比如在金融和医疗领域,模型的预测结果将会对相关的人产生巨大的影响,有时候我们依然需要专家对结果进行解释。解释为什么一个机器学习模型将某个患者的肿瘤归类为良性或恶性,解释为什么模型会拒绝一个人的贷款申请,这样,专家更有可能信任机器学习模型给出的预测结果。
长久来看,更好地理解机器学习模型可以节省大量时间、防止收入损失。如果一个模型没有做出合理的决定,在应用这个模型并造成不良影响之前,我们就可以发现这一点。
我们在面对客户的时候,他们会问 ”我为什么要相信你的模型“。如果客户不相信模型和预测结果,就无法使用这个模型,将其部署在产品中。识别和防止偏差:
方差和偏差是机器学习中广泛讨论的话题。有偏差的模型经常由有偏见的事实导致,如果数据包含微妙的偏差,模型就会学习下来并认为拟合很好。一个有名的例子是,用机器学习模型来为囚犯建议定罪量刑,这显然反映了司法体系在种族不平等上的内在偏差。其他例子比如用于招聘的机器学习模型,揭示了在特定职位上的性别偏差,比如男性软件工程师和女性护士。机器学习模型在我们生活的各个层面上都是强有力的工具,而且它也会变得越来越流行。所以作为数据科学家和决策制定者来说,理解我们训练和发布的模型如何做出决策,让我们可以事先预防偏差的增大以及消除他们,是我们的责任。
1.2 可解释性的范围:
1.2.1. 算法透明度(Algorithm Transparency):*
How does the algorithm create the model?
算法透明度指的是,如何从数据中学习一个模型,更加强调模型的构建方式以及影响决策的技术细节。比如CNN来对图片进行分类时,模型做出预测,是因为算法学习到了边或者其他纹理。算法透明度需要弄懂算法知识而不是数据以及学到的模型。对于简单的算法,比如线性模型,具有非常高的算法透明度。复杂的模型如深度学习,人们对模型内部了解较少,透明度较差,这将非常重要的一个研究方向。由于业务可能不太精通这些技术细节,本文集中于模型的全局和局部可解释性,而不是算法的可解释性(透明度)。
1.2.2 全局可解释(Global Interpretability):
How does the trained model make predictions?
为了解释模型的全局输出,需要训练模型了解算法和数据。这个层级的可解释性指的是,模型如何基于整个特征空间和模型结构、参数等作出决策的。什么特征是重要的,特征交互会发生什么。模型的全局可解释性可以帮助理解,针对不同特征,目标变量的分布是什么。实际在,模型具有大量参数的情况下,人们很难想象 特征之间是如何相互作用的,以得到这样的预测结果。
某些模型在这个层级是可以解释的。例如线性模型的权重是可以解释的,树模型如何划分分支和如何得到结点预测值是可以解释的。
1.2.3 局部可解释(Local Interpretability):
Why did the model make a certain prediction for an/a group of instance?
局部可解释性更加关注单条样本或一组样本。这种情况下我们可以将模型看做是一个黑盒,不再考虑模型的复杂情况。单条样本来看,模型给出的预测值和某些特征可能是线性关系,甚至是单调关系。因此局不可解释性可能相比全局可解释,更加准确点。
二、与模型无关的方法:
获得可解释性的一个非常容易的方法是使用一系列可解释的模型,比如线性回归,逻辑回归,决策树等。这些模型已经有很多文章详细解释,本文不再介绍,以与模型无关的方法为主。与模型无关也就是可以适用于任何模型,和模型的内部结构无关。
2.1 Permutation Feature Importance:
Permutation Importance是一种计算模型特征重要性的算法。特征重要性是指,一个特征对预测的贡献有多大。某些模型,例如LR、决策树,lightgbm等模型可以直接计算特征重要性。
基本思想:
假设要研究特征iii的重要性,那么将这列数据打乱,其他列的数据保持不变,然后观察预测的metric(eg.准确率)或者loss变化了多少,根据变化量来决定特征重要性。如果打乱以后对准确率没什么影响的话,可以认为这个特征没什么作用,特征重要性很低。
2.1.1 实例:
1. 读取数据预测每个人的年收入:
使用的数据集从1994年的人口普查局数据库中提取。根据人的一些基本信息来预测一个人每年的收入是否超过5万美元。数据的下载链接。
feature_names = ["Age", "Workclass", "fnlwgt", "Education", "Education-Num", "Marital Status","Occupation", "Relationship", "Race", "Sex", "Capital Gain", "Capital Loss","Hours per week", "Country"]
data = np.genfromtxt('adult.data', delimiter=', ', dtype=str)
data = pd.DataFrame(data, columns=feature_names+['label'])
2. 数据预处理:
labels = data.iloc[:,14]
le= LabelEncoder()
le.fit(labels)
labels = le.transform(labels)
class_names = le.classes_
# data = data[:,:-1]categorical_features = [1,3,5, 6,7,8,9,13]categorical_names = {}
for feature in categorical_features:le = LabelEncoder()le.fit(data.iloc[:, feature])data.iloc[:, feature] = le.transform(data.iloc[:, feature])categorical_names[feature] = le.classes_data[feature_names] = data[feature_names].astype(float)
encoder = OneHotEncoder(categorical_features=categorical_features)
3. 训练XGBoost模型以及XGB的特征重要性:
np.random.seed(1)
train, test, labels_train, labels_test = sklearn.model_selection.train_test_split(data[feature_names], labels, train_size=0.80)# encoder.fit(data)
# encoded_train = encoder.transform(train)
# encoded_test = encoder.transform(test)gbtree = xgb.XGBClassifier(n_estimators=2000, max_depth=4, learning_rate=0.05, n_jobs=8)
gbtree.fit(train, labels_train,eval_set=[(test, labels_test)], eval_metric='auc', verbose=100, early_stopping_rounds=100)
4. Permutation Feature Importance-slearn:
from sklearn.inspection import permutation_importance
result = permutation_importance(clf, train_x, train_y, n_repeats=10,random_state=42)
featImp = pd.DataFrame()
featImp['feat'] = feature_names
featImp['importance'] = result.importances_mean
featImp = featImp.sort_values('importance',ascending = False)plt.figure(figsize=[20,10])
sns.barplot(x = 'importance', y = 'feat',data = featImp[:20],orient='h')
plt.show
从上述两个重要性可以看出,xgb自带的特征重要性和Permutation Importance求出的有所差异,可以综合的生成特征重要性,辅助特征选择。如果Permutation Feature Importance是负的,说明扰乱以后预测效果反而提升了,这种特征应该删除,其他较小的可以删除。
5. Permutation Feature Importance-eli5:
import eli5
from eli5.sklearn import PermutationImportance
perm = PermutationImportance(clf, n_iter=10)
perm.fit(train_x, train_y)
eli5.show_weights(perm, feature_names=train_x.columns.tolist())
eli5求出的结果和sklearn给出的实现基本一样,后面的几个特征的重要性稍微有些差异,说明这种方法的稳定性还是可靠的。
2.2 Partial Dependency Plots:
通过permutation importance可以得到特征的重要性,但是不知道不同的特征值如何影响预测结果的。PDP可以求得特征和预测结果的关系。
部分依赖图(Partial Dependency Plots-PDP)展示的是,对一个机器学习模型,一个或者两个特征的边际效应。由PDP我们可以得到目标值(target)和特征的关系,是线性、单调还是更复杂的关系。如果线性模型,特征和目标值之间则是线性关系。PDP的计算需要满足一个假设,所有的特征,是两两不相关的,如果相关就会出现问题,见PDP的缺点部分。
回归问题的部分依赖函数:
f^xS(xS)=ExC[f^(xS,xC)]=∫f^(xS,xC)dP(xC)\hat{f}_{x_{S}}\left(x_{S}\right)=E_{x_{C}}\left[\hat{f}\left(x_{S}, x_{C}\right)\right]=\int \hat{f}\left(x_{S}, x_{C}\right) d \mathbb{P}\left(x_{C}\right) f^xS(xS)=ExC[f^(xS,xC)]=∫f^(xS,xC)dP(xC)
- xSx_SxS:PDP所需要绘制的特征;
- xCx_CxC:模型中使用的其他特征;
其实上述式子,便是一个连续分布边际概率的求解公式。我们可以通过Monte Carlo方法在训练集上得到估计值,求特征xCx_CxC对预测的影响:
f^xS(xS)=1n∑i=1nf^(xS,xC(i))\hat{f}_{x_{S}}\left(x_{S}\right)=\frac{1}{n} \sum_{i=1}^{n} \hat{f}\left(x_{S}, x_{C}^{(i)}\right) f^xS(xS)=n1i=1∑nf^(xS,xC(i))
PDP分析步骤:
- 训练一个机器学习模型(假设特征是F1…F4F_1 … F_4F1…F4,yyy是目标变量,F1F_1F1是最重要的特征);
- 我们想探索探索yyy和F1F_1F1的直接关系,F1F_1F1的取值是(a1,a2,a3,...,an)(a_1, a_2, a_3,...,a_n)(a1,a2,a3,...,an);
- 用a1a_1a1代替F1F_1F1列,利用训练的模型对这些数据进行预测,求所有样本的预测的平均值;
- 对(a2,a3,...,an)( a_2, a_3,...,a_n)(a2,a3,...,an)重复步骤3,即遍历特征F1F_1F1的所有不同值;
- PDP的X轴为特征F1F_1F1的各个值,而Y轴是对应不同F1F_1F1值的平均预测平均值;
例如我们的数据集包含三个样本,每个样本有三个特征,A,B,C。
我们想要知道特征A是如何影响预测结果的。假设特征A一共有三种类型:A1,A2,A3A_1, A_2, A_3A1,A2,A3。训练数据其他特征保持不变,特征A依次修改为各个特征值,然后对预测求平均值。
最后PDP需要的是我针对不同特征值的平均预测值。
2.2.1 优缺点:
优点:
- 计算直观:在某个特征取特定值时,对预测取平均值;
- 解释清晰:PDP展示了随着特征值的改变,预测值的改变情况;
- 容易实现
缺点:
- 最多考虑两个特征:空间维度的限制,超过三维我们无法想象。如果不用图像显示特征分布,很难解释规律性。
- 独立性假设,需要满足特征两两独立,如果特征之间存在相关性,所求结果不合理;
- 异步效应可能被隐藏:特征变化对整个数据集带来的影响,也许一半数据集预测增加,一半介绍,取平均将是不变;
2.2.2 实例:
和上述一样,仍然选择预测每个人的年收入是否会超过50k这个数据集,使用XGBoost模型。
1. Age的PDP:
pdp_fare = pdp.pdp_isolate(model=gbtree, dataset=data, model_features=feature_names, feature='Age'
)
fig, axes = pdp.pdp_plot(pdp_fare, 'Age')
y轴是预测值的变化量,蓝色区域是置信区间。从图中可以看出,中年人,30多岁到60岁,有更高的PDP值,有更高的可能收入大于50K,相比少年和年老的 人,这和我们的常识是相统一的。
4.不同Age的收入大于50k的比率:
fig, axes, summary_df = info_plots.target_plot(df=data, feature='Age', feature_name='age', target='label', show_percentile=True
)
从图中发现,随着年龄的上升,收入大于50k的概率越来越高,超过一定年龄后会下降,这和PDP得出的结果是对应的。
5. Education-Num和Age的交互PDP(交叉特征):
plots_list = interpreter.partial_dependence.plot_partial_dependence([('Age', 'Education-Num')], im_model, grid_range=(0,1), figsize=(12, 5),grid_resolution=100)
从图中发现,教育水平低的话,中年人收入大于50k的可能性仍然不高。随着接受教育时间的增加,同等年龄收入大的可能性更大一些。
7. Education-Num和Age交叉特征
fig, axes, summary_df = info_plots.target_plot_interact(df=data, features=['Age', 'Education-Num'], feature_names=['Age', 'Education-Num'], target='label'
)
从图中可以看出,真实的收入水平和Age&Education-Num的关系和刚才求得的PDP值非常接近,
2.3 ICE(Individual Conditional Expectation):
PDP有一个缺点,它描述的是特征变化对整个数据集的影响,ICE能深入到单个样本,分析特征变化对单个样本的影响。求解过程和上述PDP类似,但是ICE会给出每一个样本的预测值。
ICE的作者[2]认为,至少通过这种方式,任何有兴趣的点将不会因为求平均值而难以发现,论文中给出的例子如下图所示:
如上述例子,如果仅看图b的PDP,会认为特征x_2和预测值无关 ,实际上如果看图a,会发现结论是错误的。这样通过绘制individual conditional expectation(ICE)曲线,一切将会变得显而易见。在求解Fare的PDP时,我们会得到一个蓝色的置信区间,而置信区间便是由一条条的ICE曲线汇合得到的。
2.4 LIME:
Local Interpretable Model-Agnostic Explanation(LIME) ,通过名字便可以看出,该模型是一个局部可解释模型,并且是一个与模型自身的无关的可解释方法。通过扰动输入样本(perturb the input),来对模型的预测结果进行解释。该算法不止适用于表格型(tabular)数据,而且适用于文本和图片任务。
论文作者提出了解释器需要满足的四个条件:
可解释性: 对模型和特征两个方面都有要求。决策树、线性回归和朴素贝叶斯都是具有可解释的模型,前提是特征也要容易解释才行。否则像是词嵌入(Word Embedding)的方式,即使是简单的线性回归也无法做到可解释性。而且解释性还要取决于目标群体,比如向不了解模型的业务人员去解释这些模型。相比之下,线性模型也要比简单的贝叶斯更容易理解。
局部忠诚( local fidelity):既然我们已经使用了可解释的模型与特征,就不可能期望简单的可解释模型在效果上等同于复杂模型(比如原始CNN分类器)。所以解释器不需要在全局上达到复杂模型的效果,但至少在局部上效果要很接近,而此处的局部代表我们想观察的那个样本的周围。
与模型无关: 任何其他模型,像是SVM或神经网络,该解释器都可以工作。
全局视角: 准确度,AUC等有时并不是一个很好的指标,我们需要去解释模型。解释器的工作在于提供对样本的解释,来帮助人们对模型产生信任。
2.4.1 可解释性和性能的平衡:
ξ(x)=argming∈GL(f,g,πx)+Ω(g)\xi(x)=\underset{g \in G}{\operatorname{argmin}} \mathcal{L}\left(f, g, \pi_{x}\right)+\Omega(g) ξ(x)=g∈GargminL(f,g,πx)+Ω(g)
- fff:分类器(复杂模型);
- ggg:可解释模型(简单模型,eg.LR);
- GGG:可解释模型集合;
- Ω(g)\Omega(g)Ω(g):可解释模型的复杂度度量;
- xxx:特征;
- ξ(x)\xi(x)ξ(x):目标函数;
- πx\pi_xπx:相似度度量函数;
- LLL:损失函数;
2.4.2 LIME分析步骤:
- 对整个数据进行训练,模型fff可以是Lightgbm,XGBoost等;
- 选择一个样例xxx,进行可解释的N次扰动,生成局部样本x‘x^`x‘;
- 定义一个相似度度量的函数πx\pi_xπx,选取最能描述复杂模型输出结果的K个特征,
- 使用复杂模型对xxx和x‘x^`x‘进行预测;
- 对采样后的样本,拟合一个简单的模型,比如Lasso Regression得到模型的权重;
我们人为的选择K个特征,特征越少,可解释性越好,特征越多简单模型也将具有更好的忠诚度。对数据进行扰动的时候,不可以进行随机、完全无意义的扰动。对于图像,按照超像素(可理解的图像块);文本,随机的对单个词进行筛选;表格型数据,每次单独改变一个特征。
2.4.3 优缺点:
优点:
- 表格型数据、文本和图片均适用;
- 解释对人友好,容易明白;
- 给出一个忠诚性度量,判断可解释模型是否可靠;
- LIME可以使用原模型所用不到的一些特征数据,比如文本中一个词是否出现;
缺点:
- 表格型数据中,相邻点很难定义,需要尝试不同的kernel来看LIME给出的可解释是否合理;
- 扰动时,样本服从高斯分布,忽视了特征之间的相关性;
- 稳定性不够好,重复同样的操作,扰动生成的样本不同,给出的解释可能会差别很大;
2.4.4 实例:
和上述一样,仍然选择预测每个人的年收入是否会超过50k这个数据集,使用XGBoost模型。
- 选择一个样本,重要性最高的5个特征,进行可解释分析:
np.random.seed(1)
i = 16explainer = lime.lime_tabular.LimeTabularExplainer(train,feature_names = feature_names,class_names=class_names,categorical_features=categorical_features, categorical_names=categorical_names, kernel_width=3)exp = explainer.explain_instance(test[i], predict_fn, num_features=5)
exp.show_in_notebook(show_all=False)
我们发现预测收入大于50k的概率是0.9。LIME给出解释,做出这样的预测是考虑到,婚姻状态,教育,每小时工作时间和年龄,而资本收益带来的是负的影响。
另一个例子:
i = 10
exp = explainer.explain_instance(test[i], predict_fn, num_features=5)
exp.show_in_notebook(show_all=True)
2.5 SHAP(SHapley Additive exPlanation):
2.5.1 shapley值:
shapley由伊德·夏普利(Lloyd Shapley)教授提出,用于解决合作博弈的贡献和收益分配问题。N人合作中,单个成员的贡献不一样,收益分配也应该不一样。理想的分配方式是:收益=贡献;
目标问题: NNN个人合作,创造了v(N)v(N)v(N)的价值,如何对所创造的价值进行分配。
基本条件: 全集N={x1,x2,⋯,xn}N=\{x_1,x_2,⋯,x_n\}N={x1,x2,⋯,xn}有N个元素xix_ixi,任意多个人形成的子集S⊆NS⊆NS⊆N,有v(S)v(S)v(S)表示S子集中所包括的元素共同合作所产生的价值。最终分配的价值(Shapley Value)ϕi(N,v)\phi_i(N,v)ϕi(N,v)。
需满足分配四原则:
- 有效性(Efficiency):所有价值均被分配
- 对称性(Symmetry):假设x_i和x_j可以互相替代,那他们收益应该一样;
- Dummy: 未做贡献的话收益为0;
- 可加性(Additivity):如果同一批人完成两项任务,那么两项任务的收益一起分配应该和分开分配的结果一致:
假设有500个题目,三个人去做,一天内完成。一天,A单独能完成100道,B完成125道,C完成50道。 v(A)=100,v(B)=125,v(C)=50v({A})=100, v({B})=125, v({C})=50v(A)=100,v(B)=125,v(C)=50
两个人合作的话,会快一些,v(A,B)=270,v(B,C)=350,v(A,C)=375v({A, B})=270, v({B, C})=350, v({A, C})=375v(A,B)=270,v(B,C)=350,v(A,C)=375。三个人合作,一天可以完成v(A,B,C)=500v({A, B, C}) = 500v(A,B,C)=500。分别考虑6种不同的分组情况,然后计算三个人分别对应的边际收益。
第i个人加入到组织S的边际收益是:ϕi(S)=v(S∪{i})−v(S)\phi_i(S) = v(S \cup \{i\}) - v(S)ϕi(S)=v(S∪{i})−v(S)
借鉴上述博弈论中Shapley值的计算方法,在机器学习训练任务中,一个特征的贡献值可由下面的公式计算:
ϕj(val)=∑S⊆{x1,…,xp}\{xj}∣S∣!(p−∣S∣−1)!p!(val(S∪{xj})−val(S))\phi_{j}(v a l)=\sum_{S \subseteq\left\{x_{1}, \ldots, x_{p}\right\} \backslash\left\{x_{j}\right\}} \frac{|S| !(p-|S|-1) !}{p !}\left(v a l\left(S \cup\left\{x_{j}\right\}\right)-v a l(S)\right) ϕj(val)=S⊆{x1,…,xp}\{xj}∑p!∣S∣!(p−∣S∣−1)!(val(S∪{xj})−val(S))
- SSS:特征的子集;
- xxx:样本特征值;
- valx(S)val_x(S)valx(S):针对集合S特征值的预测;
- ppp:总的特征数;
和上述例子是类似的,但是增加了一个权重。
计算Shapley值,要考虑每个特征是否在集合S中,随着特征数的增加,计算复杂度会呈指数上升,所以Strumbelj等人提出了一种通过Monte-Carlo采样实现的近似算法:
ϕ^j=1M∑m=1M(f^(x+jm)−f^(x−jm))\hat{\phi}_{j}=\frac{1}{M} \sum_{m=1}^{M}\left(\hat{f}\left(x_{+j}^{m}\right)-\hat{f}\left(x_{-j}^{m}\right)\right) ϕ^j=M1m=1∑M(f^(x+jm)−f^(x−jm))
- f^(x+jm)\hat{f}(x_{+j}^{m})f^(x+jm):特征jjj不变,其他特征被随机数据点替换,得到的预测结果;
- f^(x−jm)\hat{f}(x_{-j}^{m})f^(x−jm):和上述类似,特征jjj同样被替换;
- M:迭代M次;
特征的近似Shapley值求解步骤:
输出: 第jjj个特征的Shapley值
输入: 迭代次数 M,样本点 x, 特征索引 jjj,训练数据 XXX, 训练模型 fff
for m = 1,…M:
- 从训练数据中随机采样,样本z0=(z(1),z(2),...z(j),...,z(p))z_0 = (z_{(1)}, z_{(2)}, ...z_{(j)}, ...,z_{(p)})z0=(z(1),z(2),...z(j),...,z(p));
- 假设样本待预测样本为 x0=(x(1),x(2),...x(j),...,x(p))x_0 = (x_{(1)}, x_{(2)}, ...x_{(j)}, ...,x_{(p)})x0=(x(1),x(2),...x(j),...,x(p))
- 将样本x中的特征随机替换为z中的特征,得到两个新的向量:
x+j=(x(1),…,x(j−1),x(j),z(j+1),…,z(p))x_{+j}=\left(x_{(1)}, \ldots, x_{(j-1)}, x_{(j)}, z_{(j+1)}, \ldots, z_{(p)}\right)x+j=(x(1),…,x(j−1),x(j),z(j+1),…,z(p))
x−j=(x(1),…,x(j−1),z(j),z(j+1),…,z(p))x_{-j}=\left(x_{(1)}, \ldots, x_{(j-1)}, z_{(j)}, z_{(j+1)}, \ldots, z_{(p)}\right)x−j=(x(1),…,x(j−1),z(j),z(j+1),…,z(p))
- 计算每次的边际收益
ϕjm=f^(x+j)−f^(x−j)\phi_j^m = \hat{f}\left(x_{+j}\right)-\hat{f}\left(x_{-j}\right)ϕjm=f^(x+j)−f^(x−j)
取平均,计算特征jjj的Shape值:ϕ^j=1M∑m=1M(f^(x+jm)−f^(x−jm))\hat{\phi}_{j}=\frac{1}{M} \sum_{m=1}^{M}\left(\hat{f}\left(x_{+j}^{m}\right)-\hat{f}\left(x_{-j}^{m}\right)\right)ϕ^j=M1∑m=1M(f^(x+jm)−f^(x−jm))
2.5.2 优缺点:
优点:
- SHAP值的计算是公平分配到不同的特征的,而LIME是选择一部分特征进行解释;
- 可以进行对比分析,同一个特征在不同样本之间的SHAP值进行比较,但是LIME不能;
- 具有坚实的理论基础,LIME使用LR等简单模型进行拟合,但是并不清楚为什么这样是work的;
缺点:
- 计算非常耗时,指数级别的复杂度;
- SHAP可能存在误导,他计算的并不是将这个特征去掉以后训练模型得到的结果
- 计算某个样本的SHAP值时,需要获取整个训练数据集;
- 如果特征之间存在相关性,这种基于扰动的方法,可能会出现不切实际的数据;
2.5.3 实例:
为了方便对比,选择和LIME同样的数据集,预测用户的收入。读取数据,数据预处理,和模型训练部分和前面相同,不再赘述。
1. 选择和LIME同样的一条样本进行可解释分析:
# explain the model's predictions using SHAP values
explainer = shap.TreeExplainer(gbtree)
shap_values = explainer.shap_values(test)# 对一个样本求shap值,各个特征对output所带来的变化
shap.force_plot(explainer.expected_value, shap_values[16,:], test.iloc[16,:])
图解:
- base value:全体样本Shap平均值;
- output value:当前样本的Shap输出值;
- 正向作用特征:Education-num, Relationship, Age;
- 反向作用的特征:Country, Capital Gain
这个图说明了,对于单个样本,预测值的高低是如何造成的,由哪些特征造成的。和LIME的解释对比可以发现,基本是一致的,均是因为Age,Education,Capital Gain等做出的决策。
2. 另一个样例:
shap.force_plot(explainer.expected_value, shap_values[10,:], test.iloc[10,:])
从图中发现,大部分特征都是呈现反向作用,所以预测的值较低。
3. 将上图旋转90°,然后将所有的test拼接在一起,可以看到在整个数据集上Shap分布:
shap.force_plot(explainer.expected_value, shap_values, test)
4. 从特征维度,观察特征对Shap的影响:
shap.summary_plot(shap_values, test)
图解:
- 横坐标是SHAP值(对模型输出的影响)
- 纵坐标是不同的特征
- 颜色越红,特征值越大,越蓝特征值越小;
从图中可以看出,年龄(Age)越大,对收入的正向作用越大,但是到达一定年龄,对收入的贡献将不变,同时发现,存在年龄小但收入高的群体。同样,随着接受教育时间(Education-Num)变大,收入随之提高。同时,资本收益(Capital Gain)对收入的影响最大。
5. 特征重要性:
对所有样本的SHAP绝对值取平均,得到类似lgb、xgb特征重要性的数据。
6. 观察某个特征的SHAP分布:
数值型特征:Age
从图中,我们可以发现,随着年龄的增加SHAP值不断增加,但是超过一定年龄后,SHAP值反而会下降。同时,高资本收益的人群分布在30岁往后,同样年龄,高资本收益的人群,收入更高,十分合理(hhhh)。
类别型特征:Relationship
每一个用户在家庭中所处的关系,从左到右分别是【‘Husband’, ‘Not-in-family’, ‘Other-relative’, ‘Own-child’, ‘Unmarried’, ‘Wife’】,已婚的SHAP值更高,小孩和未婚的更低,符合常识。
三、其他方法:
3.1 Interpret:
微软新提出了,一个可以训练可解释机器学习模型和解释模型的,开源框架。一方面这个框架,实现了可解释提升模型(Explainable Boosting Machine-EBM)。EBM是GA2MGA^2MGA2M的一种实现,在基础上添加了一些诸如bagging和boosting等模型融合的方法。微软表示,EMB的性能媲美XGBoost和Lightgbm等集成树模型,同时保持模型的可解释性。
接下来看GAMs。
3.1.1 GAMS:
线性模型具有非常好的可解释性,通过权重可以分析每个特征是如何影响预测结果的。但是线性模型过于简单。线性模型非常严重的缺陷是无法拟合交叉特征和非线性关系。非线性关系可以通过以下几种方式解决,对特征进行转换(log,exp等),将特征分箱然后onehot,另一种便是GAMs。
标准线性模型: y=β0+β1x1+...+βnxn+ϵy = \beta_0 + \beta_1x_1 + ... + \beta_nx_n + \epsilony=β0+β1x1+...+βnxn+ϵ
GAM: g(EY(y∣x))=β0+f1(x1)+f2(x2)+…+fp(xp)=β0+∑fj(xj)g\left(E_{Y}(y | x)\right)=\beta_{0}+f_{1}\left(x_{1}\right)+f_{2}\left(x_{2}\right)+\ldots+f_{p}\left(x_{p}\right)= \beta_0 + \sum{f_j(x_j)}g(EY(y∣x))=β0+f1(x1)+f2(x2)+…+fp(xp)=β0+∑fj(xj)
GAMs和标准线性模型非常相似,只不过是将βjxj\beta_jx_jβjxj用一个灵活的函数表示fj(xj)f_j(x_j)fj(xj)。本质上依然是对特征的影响进行求和。
同时线性模型无法学习到交叉特征,GA2MGA^2MGA2M在GAM的基础上添加了交叉项:
g(E[y])=β0+∑fj(xj)+∑fij(xi,xj)g(E[y])=\beta_{0}+\sum f_{j}\left(x_{j}\right)+\sum f_{ij}\left(x_{i}, x_{j}\right)g(E[y])=β0+∑fj(xj)+∑fij(xi,xj)
实际使用了下,微软把没弄好的东西丢了出来,训练时间非常长,在小数据集上效果尚可,不排除是随机数的影响,而且XGBoost是默认参数。在大数据集上,训练时间相当长,指标(AUC)和lgb有差距。还是有待改善吧,还需要在更多的数据集上进行尝试。
实验结果:
Model | heart-disease(303,13) | breast-cancer(569,30) | adult-data(32561,19) | credit-fraud(284807,30) |
---|---|---|---|---|
SGD | 0.885 | 0.993 | 0.891 | 0.980 |
LR | 0.915 | 0.996 | 0.907 | 0.974 |
RandomForest | 0.908 | 0.991 | 0.903 | 0.942 |
XGBoost | 0.879 | 0.995 | 0.922 | 0.979 |
Lightgbm | 0.869 | 0.994 | 0.929 | 0.984 |
EBM | 0.925 | 0.995 | 0.929 | 0.969 |
3.2 非事实解释(Counterfactual Explanations):
讲一个有意思的场景。假设我想去贷款,然后被银行的机器学习模型拒绝了。我会想,为什么我会被拒绝,以及如何能提高我被接受的概率。机器学习模型用到的特征包括,我自身的属性,包括收入,银行卡数量,年龄等。如何对这些特征做出最小的改变,使得模型的预测从拒绝变成接受呢。通过构建违反常规的样本,来改变模型的预测,从而达到对模型进行可解释的目的。
类似在风控任务中,为什么这个人违约率高。如果,对其修改某个特征后,概率会降低。这样可以解释,是因为某个特征值,模型预测的概率比较高。
如何定义一个好的非事实解释:
- 尽可能和想要的预测更接近;
- 对于特征值进行尽可能少的改变;
- 修改后的特征值尽可能符合实际情况;
参考资料
文章:
Interpretable Machine Learning A Guide for Making Black Box Models Explainable.
可解释的机器学习
Kaggle课程-Machine Learning Explainability
机器学习模型可解释性的详尽介绍
A Brief History of Machine Learning Models Explainability
Shapley, LIME and SHAP
Interpreting machine learning models
What If… you could inspect a machine learning model, with minimal coding required?
Papers on Explainable Artificial Intelligence
Limitations of Interpretable Machine Learning Methods
Comparison between SHAP (Shapley Additive Explanation) and LIME (Local Interpretable Model-Agnostic Explanations)
One Feature Attribution Method to (Supposedly) Rule Them All: Shapley Values
Introduction to AI Explanations for AI Platform
Hands-on Machine Learning Model Interpretation
Papers:
[1] Friedman, J. (2001). Greedy Function Approximation: A Gradient Boosting Machine. The Annals of Statistics, 29(5):1189–1232.
[2] Goldstein, A., Kapelner, A., Bleich, J., and Pitkin, E., Peeking Inside the Black Box: Visualizing Statistical Learning With Plots of Individual Conditional Expectation. (2015) Journal of Computational and Graphical Statistics, 24(1): 44-65
[3] Lundberg S M, Erion G G, Lee S I. Consistent individualized feature attribution for tree ensembles[J]. arXiv preprint arXiv:1802.03888, 2018.
[4] Ribeiro M T, Singh S, Guestrin C. Why should i trust you?: Explaining the predictions of any classifier[C]//Proceedings of the 22nd ACM SIGKDD international conference on knowledge discovery and data mining. ACM, 2016: 1135-1144.
[5] Lundberg S M, Lee S I. A unified approach to interpreting model predictions[C]//Advances in Neural Information Processing Systems. 2017: 4765-4774.
[6] Nori H, Jenkins S, Koch P, et al. InterpretML: A Unified Framework for Machine Learning Interpretability[J]. arXiv preprint arXiv:1909.09223, 2019.
[7] AI Explainability Whitepaper-Google
开源库:
- eli5
- pdpbox
- shap
- lime
- interpret
- skater
可解释性机器学习:从入门到实战相关推荐
- PyTorch机器学习从入门到实战
人工智能入门实践, 轻松玩转PyTorch框架. 校宝在线出品的书籍<PyTorch机器学习从入门到实战>发售了! 购书链接: 内容简介 近年来,基于深度学习的人工智能掀起了一股学习的热潮 ...
- 【机器学习】入门到实战笔记系列 | 西瓜书
机器学习 南京大学周志华教授亲讲<机器学习初步>!跟着大佬从入门到实战 机器学习的本质就是寻找一个函数function,来寻找一个输入input与输出output之间的映射关系.可以是输入 ...
- PyTorch机器学习从入门到实战-CH2
PyTorch安装和快速上手 基础安装和工具使用 安装Anaconda3,内置python3.7 启动Jupyter Notebook 命令终端输入:jupyter notebook 命令运行后,浏览 ...
- 《PyTorch机器学习从入门到实战》 例程(PyTorch1.2版本可用)
文章目录 1.单层神经网络实现(CH3.7) 2.(optimizer)优化器的使用示例(CH4.3) 4.MNIST数据集上卷积神经网络的实现(CH5.3) 5.自编码器实现(CH6.2) 6.基于 ...
- 回归素材(part7)--机器学习入门到实战-MATLAB实践应用
学习笔记,仅供参考,有错必纠 文章目录 机器学习入门到实战-MATLAB实践应用 线性回归原理 简单线性回归 多元线性回归 机器学习入门到实战-MATLAB实践应用 线性回归原理 简单线性回归
- python3人工智能网盘_《Python3入门人工智能掌握机器学习+深度学习提升实战能力》百度云网盘资源分享下载[MP4/5.77GB]...
内容简介 本资源为<Python3入门人工智能掌握机器学习+深度学习提升实战能力>百度云网盘资源分享下载,具体看下文目录,格式为MP4/5.77GB.本资源已做压缩包处理,请勿直接在百度网 ...
- 【白话机器学习】算法理论+实战之Xgboost算法
1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,在这简单的先捋一捋, 常见的机器学习算法: 监督学习算法:逻辑回归,线性回归,决策树,朴素贝叶斯,K近邻,支 ...
- 【白话机器学习】算法理论+实战之PCA降维
1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,在这简单的先捋一捋, 常见的机器学习算法: 监督学习算法:逻辑回归,线性回归,决策树,朴素贝叶斯,K近邻,支 ...
- 深度学习-机器学习从入门到深入全套资源分享
深度学习.机器学习从入门到深入,全套资源分享.涉及深度学习.机器学习数学.算法基础理论.实战和工程开发相关最佳资源.深度学习常用模型相关教程,深度学习模型优化.调参相关技巧:深度学习常用的框架,公开数 ...
- AI深度学习入门与实战21 文本分类:用 Bert 做出一个优秀的文本分类模型
在上一讲,我们一同了解了文本分类(NLP)问题中的词向量表示,以及简单的基于 CNN 的文本分类算法 TextCNN.结合之前咱们学习的 TensorFlow 或者其他框架,相信你已经可以构建出一个属 ...
最新文章
- iOS 数组中的模型去重
- Linux下搭建高效的SVN
- Nginx配置:nginx如何配置跳转fpm
- vsftpd类似wu-ftpd分类(Class)的配置-给不同网段的人以不同的上传权限-对虚拟用户进行访问IP限制...
- Ubuntu建立(apache+php+mysql)+phpmyadmin
- rocketmq java home,rocketmq 安装与配置以及遇到的问题
- three.js和php,threejs--初创项目
- 双目测距数学原理详解(转载)
- MySQL 创建联结
- STM32学习——中断方式下的发送数据
- linux定时器时间间隔为0,linux下定时器的使用--timer_create等系列
- 比特币蒸发 1 万亿;中兴入局无人驾驶;特斯拉 Model 3 在华降价 | 极客头条
- HDU4536+DFS
- LINUX 命令手册
- Redis集群搭建(单设备,多设备)
- 国内投资者投资港股的四种方法和港股必知25件事
- Python中文社区开源项目扶持计划
- 数仓建设之IP库的匹配
- Python爬虫入门(四):实战,爬取4399小游戏首页
- 如何让服务器保持运行程序