web-dev-qa-db-ja.com

カテゴリカル入力を使用した回帰ツリーまたはランダムフォレストリグレッサー

回帰ツリー(またはランダムフォレストリグレッサ)でカテゴリカルインストを使用しようとしていますが、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置換など)。

他の誰かがこの困難を抱えていましたか?

ありがとう!

11
jpsfer

scikit-learnには、カテゴリ変数(Rの因子)専用の表現がありません。考えられる解決策の1つは、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]

ただし、abが独立したカテゴリであり、ツリーベースの推定量でのみ機能する場合、これはわずかなハックであることに注意してください。どうして? bは実際にはaより大きくないからです。正しい方法は、OneHotEncoderまたはpd.get_dummiesの後にLabelEncoderを使用して、X[:, 0]の2つの別々のワンホットエンコード列を生成することです。

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))
16
Matt

Pythonで手動でコードをダミーする必要があります。 1つのホットエンコーディングに pandas.get_dummies() を使用することをお勧めします。ブーストされたツリーの場合、順序エンコードを実現するために factorize() を使用して成功しました。

この種のもののパッケージ全体もあります ここ

詳細な説明については、 this Data Science StackExchangeの投稿をご覧ください。

1
Keith