在许多(业务)案例中,同样重要的是不仅要有一个准确的机器学习模型,还要有一个可解释的机器学习模型。通常,除了想知道我们的机器学习模型的房价预测是什么之外,我们还想知道为什么它是这么高/低,以及哪些特征在确定预测时最重要。另一个例子是预测客户流失 - 拥有一个能够成功预测哪些客户容易流失的机器学习模型是非常好的,但确定哪些变量很重要可以帮助我们及早发现甚至改进产品/服务!

了解机器学习模型的特征重要性可以通过多种方式使您受益,例如:

  • 通过更好地理解机器学习模型的逻辑,您不仅可以验证它是正确的,还可以通过仅关注重要变量来改进模型
  • 您可以删除不那么重要的x变量,并且在更短的训练时间内具有类似或更好的性能
  • 在某些商业案例中,为了解释性而牺牲一些准确性是有道理的。

这就是为什么在本文中,我想通过一个随机森林模型的例子来探索不同的方法来解释特征的重要性。它们中的大多数也适用于不同的模型,从线性回归开始,以XGBoost等黑盒结束。

需要注意的一点是,我们的模型越精确,我们就越能够信任特征重要性度量和其他解释。我假设我们构建的模型相当准确(因为每个数据科学家都会努力建立这样的模型),在本文中我将重点关注重要性度量。

数据

对于这个例子,我将使用波士顿房价数据集(所以回归问题)。但是本文中描述的方法与分类问题一样,唯一的区别是用于评估的度量。Python代码如下:

import pandas as pdfrom sklearn.datasets import load_bostonboston = load_boston()y = boston.targetX = pd.DataFrame(boston.data, columns = boston.feature_names)np.random.seed(seed = 42)X['random'] = np.random.random(size = len(X))X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size = 0.8, random_state = 42)

下面我检查随机特征和目标变量之间的关系。可以看出,散点图上没有模式,相关性几乎为0。

sns.scatterplot(x = 'random', y = 'target', data = X.assign(target = y)).set_title('Random feature vs. target variable', fontsize = 16)
sns.heatmap(X.assign(target = y).corr().round(2), cmap = 'Blues', annot = True).set_title('Correlation matrix', fontsize = 16)

这里需要注意的一点是,为CHAS解释相关性没有多大意义,因为它是一个二元变量,应该使用不同的方法。

基准模型

我训练一个普通的随机森林模型来获得一个基准。我设置了一个random_state以确保结果的可比性。我也使用bootstrap并设置,oob_score = True以便稍后我可以使用out-of-bag error。

简单地说,随机森林中的每棵树都在不同的数据集上进行训练,从原始数据中进行替换取样。这导致每个训练集中大约有2/3的不同观测值。out-of-bag误差是根据所有观测值计算的,但是对于计算每一行的误差,模型只考虑在训练过程中没有看到这一行的树。这类似于在验证集上对模型进行评估。查看如下Python代码:

from sklearn.ensemble import RandomForestRegressorrf = RandomForestRegressor(n_estimators = 100, n_jobs = -1, oob_score = True, bootstrap = True, random_state = 42)rf.fit(X_train, y_train)print('R^2 Training Score: {:.2f} OOB Score: {:.2f} R^2 Validation Score: {:.2f}'.format(rf.score(X_train, y_train),  rf.oob_score_, rf.score(X_valid, y_valid)))

R^2 Training Score: 0.93

OOB Score: 0.58

R^2 Validation Score: 0.76

模型中存在一些过度拟合,因为它在OOB样本上和验证集上的表现都差得多。但我们假设它已经足够好了,接下来是特征重要性(通过训练集的性能来衡量)。一些方法还可以用于验证/OOB集,以获得对不可见数据的进一步解释性。

特征重要性

默认Scikit-learn的特征重要性

让我们从决策树开始建立一些直觉。在决策树中,每个节点都是在一个特征中拆分值的条件,这样在拆分后,相类似的因变量值就会在同一个集合中结束。该条件基于杂质,分类问题为基尼杂质/信息增益(熵),回归树为其方差。因此,当训练一棵树时,我们可以计算出每个特征对减少加权杂质的贡献有多大。Scikit-Learn中的feature_importances_是基于这个逻辑的,但是在随机森林中,我们正在讨论的是对树上的杂质减少进行平均。

