前言
随着推荐算法引起的信息茧房和自由主义的发展,让这个世界以无与伦比的速度分裂着。一个浅显的好处是打破了原先的单一价值追求,由着不同的价值取向朝着各自平行的元宇宙进发。
多元化本身来说是件好事,但另一方面也让本就“黑盒”的 AI
模型遭遇了前所未有的挑战,进而引起一系列的混沌,摩擦,对立甚至冲突...
可解释性
在实际应用中,特别是涉及到金融领域,可解释性太重要了。一个决策系统,如果结果无法归因,那谁也不敢在生产环境中使用。
举个例子,Zillow
是美国最受欢迎的在线房地产数据库之一,作为交易服务的一部分,平台除了为房地产买卖双方提供交易撮合服务,还提供了房产估价模型——Zestimate
。记得在当年Kaggle
竞赛上,这个房价预测模型曾大杀四方,让公司估值翻了几倍。
但同样这个模型在去年的疫情环境下,却出现了严重的偏差,差点让公司破产。
究其原因,从新冠疫情开始后不久,美国的房地产市场就开始进入狂飙突进的阶段。政府疯狂撒钱的情况下,所有人对美元贬值的恐惧植入了心灵。
模型哪见过这种场面啊,首先历史数据造成预测的价格总是低于市场价,随着最近市场数据的权重越来越高,最新的预测价格则远高于现实,就埋下了很大的隐患。待到市场回归理性,Zillow
"旧屋翻新"项目里那段时间大把高价购入的房子就砸手里了。
这就是极端行情和从未出现过的黑天鹅事件的共同作用下,时间趋势类的金融模型预测失真,如果当时能多一些归因和最终决策前的人工审核,其实能降低这种灾难性事件发生的概率。毕竟当时传统的房地产专家普遍给出过“不宜追高”的建议,无奈大数据起家的 Zillow
更偏信了模型。
Dalex 框架
介绍一个工具,可以对模型整个生命周期的各个阶段进行数据分析和可视化,便于理解模型每个阶段所做的工作,用于对比预测和实际的效果。
本质上现阶段绝大多数的 AI
模型只是对自然事件或人类活动的一种概率仿真,即使是看似极富创造力的GPT3
或是StyleGAN
,所学习的也是一种可迁移的模式,并非人类程度的“理解后的创作”,称之为对人类活动的高维模仿更适合些。所以可解释性是破模型黑盒
的一种必要手段。
我们采用一个经典的“银行电话营销成功率”为例,以下网站可以下载到完整数据集。
https://archive.ics.uci.edu/ml/datasets/bank+marketing#
其中客户信息包含年龄,职业,教育程度,是否有房产,是否有贷款等等信息,目标是预测客户的定期存款意愿。
这是一个相对简单的二分类场景,主要工作在于构建特征,模型采用Dummy
模型,逻辑回归或决策树都行。
安装依赖
pip install dalex plotly
导入库文件
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.dummy import DummyClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler,MinMaxScaler,LabelEncoder
from sklearn.metrics import classification_report,accuracy_score,plot_confusion_matrix,confusion_matrix
from sklearn.metrics import f1_score
数据清洗
这里我们解压上文所述的数据集,选择bank-additional-full.csv
文件
df = pd.read_csv("data/bank-additional-full.csv",sep=";")
df.head()
for col in df.select_dtypes(include='object').columns:
df[col] = LabelEncoder().fit_transform(df[col])
df.head()
提取特征
这里简化了模型,就不做交叉特征和行业特征了,主要看Dalex
的使用方法。
Xfeatures = df.drop(['y'],axis=1)
ylabels = df['y']
Xfeatures.columns
sns.countplot(x='y',data=df)
模型训练
按 7:3 的比例来划分训练集和测试集,分别用 Dummy
模型、逻辑回归和决策树模型进行训练。
# Split Dataset
x_train,x_test,y_train,y_test = train_test_split(Xfeatures,ylabels,test_size=0.3,random_state=0)
# Build Pipeline
pipe_base = Pipeline(steps=[('std_scaler',StandardScaler()),('dummy',DummyClassifier())])
pipe_lr = Pipeline(steps=[('std_scaler',StandardScaler()),('lr',LogisticRegression())])
pipe_dt = Pipeline(steps=[('std_scaler',StandardScaler()),('dt',DecisionTreeClassifier())])
pipe_base.fit(x_train,y_train)
pipe_lr.fit(x_train,y_train)
pipe_dt.fit(x_train,y_train)
print("DY:",pipe_base.score(x_test,y_test))
print("LR:",pipe_lr.score(x_test,y_test))
print("DT:",pipe_dt.score(x_test,y_test))
输出:
DY: 0.8876750020231448
LR: 0.9115481103827789
DT: 0.890507404709881
基本特征的模型验证结果,逻辑回归的准确率最高。
模型解析
接下来导入 dalex,这里就以逻辑回归模型为例,创建解释器
import dalex as dx
exp = dx.Explainer(pipe_lr,x_train,y_train)
exp.model_performance()
exp.model_parts()
列出特征的重要性,影响程度最大的分别是 emp.var.rate
(每季度的就业率)、duration
(通话时长)、nr.employed
(每季度雇佣数)。
16 - emp.var.rate: employment variation rate - quarterly indicator (numeric)
11 - duration: last contact duration, in seconds (numeric).
20 - nr.employed: number of employees - quarterly indicator (numeric)
可见就业环境和接听推销电话的时长,能反映出客户的存贷款意愿,还是很符合直觉的。
# Model Variable Importance via Plot
exp.model_parts().plot()
# Model Profile
exp.model_profile(variables =['emp.var.rate','duration']).plot()
看曲线,就业率
是负相关的,即就业率越低,存贷款需求就越多,基本呈线性下降。
而通话时长
则是正相关的,沟通 1500 秒以上 (25分钟左右),则存贷款成功的可能性大大增加,至少代表了客户对存贷款业务有兴趣。
分析单个样本
选取一个样本
### Make A Prediction
ex1 = x_test.iloc[10]
# Expected Prediction
y_test.iloc[10]
输出:1
这是一个 29 岁的客户最终存贷款成功的案例。
sample = pd.DataFrame(ex1).T
sample
# Model Prediction
print("LR:",pipe_lr.predict(sample))
输出:LR: [1]
# Prediction
exp.predict(sample)
输出:array([0.61587757])
# Predict Parts
explanation = exp.predict_parts(sample)
# Plot Explanation of Prediction
explanation.plot()
13 - pdays: number of days that passed by after the client was last contacted from a previous campaign (numeric; 999 means client was not previously contacted)
19 - euribor3m: euribor 3 month rate - daily indicator (numeric)
分析一下模型的预测依据,绿色为存贷款成功依据,红色为存贷款不成功依据。
这个案例中,就业率
贡献了+0.503
,上次联系天数
贡献了+0.155
, 通话时长
在这个样本中反而没什么影响力,3个月的日利率
则降低了存贷款概率-0.307
....
以上特征指标综合起来,该客户办理存贷款业务的概率为 61.6%
。
# Prediction Profile
pred_profile = exp.predict_profile(sample, variables =['emp.var.rate','pdays','euribor3m','duration'])
pred_profile.plot()
我们也可以从实际生产环境中,找到一个模型预测错误的样本,来详细分析具体的原因,进而以此改进模型,扩增特定的数据集。
源码下载
本期相关文件资料,可在公众号“深度觉醒”,后台回复:“explore01”,获取下载链接。
下一篇预告
这一篇主要介绍模型的可解释性,并用Dalex
对一个银行业务的推荐模型进行了分析,接下来我们将继续讨论一下AI
模型安全性以及正义性上的问题。