Scikit-learn Random Forest - 模型因输入缩放而发生变化

数据挖掘 机器学习 Python scikit-学习 随机森林
2022-03-03 11:06:07

我读过的关于随机森林的所有内容都表明它们不需要对输入进行缩放,并且缩放不应影响模型的构建。这是另一个 SE 问题的引述(https://stats.stackexchange.com/questions/255765/does-random-forest-need-input-variables-to-be-scaled-or-centered):

随机森林基于树分区算法。

因此,没有类似于在一般回归策略中获得的系数,这将取决于自变量的单位。取而代之的是,获得一组分区规则,基本上是给定阈值的决定,这不应该随着缩放而改变。换句话说,树只看到特征中的等级。

基本上,数据的任何单调变换都不应该改变森林(在最常见的实现中)。

这是我目前正在使用的。如果我删除权重乘数,我会得到一个不同的模型(即不同的值model.score和不同的树深度),尽管random_state=0在这两种情况下都进行了设置。

model = RandomForestRegressor(n_estimators=10, criterion='mse', random_state=0)
weights = np.arange(1,self.x_train.shape[1]+1)[None,:]
# weights = [[ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10. 11. 12. 13. 14. 15.]]
model.fit(self.x_train * weights, self.y_train)

相比之下,我注意到如果我使用XGBRegressor而不是RandomForestRegressor,缩放不会改变模型。

我犯了一个明显的错误还是上面的解释不正确?

1个回答

在尝试使用随机数重新创建问题(并且最初失败)之后,我发现问题来自这样一个事实,x_train即我使用的数据包含具有非常小的接近零值的列。

要重新创建,第一部分只运行一次:

scale = 0.0001 # making this larger eliminates the issue
x_train = np.random.uniform(0,scale,size=(1000,10))
y_train = np.random.uniform(0,1,size=(x_train.shape[0]))

x_train然后对and使用相同的值y_train,运行下面的部分,但use_weights设置为Trueand then False

use_weights = True
model = RandomForestRegressor(n_estimators=10, random_state=0)

if use_weights:
    weights = np.arange(1,x_train.shape[1]+1)[None,:]
    model.fit(x_train * weights, y_train)
    prediction = model.predict(x_train * weights)
else:
    model.fit(x_train, y_train)
    prediction = model.predict(x_train)

print(prediction[0]) # changes based on use_weights value assuming scale is very small

附带说明一下,y_train真实数据集的值也非常小,我必须将它们乘以 100 或更多才能使模型运行。也就是说,在不扩大值的规模的情况下,它根本不会创建任何叶子y_train(通过get_depth在每棵树上运行该方法来确认)。

我想知道,这纯粹是一个数值不精确的问题,还是引擎盖下发生的随机森林计算所独有的?