And*_* Ph 5 python machine-learning random-forest scikit-learn
在使用 RandomForestRegressor 时,我注意到一些奇怪的事情。为了说明问题,这里有一个小例子。我在测试数据集上应用了 RandomForestRegressor 并绘制了森林中第一棵树的图。这给了我以下输出:
Root_node:
mse=8.64
samples=2
value=20.4
Left_leaf:
mse=0
samples=1
value=24
Right_leaf:
mse=0
samples=1
value=18
Run Code Online (Sandbox Code Playgroud)
首先,我希望根节点的值为(24+18)/2=21。但不知何故,它是 20.4。但是,即使这个值是正确的,我如何获得 8.64 的 mse?从我的角度来看,它应该是:(1/2[(24-20.4)^2+(18-20.4)^2]=9.36假设根值 20.4 是正确的)
我的解决办法是:1/2[(24-21)^2+(18-21)^2]=9。如果我只使用 DecisionTreeRegressor,这也是我得到的结果。
RandomForestRegressor 的实现有什么问题还是我完全错了?
这是我的可重现代码:
import pandas as pd
from sklearn import tree
from sklearn.ensemble import RandomForestRegressor
import graphviz
# create example dataset
data = {'AGE': [91, 42, 29, 94, 85], 'TAX': [384, 223, 280, 666, 384], 'Y': [19, 21, 24, 13, 18]}
df = pd.DataFrame(data=data)
x = df[['AGE','TAX']]
y = df[['Y']]
rf_reg = RandomForestRegressor(max_depth=2, random_state=1)
rf_reg.fit(x,y)
# plot a single tree of forest
dot_data = tree.export_graphviz(rf_reg.estimators_[0], out_file=None, feature_names=x.columns)
graph = graphviz.Source(dot_data)
graph
Run Code Online (Sandbox Code Playgroud)
和输出图:
太长了;博士
这是由于引导采样。
详细:
在默认设置下bootstrap=True,RF在构建各个树时将使用引导采样;引用交叉验证线程随机森林中每棵树的样本数:
如果
bootstrap=True,则对于每棵树,从训练集中随机抽取 N 个样本并进行替换,并且树是基于新版本的训练数据构建的。这在训练过程中引入了随机性,因为每棵树都会在稍微不同的训练集上进行训练。预计,从大小为 N 的数据集中抽取 N 个带有替换的样本将从原始集中选择约 2/3 的唯一样本。
“替换”意味着某些样本可能会被多次选择,而其他样本将被排除,所选样本的总数仍等于原始数据集的样本数(此处为5)。
您显示的树中实际发生的情况是,尽管 Graphviz 显示,但这应该被理解为唯一样本samples=2的数量;根节点中总共有5 个(引导)样本:2 个样本的副本和 3 个样本的副本(回想一下,根据引导采样过程的定义,这里的根节点必须包含 5 个样本,不能再多)也不少)。y=24y=18
现在显示的值相加:
# value:
(2*24 + 3*18)/5
# 20.4
# mse:
(2*(24-20.4)**2 + 3*(18-20.4)**2)/5
# 8.64
Run Code Online (Sandbox Code Playgroud)
显然,无论是在 Graphviz 可视化中还是在底层中,似乎都有一些设计选择,DecisionTreeRegressor以便仅存储/显示唯一样本的数量,这可能(或可能不是)打开 Github 问题的原因,但这目前的情况是这样的(说实话,我自己也不确定我是否希望在此处显示实际的样本总数,包括由于引导采样而产生的重复项)。
RF 和 Bagging 分类器模型的情况类似 - 分别参见:
| 归档时间: |
|
| 查看次数: |
197 次 |
| 最近记录: |