优点:

  • 快速计算
  • 易于检索

缺点:

  • 有偏见的方法,因为它倾向于夸大连续特征或高基数分类变量的重要性
base_imp = imp_df(X_train.columns, rf.feature_importances_)var_imp_plot(base_imp, 'Default feature importance (scikit-learn)')

似乎最重要的三大特征是:

  • RM:平均房间数量
  • LSTAT:人口lower status的百分比
  • DIS:到波士顿五个就业中心的加权距离

然而,令人惊讶的是,一列随机值竟然比以下内容更重要:

  • INDUS:城镇非零售商业用地比例
  • RAD:径向高速公路的可达性指数
  • ZN:占地面积超过25,000平方尺的住宅用地比例。
  • CHAS:Charles River虚拟变量(如果有河= 1;否则为0)

直观地说,这个特征对目标变量的重要性应该是零。让我们看看它是如何通过不同的方法进行评估的。

排列特征重要性

这种方法通过观察每个预测器的随机re-shuffling(从而保持变量的分布)如何影响模型性能来直接度量特征的重要性。

该方法可按以下步骤描述:

  1. 训练基线模型并通过传递验证集(或随机森林情况下设置的OOB)记录得分(准确度/R²/任何重要度量)。这也可以在训练集上完成,但代价是牺牲关于泛化的信息。
  2. 从所选数据集中的一个特征Re-shuffle值,再次将数据集传递给模型以获取预测并计算此已修改数据集的度量标准。特征重要性是基准分数与修改(置换)数据集之间的差异。
  3. 对数据集中的所有特征重复2.

优点:

  • 适用于任何模型
  • 合理有效
  • 可靠的技术
  • 无需在每次修改数据集时重新训练机器学习模型

缺点:

  • 比默认的feature_importances在计算上更昂贵
  • 排列重要性高估了相关预测因子的重要性

我将可视化Spearman的相关性。标准皮尔逊相关性的不同之处在于,它首先将变量转换为秩,然后在秩上运行皮尔逊相关性。

Spearman相关性:

  • 是非参数的
  • 不假设变量之间存在线性关系
  • 它寻找单调的关系。
from rfpimp import plot_corr_heatmapviz = plot_corr_heatmap(X_train, figsize=(15,10))viz.view()

rfpimp:关于这个库需要注意的一点是,我们必须我们必须以metric(model, X, y)的形式提供一个度量,这样我们就可以使用更高级的方法,比如使用随机森林的OOB评分。这个库已经包含了相应的函数(oob_regression_r2_score)。但是为了保持方法的一致性,我将计算训练集上的度量(失去了关于泛化的信息)。

from sklearn.metrics import r2_scorefrom rfpimp import permutation_importancesdef r2(rf, X_train, y_train): return r2_score(y_train, rf.predict(X_train))perm_imp_rfpimp = permutation_importances(rf, X_train, y_train, r2)perm_imp_rfpimp.reset_index(drop = False, inplace = True)var_imp_plot(perm_imp_rfpimp, 'Permutation feature importance (rfpimp)')

该图证实了我们上面所看到的,4个变量不如随机变量重要!令人惊讶的是......前4名保持不变。关于`rfpimp`的一个更好的特性是它包含处理共线特征问题的功能(这是显示Spearman相关矩阵背后的想法)。

eli5:rfpimp的基本方法和eli5的方法有一些不同。其中一些是:

  • 有参数cv和refit连接到使用交叉验证。在这个例子中,我将它们设置为None,因为我不使用它,但在某些情况下它可能会派上用场。
  • 有一个metric参数,在rfpimp中接受metric(model, X, y)形式的函数。如果未指定此参数,则该函数将使用score估计器的默认方法。
  • n_iter - 随机shuffle迭代次数,最终得分是平均值
import eli5from eli5.sklearn import PermutationImportanceperm = PermutationImportance(rf, cv = None, refit = False, n_iter = 50).fit(X_train, y_train)perm_imp_eli5 = imp_df(X_train.columns, perm.feature_importances_)var_imp_plot(perm_imp_eli5, 'Permutation feature importance (eli5)')

