使用scikit-learn解释随机森林算法

文/CSDN 译者/赵屹华 校检/刘帝伟、朱正贵、李子健 责编/周建丁

赵屹华,计算广告工程师@搜狗,前生物医学工程师,关注推荐算法、机器学习领域。

绝大多数的随机森林算法库(包括scikit-learn)不暴露预测过程的树路径(tree paths)。sklearn的实现方法需要一个额外补丁来暴露。庆幸的是,scikit-learn自0.17版起在API中添加了两项功能,使得这个过程相对而言比较容易理解:获取用于预测的所有叶子节点的ID,并存储所有决策树的所有节点的中间值,而不仅仅只存叶子节点的。结合这两步,就可以获取每次独立预测的预测路径,同时根据查看路径来分解预测过程。

代码已经放在github上了(https://github.com/andosa/treeinterpreter),也可以用 pip install treeinterpreter进行安装。

注意:需要用到仍在开发中的scikit-learn 0.17,你在下面的链接中能找到安装方法http://scikit-learn.org/stable/install.html#install-bleeding-edge。

用treeinterpreter分解随机森林预测

我们选一个简单的数据集,训练一个随机森林模型,并用测试集进行预测,然后分解预测过程。

[py] view plaincopy

  1. from treeinterpreter import treeinterpreter as ti
  2. from sklearn.tree import DecisionTreeRegressor
  3. from sklearn.ensemble import RandomForestRegressor
  4. import numpy as np
  5. from sklearn.datasets import load_boston
  6. boston = load_boston()
  7. rf = RandomForestRegressor()
  8. rf.fit(boston.data[:300], boston.target[:300])

我们随机挑选两个预测价格不相同的样本。

[py] view plaincopy

  1. instances = boston.data[[300, 309]]
  2. print "Instance 0 prediction:", rf.predict(instances[0])
  3. print "Instance 1 prediction:", rf.predict(instances[1])

Instance 0 prediction: [ 30.76] Instance 1 prediction: [ 22.41]

随机森林模型对它们的预测结果迥然不同。这是为什么呢?我们接下来就把预测结果分为偏置项(也就是训练集的平均结果)和单个特征贡献值,以便于观察究竟哪些特征项造成了差异,差异程度有多大。

我们直接调用tree interpreter的predict方法,向其传入模型和数据作为参数。

[py] view plaincopy

  1. prediction, bias, contributions = ti.predict(rf, instances)

打印出这些结果:

[py] view plaincopy

  1. for i in range(len(instances)):
  2. print "Instance", i
  3. print "Bias (trainset mean)", biases[i]
  4. print "Feature contributions:"
  5. for c, feature in sorted(zip(contributions[i],
  6. boston.feature_names),
  7. key=lambda x: -abs(x[0])):
  8. print feature, round(c, 2)
  9. print "-"*20

Instance 0 Bias (trainset mean) 25.2849333333 Feature contributions: RM 2.73 LSTAT 1.71 PTRATIO 1.27 ZN 1.04 DIS -0.7 B -0.39 TAX -0.19 CRIM -0.13 RAD 0.11 INDUS 0.06 AGE -0.02 NOX -0.01 CHAS 0.0

--------------------

Instance 1 Bias (trainset mean) 25.2849333333 Feature contributions: RM -4.88 LSTAT 2.38 DIS 0.32 AGE -0.28 TAX -0.23 CRIM 0.16 PTRATIO 0.15 B -0.15 INDUS -0.14 CHAS -0.1 ZN -0.05 NOX -0.05 RAD -0.02

特征贡献值按照其绝对值从大到小排序。我们观察到第一个样本的预测结果较高,正贡献值主要来自RM、LSTAT和PTRATIO特征。第二个样本的预测值则低得多,因为RM特征实际上有很大的负面影响,它不会被其它特征的正面影响所抵消,因此使得预测值要低于数据集的平均水平。

分解的结果真的对吗?很容易检验:偏置和特征贡献值相加应该等于预测值:

[py] view plaincopy

  1. print prediction
  2. print biases + np.sum(contributions, axis=1)

[ 30.76 22.41] [ 30.76 22.41]

注意,在把贡献值相加时,我们需要对浮点数进行处理,所以经过四舍五入处理后的值可能略有不同。

比较两个数据集

这个方法的用武之地之一就是比较两个数据集。例如:

  • 理解造成两个数据集预测值差异的真正原因,比如是什么因素导致相邻两幢房屋的预测价值差异。
  • 调试模型和数据,例如解释为什么新数据的平均预测值和旧数据的不一样。

还是上面这个例子,我们把房价数据的测试集再一分为二,分别计算它们的平均预测价值。

[py] view plaincopy

  1. ds1 = boston.data[300:400]
  2. ds2 = boston.data[400:]
  3. print np.mean(rf.predict(ds1))
  4. print np.mean(rf.predict(ds2))

22.1912 18.4773584906

我们发现两个数据集的平均预测价值完全不同。现在我们就能细分导致差异的因素:究竟哪些特征项造成了差异,差异程度有多大。

[py] view plaincopy

  1. prediction1, bias1, contributions1 = ti.predict(rf, ds1)
  2. prediction2, bias2, contributions2 = ti.predict(rf, ds2)

我们再来计算每一维特征的平均贡献程度。

[py] view plaincopy

  1. totalc1 = np.mean(contributions1, axis=0)
  2. totalc2 = np.mean(contributions2, axis=0)

由于两个数据集的偏置项都一样(因为模型的训练集都一样),平均预测价值的差异只能来自于特征的贡献值。换句话说,特征贡献差异的总和应该与平均预测的差异相等,我们很容易验证

[py] view plaincopy

  1. print np.sum(totalc1 - totalc2)
  2. print np.mean(prediction1) - np.mean(prediction2)

3.71384150943 3.71384150943

最后,我们把每一维特征贡献的差异之和显示出来,正好就是平均预测值的差异。

[py] view plaincopy

  1. for c, feature in sorted(zip(totalc1 - totalc2,
  2. boston.feature_names), reverse=True):
  3. print feature, round(c, 2)

LSTAT 2.8 CRIM 0.5 RM 0.5 PTRATIO 0.09 AGE 0.08 NOX 0.03 B 0.01 CHAS -0.01 ZN -0.02 RAD -0.03 INDUS -0.03 TAX -0.08 DIS -0.14

分类树和森林

同样的方法也能用于分类树,查看特征对某个类别的预测概率值的影响力。

我们在iris数据集上做演示。

[py] view plaincopy

  1. from sklearn.ensemble import RandomForestClassifier
  2. from sklearn.datasets import load_iris
  3. iris = load_iris()
  4. rf = RandomForestClassifier(max_depth = 4)
  5. idx = range(len(iris.target))
  6. np.random.shuffle(idx)
  7. rf.fit(iris.data[idx][:100], iris.target[idx][:100])

接着用一个独立样本做预测。

[py] view plaincopy

  1. instance = iris.data[idx][100:101]
  2. print rf.predict_proba(instance)

拆分每一维特征的贡献值:

[py] view plaincopy

  1. prediction, bias, contributions = ti.predict(rf, instance)
  2. print "Prediction", prediction
  3. print "Bias (trainset prior)", bias
  4. print "Feature contributions:"
  5. for c, feature in zip(contributions[0],
  6. iris.feature_names):
  7. print feature, c

Prediction [[ 0. 0.9 0.1]] Bias (trainset prior) [[ 0.36 0.262 0.378]] Feature contributions: sepal length (cm) [-0.1228614 0.07971035 0.04315104] sepal width (cm) [ 0. -0.01352012 0.01352012] petal length (cm) [-0.11716058 0.24709886 -0.12993828] petal width (cm) [-0.11997802 0.32471091 -0.20473289]

我们看到对第二类预测能力最强的特征是花瓣长度和宽度,它们极大提高了预测的概率值。

总结

让随机森林算法的预测结果具有解释性也很容易,几乎达到了线性模型的解释能力。有了treeinterpreter,这个步骤只需几行代码就能搞定。


原文发布于微信公众号 - 大数据挖掘DT数据分析(datadw)

原文发表时间:2015-10-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏SimpleAI

【DL碎片2】神经网络中的优化算法

从【DL笔记1】到【DL笔记N】以及【DL碎片】系列,是我学习深度学习一路上的点点滴滴的记录,是从Coursera网课、各大博客、论文的学习以及自己的实践中总结...

873
来自专栏Brian

深度学习笔记-神经网络介绍

---- Deep Learning 学习笔记-第一周 Andrew Ng发布了新课程,业界评价很好。在看的过程中非常不错,我把一些重要的知识和要点进行了总结和...

3254
来自专栏智能算法

深度学习三人行(第5期)----深度学习中的优化器选择

上一期,我们一起学习了TensorFlow在训练深度网络的时候怎么解决梯度消失或梯度爆炸的问题,以及怎么尽可能的减少训练时间。

1001
来自专栏媒矿工厂

HDR质量评价技术

本文聚焦HDR质量评价技术,对于编解码、色调映射以及逆色调映射等不同任务,通常会采取不同的评价方法。本部分先从主观评价和客观评价两个角度对常用的HDR视觉质量评...

3083
来自专栏marsggbo

Andrew Ng机器学习课程笔记--week10(优化梯度下降)

本周主要介绍了梯度下降算法运用到大数据时的优化方法。 一、内容概要 Gradient Descent with Large Datasets Stochast...

2198
来自专栏深度学习自然语言处理

【收藏版】深度学习中的各种优化算法

说到优化算法,入门级必从SGD学起,老司机则会告诉你更好的还有AdaGrad / AdaDelta,或者直接无脑用Adam。可是看看学术界的最新paper,却发...

1162
来自专栏MelonTeam专栏

机器学习入门系列02,Regression 回归:案例研究

引用课程:http://speech.ee.ntu.edu.tw/~tlkagk/courses_ML16.html 先看这里,可能由于你正在查看这个平...

1967
来自专栏进击的程序猿

停下来思考下神经网络

在神经网络中backpropagation是非常重要的一个算法,backpropagation能帮助我们测量出每个weight对于最终输出错误的影响。

702
来自专栏人工智能头条

使用scikit-learn解释随机森林算法

2212
来自专栏机器之心

ICLR 2018论文评审结果出炉:一文概览论文 TOP 5

3605

扫码关注云+社区