在人工智能领域,可解释性是一个关键的概念,它涉及到如何将所谓的“黑箱”模型(例如机器学习或深度学习模型)的内部工作机制以人类可以理解的方式进行解释。如果不仅知道模型的输出结果,还知道模型为何得出这样的结果,即输出结果背后有恰当的解释,这对于推动业务发展是非常有益的。
可解释性的范围可以是局部的(针对单个样本)或全局的(整体)。例如,基于模型系数的线性/逻辑回归算法相对容易解释,而基于树的算法则可以通过内置的特征重要性和可视化来帮助理解模型是如何做出决策的。
对于复杂的机器学习算法,可以使用排列特征重要性(Permutation Feature Importance)方法。这是一种模型检查技术,可以用于任何已拟合的估计器,特别是当数据是表格形式时。排列特征重要性定义为当单个特征值被随机打乱时模型得分的下降。这个过程破坏了特征与目标之间的关系,因此模型得分的下降表明了模型对特征的依赖程度。
影响误差指标最多的特征是重要的,因为它表明了模型对该特征的依赖性。可以计算每个特征的重要性得分,公式如下:
i_j = (s - s_k,j) / s
其中,i_j
是特征j的重要性,s
是训练模型计算出的参考得分,K
是为特征执行的迭代(打乱操作)次数,s_k,j
是第k次迭代在特征j上的得分。
可以使用Python的sklearn包中的内置permutation_importance
函数。以下是使用Xgboost算法和Boston数据集的示例代码:
from sklearn.inspection import permutation_importance
xg = xgboost.XGBRegressor()
xg.fit(Xtrain, ytrain)
r = permutation_importance(xg, Xtest, ytest, n_repeats=30, random_state=0)
这里,设置了n_repeats=30
。返回的对象r
将包含每个特征的重要性值,可以使用matplotlib Python库进行可视化。
import matplotlib.pyplot as plt
plt.figure(figsize=(10,4))
plt.bar(boston.feature_names, r.importances_mean)
plt.xlabel('Features')
plt.ylabel('Mean Importance')
plt.title('Feature importance using Feature Permutation Importance')
如果两个特征是相关的,并且其中一个特征被置换,模型仍然有另一个相关特征,在这种情况下,两个特征的重要性值都会降低,即使这些特征实际上是重要的。此外,置换形成的不切实际的数据实例可能会产生偏差,对于大量特征来说,计算成本也很高。
一个好的做法是基于领域理解,放弃其中一个相关特征,并尝试应用排列特征重要性算法,这将提供更好的特征理解。
让讨论另一种解释黑箱模型的方法。全局替代模型是一种解释模型,它被训练用来近似黑箱模型的预测。这就像是用更简单、可解释的模型(如线性回归、决策树等)来解决黑箱可解释性任务,即用更多的机器学习来解释机器学习。
最后,可以解释全局替代模型。这种方法的优点是灵活的,因为替代模型的选择不依赖于黑箱模型。如果在某个时候有一个表现更好的黑箱模型来替代现有的黑箱模型,不需要改变解释方法。
已经看到了一些全局解释的技术,那么局部解释呢?当想要理解模型对特定观测值的预测是如何做出的。
以贷款审批模型为例,如果用户的请求被拒绝,用户有权询问为什么?当局应该知道模型为何拒绝用户请求,并将同样的理由传达给用户,因为他们不能简单地说系统拒绝了它,而是需要解释请求是基于哪些因素(特征)被拒绝的。
LIME可以以忠实的方式解释任何分类器或回归器的预测,通过在局部用可解释的模型(线性回归、决策树等)来近似它。它测试当将数据的变化输入到机器学习模型时会发生什么。LIME可以用于表格、文本和图像数据。
import lime
import lime.lime_tabular
xg = xgboost.XGBRegressor()
xg.fit(Xtrain, ytrain)
explainer = lime.lime_tabular.LimeTabularExplainer(Xtrain, feature_names=boston.feature_names, class_names=['price'], categorical_features=categorical_features, verbose=True, mode='regression')
exp = explainer.explain_instance(Xtest[i], xg.predict, num_features=5)
exp.show_in_notebook(show_table=True)