LIME 模型解释器

LIME 即是Local Interpretable Model-agnostic Explanations模型解释器,简单来说就是将每个变量的重要性可视化,集成学习xgb等有feature_importances_,还有专门的SHARP,那么LIME有什么优势呢?

首先我们来看看它的基本操作流程

下面使用GiveMeSomeCredit,数据地址:https://www.kaggle.com/brycecf/give-me-some-credit-dataset?select=cs-test.csv

 这个是另外的 https://www.statsmodels.org/stable/generated/statsmodels.discrete.discrete_model.Logit.html#statsmodels.discrete.discrete_model.Logit

直接看代码:

import pandas as pd
import numpy as np

data = pd.read_csv('cs-training.csv')

#删除没有用的列
data = data.iloc[:,1:]
from xgboost import XGBClassifier import shap from sklearn.model_selection import train_test_split # 训练集测试集分割 X = data.iloc[:,1:] y = data['SeriousDlqin2yrs'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=2022) # 模型训练 params={ 'eta':0.2, #特征权重,取值范围0~1,通常最后设置eta为0.01~0.2 'max_depth':3, #树的深度,通常取值3-10,过大容易过拟合,过小欠拟合 'min_child_weight':50, #最小样本的权重,调大参数可以繁殖过拟合 'gamma':0.4, #控制是否后剪枝,越大越保守,一般0.1、 0.2的样子 'subsample':0.8, #随机取样比例 'colsample_bytree':0.8 , #默认为1,取值0~1,对特征随机采集比例 'lambda':0.8, 'alpha':0.6, 'n_estimators':50, 'booster':'gbtree', #迭代树 'objective':'binary:logistic', #逻辑回归,输出为概率 'nthread':6, #设置最大的进程量,若不设置则会使用全部资源 'scale_pos_weight':1.5, #默认为0,1可以处理类别不平衡 'seed':1234, #随机树种子 'silent':1, #0表示输出结果 'eval_metric':'auc'} #评分指标 model = XGBClassifier(**params) model.fit(X_train, y_train) score = model.score(X_test, y_test) score #预测结果 t = model.predict_proba(X_test)[:,1]

计算AUC,KS 

#
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve,auc
def plot_roc(p1, p,string):
    '''
    目标:计算出分类模型的ks值
    变量:
    self:模型fit(x,y),如(self=tree.fit(x,y))
    data:一般是训练集(不包括label)或者是测试集(也是不包括label)
    y:label的column_name 
    返回:训练集(或者测试集)的auc的图片

    '''      

 
    fpr, tpr, p_threshold = roc_curve(p1, p,
                                              drop_intermediate=False,
                                              pos_label=1)
    df = pd.DataFrame({'fpr': fpr, 'tpr': tpr, 'p': p_threshold})
    df.loc[0, 'p'] = max(p)

    ks = (df['tpr'] - df['fpr']).max()
    roc_auc = auc(fpr, tpr)

    fig = plt.figure(figsize=(2.8, 2.8), dpi=140)
    ax = fig.add_subplot(111)

    ax.plot(fpr, tpr, color='darkorange', lw=2,
            label='ROC curve\nAUC = %0.4f\nK-S = %0.4f' % (roc_auc, ks)
            )
    ax.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')

    ax.set_xlim([0.0, 1.0])
    ax.set_ylim([0.0, 1.05])
    ax.set_xlabel('False Positive Rate')
    ax.set_ylabel('True Positive Rate')
    ax.set_title(string)
    ax.legend(loc="lower right")
    plt.close()
    return fig
plot_roc(y_test, t,'训练集ROC Curve')  #训练集 

 

 

 下面使用LIME 

import lime
from lime import lime_tabular
 
explainer = lime_tabular.LimeTabularExplainer(
    training_data=np.array(X_train),
    feature_names=X_train.columns,
    class_names=['good', 'bad'],
    mode='classification',
    discretize_continuous=False #记住要加这个参数,不然会报错
)

预测概率为0的可视化

