Partial Dependence Plot
Partial Dependence就是用来解释某个特征和目标值y的关系的,一般是通过画出Partial Dependence Plot(PDP)来体现。
PDP是依赖于模型本身的,所以我们需要先训练模型(比如训练一个random forest模型)。假设我们想研究y和特征\(X_1\)的关系,那么PDP就是一个关于\(X_1\)和模型预测值的函数。我们先拟合了一个随机森林模型RF(X),然后用\(X_k^{i}\)表示训练集中第k个样本的第i个特征,那么PDP的函数就是
也就是说PDP在\(X_1\)的值,就是把训练集中第一个变量换成\(X_1\)之后,原模型预测出来的平均值。
根据\(X_1\)的不同取值,\(f(X_1)\)就可以练成折线,这个折线就是Partial Dependence Plot,横轴是\(X_1\),纵轴就是Partial Dependence。
下图就是一个例子
自己写代码模拟:
from sklearn.tree import DecisionTreeRegressor
from sklearn.inspection import partial_dependence
from sklearn.datasets import load_boston
import numpy as np
import matplotlib.pyplot as plt
data = load_boston()
X, y = data.data, data.target
dtr = DecisionTreeRegressor()
dtr.fit(X,y)
def my_pdp(model, X, feat_idx):
fmax, fmin = np.max(X[:, feat_idx]), np.min(X[:, feat_idx])
frange = np.linspace(fmin, fmax, 100)
preds = []
for x in frange:
X_ = X.copy()
X_[:, feat_idx] = x
pred = model.predict(X_)
preds.append(np.mean(pred))
return (frange, np.array(preds))
del dtr.classes_
my_data = my_pdp(dtr, X, 0)
sk_data = partial_dependence(dtr, X = X, features = [0], percentiles=[0,1])
plt.subplot(121)
plt.plot(my_data[0], my_data[1])
plt.subplot(122)
plt.plot(sk_data[1][0], sk_data[0][0])
plt.show()
Github python library PDPbox
优点
pdp的计算是直观的:partial dependence function 在某个特定特征值位置表示预测的平均值,如果我们强制所有的数据点都取那个特征值。在我的经验中,lay people(普通人,没有专业知识的大众)通常都可以很快理解PDPs的idea。
如果你要计算的PDP的特征和其它特征没有关联,那么PDP可以完美的展示出这个特征大体上上如何影响预测值的。在不相关的情况下,解释是清晰的:PDP展示了平均预测值在某个特征改变时是如何变化的。如果特征是相互关联的,这会变得更加复杂。
不足
实际分析PDP时的最大特征个数是2。这不是PDP的错误,而是由于我们人无法想象超过三维的空间。
有一些 PDP并不展示特征分布。忽略分布可能会造成误解,因为你可能会过度解读具有少量数据的地方。这个问题通过展示一个rug或者histogram在x轴上的方式很容易解决。
独立性假设是PDP的最大问题,它假设计算的特征和其它特征是不相关的。当特征是相关的时候,我们创造的新的数据点在特征分布的空间中出现的概率是很低的。对这个问题的一个解决方法就是Accumulate Local Effect plots,或者简称ALE plots,它工作在条件分布下而不是边缘分布下。
多种类的影响可能会被隐藏,因为PDP仅仅展示边际影响的平均值。假设对于一个要计算的特征,一半的数据点对预测有正相关性,一半的数据点对预测有负相关性。PD曲线可能会是一个水平的直线,因为两半数据点的影响可能会互相抵消。然后你可能会得出特征对预测没有影响的结论。通过绘制individual conditional expectation curves而不是aggregated line,我们可以揭示出这种heterogeneous effects。
posted on 2019-05-31 10:01 Frank_Allen 阅读(5932) 评论(1) 编辑 收藏 举报