我一直在尝试在回归树(或随机森林回归器)中使用分类的inpust,但是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替代)。
还有其他人遇到过这种困难吗?
谢谢!
答案 0 :(得分:16)
scikit-learn
没有分类变量的专用表示(在R中为a.k.a因子),一种可能的解决方案是使用int
将字符串编码为LabelEncoder
:
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]
但请记住,如果a
和b
是独立类别,这只是一个轻微的黑客攻击,它只适用于基于树的估算工具。为什么?因为b
并不比a
大。正确的方法是在OneHotEncoder
或LabelEncoder
之后使用pd.get_dummies
,为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))
答案 1 :(得分:1)
你必须在python中手动编写代码。我建议使用pandas.get_dummies()进行一次热编码。对于Boosted树,我使用factorize()成功实现了Ordinal编码。
还有一整套用于此类事情here。
有关更详细的说明,请参阅this Data Science Stack Exchange帖子。