Update
如今我对 ML 的了解比 2.5 年前更加丰富,我现在会说这种方法仅适用于高度线性的决策问题。如果你不小心将它应用于非线性问题,你就会遇到麻烦。
Example:想象一个特征,它既不能很大也不能很小的值可以预测类别,但某个中间区间的值可以预测类别。这可能是通过摄入水量来预测脱水。但水的摄入量可能与盐的摄入量相互作用,因为吃更多的盐可以摄入更多的水。现在两个非线性特征之间存在交互。决策边界围绕特征空间蜿蜒以对这种非线性进行建模,并且仅询问其中一个特征对脱水风险的影响程度是无知的。这不是正确的问题。
选择:您可以问的另一个更有意义的问题是:如果我没有此信息(如果我遗漏了此功能),我对给定标签的预测会受到多大影响?为此,您只需省略一个功能,训练一个模型,然后查看每个类别的精确度和召回率下降了多少。它仍然告知特征重要性,但它不对线性做出任何假设。
以下是旧答案.
我不久前解决了类似的问题并发布了交叉验证上有同样的问题 https://stats.stackexchange.com/questions/151762/class-specific-feature-importance. 简短的答案是没有实施sklearn
这就是你想要的一切。
然而,您想要实现的目标实际上非常简单,可以通过将每个类上每个特征分割的平均标准化平均值乘以相应的model._feature_importances
数组元素。您可以编写一个简单的函数来标准化数据集,计算跨类预测的每个特征的平均值,并与model._feature_importances
大批。绝对结果值越大,这些特征对其预测类别就越重要,更好的是,符号会告诉您重要的值是小还是大。
这是一个超级简单的实现需要一个数据矩阵X
,预测列表Y
以及特征重要性数组,并输出描述每个特征对每个类的重要性的 JSON。
def class_feature_importance(X, Y, feature_importances):
N, M = X.shape
X = scale(X)
out = {}
for c in set(Y):
out[c] = dict(
zip(range(N), np.mean(X[Y==c, :], axis=0)*feature_importances)
)
return out
Example:
import numpy as np
import json
from sklearn.preprocessing import scale
X = np.array([[ 2, 2, 2, 0, 3, -1],
[ 2, 1, 2, -1, 2, 1],
[ 0, -3, 0, 1, -2, 0],
[-1, -1, 1, 1, -1, -1],
[-1, 0, 0, 2, -3, 1],
[ 2, 2, 2, 0, 3, 0]], dtype=float)
Y = np.array([0, 0, 1, 1, 1, 0])
feature_importances = np.array([0.1, 0.2, 0.3, 0.2, 0.1, 0.1])
#feature_importances = model._feature_importances
result = class_feature_importance(X, Y, feature_importances)
print json.dumps(result,indent=4)
{
"0": {
"0": 0.097014250014533204,
"1": 0.16932975630904751,
"2": 0.27854300726557774,
"3": -0.17407765595569782,
"4": 0.0961523947640823,
"5": 0.0
},
"1": {
"0": -0.097014250014533177,
"1": -0.16932975630904754,
"2": -0.27854300726557779,
"3": 0.17407765595569782,
"4": -0.0961523947640823,
"5": 0.0
}
}
第一级按键result
是类标签,第二级键是列索引,即特征索引。回想一下,大的绝对值对应于重要性,并且符号告诉您重要的是小值(可能是负值)还是大值。