结果与前面的结果非常相似,尽管这些结果来自于每列的多次reshuffles。eli5的另一个优点是,通过使用Scikit-learn的SelectFromModel或RFE,可以很容易地使用置换方法的结果进行特征选择。

删除列特征重要性

这种方法非常直观,因为我们通过将模型与所有特征进行比较来研究特征的重要性,而将模型与此特征进行比较以进行训练。

我为下面的方法创建了一个函数(基于rfpimp的实现),它显示了底层逻辑。

优点:

  • 最准确的特征重要性

缺点:

  • 由于为数据集的每个变体重新训练模型而导致潜在的高计算成本(在删除单个特征列之后)
from sklearn.base import clone def drop_col_feat_imp(model, X_train, y_train, random_state = 42):  # clone the model to have the exact same specification as the one initially trained model_clone = clone(model) # set random_state for comparability model_clone.random_state = random_state # training and scoring the benchmark model model_clone.fit(X_train, y_train) benchmark_score = model_clone.score(X_train, y_train) # list for storing feature importances importances = []  # iterating over all columns and storing feature importance (difference between benchmark and new model) for col in X_train.columns: model_clone = clone(model) model_clone.random_state = random_state model_clone.fit(X_train.drop(col, axis = 1), y_train) drop_col_score = model_clone.score(X_train.drop(col, axis = 1), y_train) importances.append(benchmark_score - drop_col_score)  importances_df = imp_df(X_train.columns, importances) return importances_dfdrop_imp = drop_col_feat_imp(rf, X_train, y_train)var_imp_plot(drop_imp, 'Drop Column feature importance')

这里很有趣。首先,在这种情况下的负面重要性意味着从模型中删除给定的特征实际上提高了性能。这在随机情况下是很好的,但奇怪的是,在删除DIS之后可以观察到最高的性能提升,DIS是之前方法中第三个最重要的变量。不幸的是,我没有一个很好的解释。

观察水平特征重要性

通过观察水平特征重要性,我指的是对解释给予模型的特定观察具有最大影响的那些。例如,在信用评分的情况下,我们可以说这些特征对确定客户的信用评分影响最大。

Treeinterpreter

treeinterpreter的主要思想是使用随机森林中的底层树来解释每个特性如何贡献最终值。我们可以观察到预测的值(定义为每个特征贡献的总和+基于整个训练集的初始节点给出的平均值)在决策树中的预测路径上(每次分割之后)是如何变化的,

以及导致分裂的信息(预测的变化也是如此)。

预测函数的公式(f(x))可以写为:

其中c_full是整个数据集(初始节点)的平均值,K是特征的总数。

这可能听起来很复杂,但请看一下库作者的一个例子:

由于随机森林的预测是树的平均值,因此平均预测的公式如下:

其中J是森林中树的数量

我首先确定具有最低和最高绝对预测误差的行,并尝试查看导致差异的原因。Python实现如下:

pred_diff = pd.DataFrame({'difference': abs(y_train - rf.predict(X_train))})print('Index with smallest error:', pred_diff.sort_values('difference').head(1).index.values[0])print('Index with largest error:', pred_diff.sort_values('difference', ascending = False).head(1).index.values[0])

Index with smallest error: 31

Index with largest error: 85

使用treeintrerpreter I获得3个对象:预测、偏差(数据集的平均值)和贡献。