exp = explainer.explain_instance(data_row=X_test.iloc[1], predict_fn=model.predict_proba)
exp.show_in_notebook(show_table=True)

预测概率为1的可视化

exp = explainer.explain_instance(data_row=X_test.iloc[25], predict_fn=model.predict_proba)
exp.show_in_notebook(show_table=True)

 

那么我们来说说它的优缺点:

优点:

(1)可以使用sklearn里面的model;

(2)可以可视化每个特征的贡献

缺点:

(1)变量中有缺失值的不能可视化,需要提前做缺失值处理

(2)看不懂预测结果0和1时的差异??可能是我们这个数据不够明显

参考资料:https://blog.csdn.net/fengdu78/article/details/118384216?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-118384216-blog-116108787.pc_relevant_multi_platform_whitelistv4eslandingrelevant&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-118384216-blog-116108787.pc_relevant_multi_platform_whitelistv4eslandingrelevant&utm_relevant_index=1

https://github.com/marcotcr/lime

 

后面又仔细看了一下源代码,发现discretize_continuous这个参数,

(1)如果discretize_continuous=False,连续型变量就不做处理,但是这样就会和上面的结果一样,看不出来预测结果0和1时的差异,

(2)如果将discretize_continuous=True,跑下面这段代码就报错

exp = explainer.explain_instance(data_row=X_test.iloc[1], predict_fn=model.predict_proba)
exp.show_in_notebook(show_table=True)
我猜测报错原因和缺失值有关,于是尝试先处理缺失值
import pandas as pd
import numpy as np

data = pd.read_csv('cs-training.csv')

data = data.iloc[:,1:]

data = data.fillna(0)

from xgboost import XGBClassifier
import shap
from sklearn.model_selection import train_test_split

# 训练集测试集分割
X = data.iloc[:,1:]
y = data['SeriousDlqin2yrs'] 
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=2022)
# 模型训练
params={
        'eta':0.2,                        #特征权重,取值范围0~1,通常最后设置eta为0.01~0.2
        'max_depth':3,                    #树的深度,通常取值3-10,过大容易过拟合,过小欠拟合
        'min_child_weight':50,             #最小样本的权重,调大参数可以繁殖过拟合
        'gamma':0.4,                      #控制是否后剪枝,越大越保守,一般0.1、 0.2的样子
        'subsample':0.8,                  #随机取样比例
        'colsample_bytree':0.8 ,          #默认为1,取值0~1,对特征随机采集比例
        'lambda':0.8,
        'alpha':0.6,
        'n_estimators':50,
        'booster':'gbtree',               #迭代树
        'objective':'binary:logistic',    #逻辑回归,输出为概率
        'nthread':6,                      #设置最大的进程量,若不设置则会使用全部资源
        'scale_pos_weight':1.5,             #默认为0,1可以处理类别不平衡

        'seed':1234,                      #随机树种子
        'silent':1,                       #0表示输出结果
        'eval_metric':'auc'}               #评分指标
model = XGBClassifier(**params)
model.fit(X_train, y_train)
score = model.score(X_test, y_test)
score

import lime
from lime import lime_tabular
 
explainer = lime_tabular.LimeTabularExplainer(
    training_data=np.array(X_train),
    feature_names=X_train.columns,
    class_names=['good', 'bad'],
    mode='classification',
    discretize_continuous=True 
)

预测概率为0

exp = explainer.explain_instance(data_row=X_test.iloc[1], predict_fn=model.predict_proba)
exp.show_in_notebook(show_table=True)

 

 预测概率为1

exp = explainer.explain_instance(data_row=X_test.iloc[25], predict_fn=model.predict_proba)
exp.show_in_notebook(show_table=True)

 

画权重图

exp.as_pyplot_figure()

 

 

 这样就能看明白了,至于柱状图里面的数值,每个变量的重要性权重,这个权重具体是什么,有空再去研究一下。

 

 

 
posted on 2022-08-31 10:49  小小喽啰  阅读(753)  评论(0编辑  收藏  举报