客户案例 网站设计,企业建设网站的需求分析,网页空间租用,wordpress一个主站多个子站机器学习可解释性
1.模型洞察的价值2.特征重要性排列3.部分依赖图4.SHAP Value5.SHAP Value 高级使用
正文 每个特征怎么样影响预测结果#xff1f; 部分依赖图 Partial Dependence Plots
虽然特征重要性显示了哪些变量对预测影响最大#xff0c;但部分依赖图显示了特征如…机器学习可解释性
1.模型洞察的价值2.特征重要性排列3.部分依赖图4.SHAP Value5.SHAP Value 高级使用
正文 每个特征怎么样影响预测结果 部分依赖图 Partial Dependence Plots
虽然特征重要性显示了哪些变量对预测影响最大但部分依赖图显示了特征如何影响预测。 这对于回答以下问题很有用
控制所有其他房屋特征经度和纬度对房价有什么影响? 重申一下同样大小的房子在不同地区会如何定价?预测两组之间的健康差异是由于饮食的差异还是由于其他因素?
如果您熟悉线性或逻辑回归模型可以将部分依赖图解释为与这些模型中的系数。 然而复杂模型上的部分依赖图比简单模型上的系数可以捕获更复杂的样式。 如果你不熟悉线性或逻辑回归也不要担心这个比较。
我们将展示几个示例解释这些图的含义然后通过代码来实现这些图。
它是如何工作的
像排列重要性一样部分依赖图是在模型拟合后计算的。该模型适用于没有以任何方式人为操纵的真实数据。
在我们的足球例子中球队可能在许多方面有所不同。他们的传球次数射门次数进球次数等等。乍一看似乎很难理清这些特征的影响。
为了了解局部图如何分离出每个特征的影响我们首先考虑单行数据。例如这一行数据可能代表一支球队有50%的控球率传球100次射门10次进1球。
我们将使用拟合模型来预测我们的结果(他们的球员赢得“全场最佳球员”的概率)。但是我们反复改变一个变量的值来做出一系列的预测。如果球队只有40%的控球率我们就能预测结果。然后我们预测他们有50%的几率拿球然后再预测60%等等… 我们追踪预测结果(在纵轴上)当我们从小的控球值移动到大的值(在横轴上)。
在这个描述中我们只使用了一行数据。特征之间的相互作用可能导致单行的图是非典型的。因此我们用原始数据集中的多行重复这个心理实验并在纵轴上绘制平均预测结果。
代码示例
模型构建不是我们的重点所以我们不会关注数据探索或模型构建代码。
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.tree import DecisionTreeClassifierdata pd.read_csv(../input/fifa-2018-match-statistics/FIFA 2018 Statistics.csv)
y (data[Man of the Match] Yes) # Convert from string Yes/No to binary
feature_names [i for i in data.columns if data[i].dtype in [np.int64]]
X data[feature_names]
train_X, val_X, train_y, val_y train_test_split(X, y, random_state1)
tree_model DecisionTreeClassifier(random_state0, max_depth5, min_samples_split5).fit(train_X, train_y)我们的第一个示例使用决策树如下所示。在实践中您将在实际应用程序中使用更复杂的模型。
from sklearn import tree
import graphviztree_graph tree.export_graphviz(tree_model, out_fileNone, feature_namesfeature_names)
graphviz.Source(tree_graph)作为阅读树的指导: 有孩子的叶子在顶部显示了它们的分裂标准 底部的一对值分别显示了树的该节点中目标数据点的False值和True值的计数。
下面是使用scikit-learn库创建部分依赖图的代码。
from matplotlib import pyplot as plt
from sklearn.inspection import PartialDependenceDisplay# Create and plot the data
disp1 PartialDependenceDisplay.from_estimator(tree_model, val_X, [Goal Scored])
plt.show()y轴被解释为相对于基线值或最左边值的预测变化。 从这张特殊的图表中我们可以看到进球大大增加了你赢得“本场最佳球员”的机会。但在此之外的额外目标似乎对预测影响不大。
这里是另一个例子
feature_to_plot Distance Covered (Kms)
disp2 PartialDependenceDisplay.from_estimator(tree_model, val_X, [feature_to_plot])
plt.show()这张图似乎太简单了不能代表现实情况。但那是因为这个模型太简单了。您应该能够从上面的决策树中看到它准确地表示了模型的结构。
您可以很容易地比较不同模型的结构或含义。这是随机森林模型的相同图。
# 生成随机森林模型
rf_model RandomForestClassifier(random_state0).fit(train_X, train_y)disp3 PartialDependenceDisplay.from_estimator(rf_model, val_X, [feature_to_plot])
plt.show()这个模型认为如果你的球员在比赛过程中总共跑了100公里你就更有可能赢得比赛最佳球员。尽管跑得越多预测越低。
一般来说这条曲线的平滑形状似乎比决策树模型中的阶跃函数更可信。尽管这个数据集足够小我们在解释任何模型时都会很小心。
二维部分依赖图
如果您对特征之间的相互作用感到好奇2D部分依赖图也很有用。举个例子可以说明这一点。
对于这个图我们将再次使用决策树模型。它将创建一个非常简单的图但您应该能够将您在图中看到的与树本身相匹配。
fig, ax plt.subplots(figsize(8, 6))
f_names [(Goal Scored, Distance Covered (Kms))]
# Similar to previous PDP plot except we use tuple of features instead of single feature
disp4 PartialDependenceDisplay.from_estimator(tree_model, val_X, f_names, axax)
plt.show()这个图表显示了对进球数和覆盖距离的任何组合的预测。
例如当一支球队至少进一个球并且他们的总距离接近100公里时我们看到的预测最高。如果他们进了0球距离就不重要了。你能通过0个目标的决策树看到这一点吗?
但如果他们进球距离会影响预测。确保你能从二维部分依赖图中看到这一点。你能在决策树中看到这种模式吗?
轮到你了
用概念性问题和简短的编码挑战测试你的理解。 练习部分
设置
今天您将创建部分依赖图并使用来自出租车票价预测竞赛的数据练习构建解释。
我们再次提供了执行基本加载、检查和模型构建的代码。运行下面的单元格设置一切:
import pandas as pd
from sklearn.ensemble import RandomForestRegressor
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split# Environment Set-Up for feedback system.
from learntools.core import binder
binder.bind(globals())
from learntools.ml_explainability.ex3 import *
print(Setup Complete)# Data manipulation code below here
data pd.read_csv(../input/new-york-city-taxi-fare-prediction/train.csv, nrows50000)# Remove data with extreme outlier coordinates or negative fares
data data.query(pickup_latitude 40.7 and pickup_latitude 40.8 and dropoff_latitude 40.7 and dropoff_latitude 40.8 and pickup_longitude -74 and pickup_longitude -73.9 and dropoff_longitude -74 and dropoff_longitude -73.9 and fare_amount 0)y data.fare_amountbase_features [pickup_longitude,pickup_latitude,dropoff_longitude,dropoff_latitude]X data[base_features]train_X, val_X, train_y, val_y train_test_split(X, y, random_state1)
first_model RandomForestRegressor(n_estimators30, random_state1).fit(train_X, train_y)
print(Data sample:)
data.head()Data sample:
keyfare_amountpickup_datetimepickup_longitudepickup_latitudedropoff_longitudedropoff_latitudepassenger_count22011-08-18 00:35:00.000000495.72011-08-18 00:35:00 UTC-73.98273840.761270-73.99124240.75056232012-04-21 04:30:42.00000017.72012-04-21 04:30:42 UTC-73.98713040.733143-73.99156740.75809242010-03-09 07:51:00.0000001355.32010-03-09 07:51:00 UTC-73.96809540.768008-73.95665540.78376262012-11-20 20:35:00.00000017.52012-11-20 20:35:00 UTC-73.98000240.751662-73.97380240.76484272012-01-04 17:22:00.0000008116.52012-01-04 17:22:00 UTC-73.95130040.774138-73.99009540.751048
data.describe()-fare_amountpickup_longitudepickup_latitudedropoff_longitudedropoff_latitudepassenger_countcount31289.00000031289.00000031289.00000031289.00000031289.00000031289.000000mean8.483093-73.97686040.756917-73.97534240.7574731.656141std4.6281640.0146350.0181700.0159170.0186611.284899min0.010000-73.99999940.700013-73.99999940.7000200.00000025%5.500000-73.98803940.744947-73.98712540.7459221.00000050%7.500000-73.97969140.758027-73.97854740.7585591.00000075%10.100000-73.96782340.769580-73.96643540.7704272.000000max165.000000-73.90006240.799952-73.90006240.7999996.000000
问题1
下面是绘制pickup_longitude的部分依赖图的代码。运行以下单元格不做任何更改。
from matplotlib import pyplot as plt
from sklearn.inspection import PartialDependenceDisplayfeat_name pickup_longitude
PartialDependenceDisplay.from_estimator(first_model, val_X, [feat_name])
plt.show()为什么部分依赖图是U形的? 你的解释是否暗示了其他特征的部分依赖图的形状? 在下面的for循环中创建所有其他部分依赖图 (从上面的代码复制适当的行)。
for feat_name in base_features:____plt.show()答案输入 PartialDependenceDisplay.from_estimator(first_model, val_X, [feat_name]) 这些形状是否符合你对它们形状的期望?既然你看到了它们你能解释一下它们的形状吗?
结论 从重要性排序结果可以看出距离是出租车价格最重要的决定因素。
该模型不包括距离度量(如纬度或经度的绝对变化)作为特征因此坐标特征(如pickup_longitude)获取距离的影响。在经度值的中心附近上车平均预计票价会降低因为这意味着更短的行程(以平均计)。
出于同样的原因我们在所有的部分依赖图中都看到了统一的U形。
问题 2
现在你将运行一个二维部分依赖图。提醒一下下面是教程中的代码。
fig, ax plt.subplots(figsize(8, 6))
f_names [(Goal Scored, Distance Covered (Kms))]
PartialDependenceDisplay.from_estimator(tree_model, val_X, f_names, axax)
plt.show()为特征pickup_longitude和dropff_longitude创建一个2D图。
你觉得它会是什么样子?
fig, ax plt.subplots(figsize(8, 6))# Add your code here
____答案 f_names [(‘pickup_longitude’, ‘dropoff_longitude’)] PartialDependenceDisplay.from_estimator(first_model, val_X, f_names, axax) plt.show() 结论 您应该期望该情节具有沿对角线运行的等高线。我们在某种程度上看到了这一点尽管有一些有趣的警告。
我们期望得到对角线轮廓因为这些值对在取车和下车经度附近表明较短的行程(控制其他因素)。
当你离中央对角线越远我们应该预期价格会随着上下车经度之间的距离增加而增加。
令人惊讶的特征是当你向图表的右上方走得更远时价格就会上涨甚至在45度线附近。
这值得进一步研究尽管移动到图表右上方的影响与离开45度线相比较小。
创建所需情节所需的代码如下:
fig, ax plt.subplots(figsize(8, 6))
fnames [(pickup_longitude, dropoff_longitude)]
disp PartialDependenceDisplay.from_estimator(first_model, val_X, fnames, axax)
plt.show()问题 3
考虑一下从经度-73.955开始到经度-74结束的旅程。使用上一个问题的图表估计如果骑手在经度-73.98开始骑行他们会节省多少钱。
savings_from_shorter_trip _____ # Check your answer
q_3.check()提示首先找到与-74下降经度对应的垂直水平。然后读取正在切换的水平值。使用等高线来确定自己接近的值的方向。你可以四舍五入到最接近的整数而不是强调精确的数值。
答案 6
结论大约6。 价格从最高的15.16 下降至 8.34 即 15.16-8.346. 82 取整为6。 问题 4
到目前为止在您所看到的 部分依赖图(PDP)中位置特征主要用作捕捉旅行距离的代理。在置换重要性课程中您添加了abs_lon_change和abs_lat_change这两个特征作为距离的更直接度量。 在此处重新创建这些特征。你只需要填写最上面的两行。然后运行以下单元格。 运行它之后确定这个部分依赖图和没有绝对值特征的图之间最重要的区别。生成没有绝对值特征的PDP的代码位于该代码单元的顶部。
# This is the PDP for pickup_longitude without the absolute difference features. Included here to help compare it to the new PDP you create
feat_name pickup_longitude
PartialDependenceDisplay.from_estimator(first_model, val_X, [feat_name])
plt.show()# Your code here
# create new features
data[abs_lon_change] ____
data[abs_lat_change] ____features_2 [pickup_longitude,pickup_latitude,dropoff_longitude,dropoff_latitude,abs_lat_change,abs_lon_change]X data[features_2]
new_train_X, new_val_X, new_train_y, new_val_y train_test_split(X, y, random_state1)
second_model RandomForestRegressor(n_estimators30, random_state1).fit(new_train_X, new_train_y)feat_name pickup_longitude
disp PartialDependenceDisplay.from_estimator(second_model, new_val_X, [feat_name])
plt.show()# Check your answer
q_4.check()提示在创建abs_lat_change和abs_lon_change 特征时使用abs函数。你不需要改变其他任何事情。
答案 # create new features data[‘abs_lon_change’] abs(data.dropoff_longitude - data.pickup_longitude) data[‘abs_lat_change’] abs(data.dropoff_latitude - data.pickup_latitude) 结论 不同的是部分依赖图变小了。两个图的垂直值最低均为8.5。但是顶部图表中的最高垂直值在10.7左右底部图表中的最大垂直值在9.1以下。换句话说一旦控制了行驶的绝对距离pickup_lonitude对预测的影响就会更小。
问题 5
假设您只有两个预测特征我们称之为feat_a和feat_B。这两个特征的最小值均为-1最大值均为1。feat_A的部分依赖性图在其整个范围内急剧增加而feat_B的部分依赖关系图在其全部范围内以较慢的速率较不陡峭增加。 这是否保证feat_A将具有比feat_B更高的排列重要性。为什么 仔细考虑后取消对下面一行的注释以获得结论。
结论 不是的。这并不能保证feat_A更重要。例如feat_A在变化的情况下可能会产生很大的影响但99%的时间都可能只有一个值。在这种情况下置换feat_A并不重要因为大多数值都不会改变。
问题 6
下面的代码单元执行以下操作 创建两个特征X1和X2其随机值在[-22]范围内。 创建一个目标变量y该变量始终为1。 在给定X1和X2的情况下训练RandomForestRegressor模型来预测y。 创建X1的PDP图和X1与y的散点图。
你对PDP图会是什么样子有预测吗运行单元格查找结果。 修改y的初始化使我们的PDP图在[-1,1]范围内具有正斜率在其他地方具有负斜率。注意您应该只修改y的创建保持X1、X2和my_model不变。
import numpy as np
from numpy.random import randn_samples 20000# Create array holding predictive feature
X1 4 * rand(n_samples) - 2
X2 4 * rand(n_samples) - 2# Your code here
# Create y. you should have X1 and X2 in the expression for y
y np.ones(n_samples)# create dataframe
my_df pd.DataFrame({X1: X1, X2: X2, y: y})
predictors_df my_df.drop([y], axis1)my_model RandomForestRegressor(n_estimators30, random_state1).fit(predictors_df, my_df.y)
disp PartialDependenceDisplay.from_estimator(my_model, predictors_df, [X1])
plt.show()# Check your answer
q_6.check()提示考虑明确使用包含数学表达式的术语如X1-1
答案 将 y np.ones(n_samples) 修改为 y -2 * X1 * (X1-1) X1 - 2 * X1 * (X11) - X2 问题 7
创建一个包含2个特征和一个目标的数据集使第一个特征的pdp是平坦的但其排列重要性很高。我们将使用随机森林作为模型。 注意您只需要提供创建变量X1、X2和y的行。提供了构建模型和计算解释的代码。
import eli5
from eli5.sklearn import PermutationImportancen_samples 20000# Create array holding predictive feature
X1 ____
X2 ____
# Create y. you should have X1 and X2 in the expression for y
y ____# create dataframe because pdp_isolate expects a dataFrame as an argument
my_df pd.DataFrame({X1: X1, X2: X2, y: y})
predictors_df my_df.drop([y], axis1)my_model RandomForestRegressor(n_estimators30, random_state1).fit(predictors_df, my_df.y)disp PartialDependenceDisplay.from_estimator(my_model, predictors_df, [X1], grid_resolution300)
plt.show()perm PermutationImportance(my_model).fit(predictors_df, my_df.y)# Check your answer
q_7.check()# show the weights for the permutation importance you just calculated
eli5.show_weights(perm, feature_names [X1, X2])提示X1需要影响预测才能影响排列的重要性。但是平均效果需要为0才能满足PDP的要求。通过创建交互来实现这一点因此X1的效果取决于X2的值反之亦然。
答案 X1 4 * rand(n_samples) - 2 X2 4 * rand(n_samples) - 2 y X1 * X2 继续深入
部分依赖图可能非常有趣。我们有一个讨论组讨论你想看到的部分依赖图解决的现实世界主题或问题。
接下来了解SHAP 值如何帮助您理解每个预测的逻辑。