具有分类输入的回归树或随机森林回归器

Posted

技术标签:

【中文标题】具有分类输入的回归树或随机森林回归器【英文标题】:Regression trees or Random Forest regressor with categorical inputs 【发布时间】:2013-12-04 09:37:42 【问题描述】:

我一直在尝试在回归树(或随机森林回归器)中使用分类输入,但 sklearn 不断返回错误并要求输入数字。

import sklearn as sk
MODEL = sk.ensemble.RandomForestRegressor(n_estimators=100)
MODEL.fit([('a',1,2),('b',2,3),('a',3,2),('b',1,3)], [1,2.5,3,4]) # does not work
MODEL.fit([(1,1,2),(2,2,3),(1,3,2),(2,1,3)], [1,2.5,3,4]) #works

MODEL = sk.tree.DecisionTreeRegressor()
MODEL.fit([('a',1,2),('b',2,3),('a',3,2),('b',1,3)], [1,2.5,3,4]) # does not work
MODEL.fit([(1,1,2),(2,2,3),(1,3,2),(2,1,3)], [1,2.5,3,4]) #works

据我了解,这些方法中的分类输入应该是可能的,无需任何转换(例如 WOE 替换)。

还有其他人遇到过这种困难吗?

谢谢!

【问题讨论】:

【参考方案1】:

scikit-learn 没有用于分类变量(也就是 R 中的因子)的专用表示,一种可能的解决方案是使用 LabelEncoder 将字符串编码为 int

import numpy as np
from sklearn.preprocessing import LabelEncoder  
from sklearn.ensemble import RandomForestRegressor

X = np.asarray([('a',1,2),('b',2,3),('a',3,2),('c',1,3)]) 
y = np.asarray([1,2.5,3,4])

# transform 1st column to numbers
X[:, 0] = LabelEncoder().fit_transform(X[:,0]) 

regressor = RandomForestRegressor(n_estimators=150, min_samples_split=2)
regressor.fit(X, y)
print(X)
print(regressor.predict(X))

输出:

[[ 0.  1.  2.]
 [ 1.  2.  3.]
 [ 0.  3.  2.]
 [ 2.  1.  3.]]
[ 1.61333333  2.13666667  2.53333333  2.95333333]

但请记住,如果 ab 是独立的类别并且它仅适用于基于树的估计器,则这是一个小技巧。为什么?因为b 并不比a 大。正确的方法是在LabelEncoderpd.get_dummies 之后使用OneHotEncoder,为X[:, 0] 生成两个单独的单热编码列。

import numpy as np
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
from sklearn.ensemble import RandomForestRegressor

X = np.asarray([('a',1,2),('b',2,3),('a',3,2),('c',1,3)]) 
y = np.asarray([1,2.5,3,4])

# transform 1st column to numbers
import pandas as pd
X_0 = pd.get_dummies(X[:, 0]).values
X = np.column_stack([X_0, X[:, 1:]])

regressor = RandomForestRegressor(n_estimators=150, min_samples_split=2)
regressor.fit(X, y)
print(X)
print(regressor.predict(X))

【讨论】:

谢谢。我不认为它可以解决问题。 “数字标签”创建了一个线性进展的假设,这很可能与您试图预测的内容不相符。想象一个决策树节点,在决定下一个截止分割时,例如使用 '=2' 与“if in ('a','c')”的意义不同。 我看错了你的问题。我刚刚看到您想将所有内容都视为分类。我将相应地更新示例... 这很有帮助,我已经尝试过了(我应该说代码不太优雅),但问题是这使得变量中包含的信息不太可能在回归树中被选择。我猜这是因为预测能力现在分散在多个变量中。尽管如此,您的代码对于如何更有效地执行此操作非常有帮助。非常感谢。【参考方案2】:

您必须在 python 中手动编写虚拟代码。我建议使用pandas.get_dummies() 进行一种热编码。对于 Boosted 树,我已经成功使用 factorize() 来实现 Ordinal Encoding。

这种东西还有一整套here。

有关更详细的解释,请查看this Data Science Stack Exchange 帖子。

【讨论】:

以上是关于具有分类输入的回归树或随机森林回归器的主要内容,如果未能解决你的问题,请参考以下文章

随机森林回归器的特征选择

MATLAB-随机森林实现数据回归分析预测

张量流随机森林回归

如何使用不同尺寸的多个分类输入变量为随机森林回归模型?

Bagging策略和随机森林的应用以及线性回归与局部加权回归三种实例(线性回归AdaBoostGradientBoostingRegressor)机器学习

随机森林(分类与回归)