for i in range(len(selected_rows)): print("Row

随机森林的特征 是放回抽样么_通过随机森林的例子解释特征重要性相关推荐

  1. 通过随机森林的例子解释特征重要性

    https://www.toutiao.com/a6657142683347190284/ 2019-02-12 23:53:35 在许多(业务)案例中,同样重要的是不仅要有一个准确的机器学习模型,还 ...

  2. 随机森林的特征 是放回抽样么_机器学习超详细实践攻略(10):随机森林算法详解及小白都能看懂的调参指南...

    一.什么是随机森林 前面我们已经介绍了决策树的基本原理和使用.但是决策树有一个很大的缺陷:因为决策树会非常细致地划分样本,如果决策树分得太多细致,会导致其在训练集上出现过拟合,而如果决策树粗略地划分样 ...

  3. python随机森林筛选变量_用随机森林分类器和GBDT进行特征筛选

    一.决策树(类型.节点特征选择的算法原理.优缺点.随机森林算法产生的背景) 1.分类树和回归树 由目标变量是离散的还是连续的来决定的:目标变量是离散的,选择分类树:反之(目标变量是连续的,但自变量可以 ...

  4. python随机森林变量重要性_利用随机森林对特征重要性进行评估

    前言 随机森林是以决策树为基学习器的集成学习算法.随机森林非常简单,易于实现,计算开销也很小,更令人惊奇的是它在分类和回归上表现出了十分惊人的性能,因此,随机森林也被誉为"代表集成学习技术水 ...

  5. python随机森林特征重要性_基于随机森林识别特征重要性(翻译)

    博主Slav Ivanov 的文章<Identifying churn drivers with Random Forests >部分内容翻译.博主有一款自己的产品RetainKit,用A ...

  6. 通过氨基酸频率特征量来预测蛋白热稳定性——随机森林算法

    一.随机森林算法原理 随机森林算法生成过程: 1.从原始数据集中每次随机有放回抽样选取与原始数据集相同数量的样本数据,构造数据子集: 2.每个数据子集从所有待选择的特征中随机选取一定数量的最优特征作为 ...

  7. 随机森林原始论文_初识随机森林

    在机器学习中,随机森林是一个包含多个决策树的分类器, 并且其输出的类别是由个别树输出的类别的众数而定. 发展出推论出随机森林的算法. 而 "Random Forests" 是他们的 ...

  8. R语言构建随机森林模型randomForest分类模型并评估模型在测试集和训练集上的效果(accuray、F1、偏差Deviance):随机森林在Bagging算法的基础上加入了列采样(分枝特征随机)

    R语言构建随机森林模型randomForest分类模型并评估模型在测试集和训练集上的效果(accuray.F1.偏差Deviance):随机森林在Bagging算法的基础上加入了列采样(分枝特征随机) ...

  9. Python计算树模型(随机森林、xgboost等)的特征重要度及其波动程度:基于熵减的特征重要度计算及可视化、基于特征排列的特征重要性(feature permutation)计算及可视化

    Python计算树模型(随机森林.xgboost等)的特征重要度及其波动程度:基于熵减的特征重要度计算及可视化.基于特征排列的特征重要性(feature permutation)计算及可视化 目录

最新文章

  1. 临时表temporary table
  2. 推荐几个小而美的原创公众号!
  3. Ajax 基础——未完待续
  4. input限制输入小数点后两位(vue版本)
  5. 计算机数据库原理试题,计算机科学与技术专业《数据库原理》模拟试题(B)
  6. 奚江华的几篇Silverlight文章
  7. mysql 文件批量插入_mysql大批量插入数据的4种方法示例
  8. [原创]c# 加解密通用类
  9. AppLinks使用详解
  10. 台式计算机颜色如何矫正,台式机怎么颜色校正操作教程
  11. mysql字段命名_数据库表及字段命名规范
  12. 北京调频(FM)无线广播发射频率/频道表 (转载)
  13. java 调用阿里云翻译
  14. 医学图像处理——基本概念(色彩、直方图、CT值)
  15. 运放的原理、应用、参数和命名规则
  16. 大学两年时间的一些感悟
  17. Android 获得联系人并排序
  18. Github 未添加密钥报错
  19. 读书笔记 - 智能体技术在城市交通信号控制系统中应用综述2014
  20. PyQt5教程(八)——实现QQ登录界面(二、加载资源文件)

热门文章

  1. IBA公司亚太区总裁SIGI、中核质子董事长孙月飞等一行人参观访问杭州医药港小镇
  2. 解读GaussDB(for Influx)的数据压缩
  3. ZYNQ7020双核AMP(linux+裸机)方案
  4. 简单易懂读《重构》 - Primitive Obesession (基本类型偏执)
  5. 记一次问题定位:plsql配置tnsnames不生效
  6. 美容行业小程序的特点
  7. pycharm获取yelp相关数据(五)
  8. nxp管理芯片的封装与基本原理
  9. python apply()函数
  10. 舔狗的救赎:学最牛的技术,做最强的舔狗