在这篇文章中,将探讨一种技术,使得任何机器学习模型都具有可解释性。通常存在一个误解,即只有线性机器学习模型比其他模型更易于解释。模型的可解释性有助于决策制定,并为客户提供可靠性。
在人工智能中,可解释性是指特征对给定输出的贡献程度或重要性。例如,如果有一个线性模型,特征重要性是通过权重的大小来计算的。如果有基于树的模型,特征重要性是通过信息增益或熵来计算的。对于深度学习模型,使用集成梯度来计算。
许多这些人工智能系统都是黑箱,意味着不理解它们是如何工作的,以及它们为何做出这样的决策。
一篇名为《Why Should I Trust You?》的研究论文,由华盛顿大学的Marco Tulio Ribeiro、Sameer Singh和Carlos Guestrin在2016年发表,解释了两种技术:LIME(局部可解释模型不可知解释)和SHAP(SHapley Additive exPlanations)。在这篇博客中,将深入探讨LIME技术的直觉。
LIME旨在识别一个在局部忠实于分类器的可解释模型。局部可解释性回答了“为什么模型在数据点x的局部表现出特定方式?”的问题。LIME只关注数据的局部结构,而不是全局结构。
高层次的直觉是考虑上图中的深红色+标记的X,并取X附近的数据点。从上图中可以看到,靠近X的点具有更高的权重,而远离X的点权重较低。在X附近采样一些点,并拟合一个替代模型g()(考虑g()为线性模型)。替代模型在X的邻域内近似f()模型。f()是最终的黑箱模型,给定输入x,将得到输出y。
让深入了解数学直觉;对于每个X,还有另一个X',其中X'是d'维可解释的二进制向量。对于文本数据,可解释向量X'是单词的存在或不存在(即)词袋模型。对于图像数据,可解释向量X'是图像块或超像素的存在或不存在。超像素不过是相似像素的连续块。对于表格数据,如果特征是分类的,那么X'是该特征的独热编码,或者如果特征是实值的,那么进行特征分箱。替代模型g ∈ G是任何可解释模型,如线性模型或决策树。Ω(g)衡量替代模型的复杂性。例如,随着线性模型中非零权重的数量增加,复杂性增加。同样,如果决策树的深度增加,模型复杂性增加。g是X'的函数。
Πx(Z) = X和Z之间的邻近度量
其中Πx是X的局部性。
局部保真度意味着在X的邻域内,替代函数g()应该紧密地类似于f()。损失函数L(f, g, πx)显示了函数g()近似f()的程度。
让Πx(z) = exp(−D(x, z)^2 / σ^2)是一个指数核。
g(z’) = w_g · z’
z'是对应于z的可解释特征。Ω(g)代表K-Lasso,这意味着使用Lasso正则化选择前K个特征。
LIME的优势在于它适用于图像、文本和表格数据,并且是模型不可知的。K Lasso提供了高度可解释的K特征。然而,LIME也有一些缺点,比如确定正确的邻域Πx(z)、正确的核宽度σ以及距离度量D(x, z)在高维数据中可能不适用。
pip install lime
以葡萄酒质量数据集为例。
import numpy as np
import pandas as pd
df=pd.read_csv("wine.csv",delimiter=';')
print(df.head())
from sklearn.model_selection import train_test_split
X = wine.drop('quality', axis=1)
y = wine['quality']
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42)
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier(random_state=42)
model.fit(X_train, y_train)
score = model.score(X_test, y_test)
LIME库有一个名为lime_tabular的模块,用于创建表格解释器对象。参数包括:training_data – 训练数据必须是Numpy数组格式。feature_names – 训练集的列名class_names – 目标变量的不同类别mode – 在情况下是分类。
import lime
from lime import lime_tabular
explainer = lime_tabular.LimeTabularExplainer(
training_data=np.array(X_train),
feature_names=X_train.columns,
class_names=['bad', 'good'],
mode='classification')
exp = explainer.explain_instance(
data_row=X_test.iloc[1],
predict_fn=model.predict_proba)
exp.show_in_notebook(show_table=True)