web-dev-qa-db-ja.com

カテゴリカルデータをSklearnディシジョンツリーに渡す

カテゴリカルデータをSklearn Decissionツリーにエンコードする方法に関する投稿がいくつかありますが、Sklearnのドキュメントからこれらを取得しました

デシジョンツリーの利点は次のとおりです。

(...)

数値データとカテゴリデータの両方を処理できます。通常、他の手法は、変数のタイプが1つしかないデータセットの分析に特化しています。詳細については、アルゴリズムを参照してください。

しかし、次のスクリプトを実行する

import pandas as pd
from sklearn.tree import DecisionTreeClassifier

data = pd.DataFrame()
data['A'] = ['a','a','b','a']
data['B'] = ['b','b','a','b']
data['C'] = [0, 0, 1, 0]
data['Class'] = ['n','n','y','n']

tree = DecisionTreeClassifier()
tree.fit(data[['A','B','C']], data['Class'])

次のエラーを出力します。

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/site-packages/sklearn/tree/tree.py", line 154, in fit
    X = check_array(X, dtype=DTYPE, accept_sparse="csc")
  File "/usr/local/lib/python2.7/site-packages/sklearn/utils/validation.py", line 377, in check_array
    array = np.array(array, dtype=dtype, order=order, copy=copy)
ValueError: could not convert string to float: b

Rでは、Sklearnを使用してカテゴリデータを渡すことができることを知っていますか?

48
0xhfff

受け入れられた答えに反して、私はこの目的のためにScikit-Learnが提供するツールを使用したいと思います。そうする主な理由は、 パイプライン に簡単に統合できるからです。

Scikit-Learn自体は、カテゴリデータを処理するための非常に優れたクラスを提供します。カスタム関数を記述する代わりに、 LabelEncoder を使用する必要があります。これは、この目的のために特別に設計されたです

ドキュメントの次のコードを参照してください。

from sklearn import preprocessing
le = preprocessing.LabelEncoder()
le.fit(["paris", "paris", "tokyo", "amsterdam"])
le.transform(["tokyo", "tokyo", "paris"]) 

これにより、機械学習アルゴリズムの数値に自動的にエンコードされます。現在、これは整数から文字列に戻ることもサポートしています。これを行うには、次のようにinverse_transformを呼び出すだけです。

list(le.inverse_transform([2, 2, 1]))

これは['tokyo', 'tokyo', 'paris']を返します。

また、ロジスティック回帰やSVMなどの決定ツリー以外の多くの分類器では、 One-Hot encoding を使用してカテゴリ変数をエンコードすることに注意してください。 Scikit-learnは、これも OneHotEncoder クラスを通じてサポートしています。

お役に立てれば!

6
Abhinav Arora

(これは 上記の私のコメント 2016からの再フォーマットに過ぎません...それはまだ当てはまります。)

この質問に対する受け入れられた答えは誤解を招くものです。

現状では、sklearn決定木はカテゴリデータを処理しません- 問題#5442を参照

ラベルエンコーディングを使用する推奨アプローチは、DecisionTreeClassifier()を数値として扱う整数に変換します。カテゴリデータが序数でない場合、これは良くありません-意味のない分割になってしまいます。

OneHotEncoderを使用することが唯一の現在有効な方法であり、ラベルの順序に依存しない任意の分割を許可しますが、計算コストが高くなります。

9
James Owers

(..)

数値データとカテゴリデータの両方を処理できます。

これは、使用できることだけを意味します

  • 分類問題のDecisionTreeClassifierクラス
  • 回帰用のDecisionTreeRegressorクラス。

いずれにせよ、ツリーをsklearnに適合させる前に、カテゴリ変数をワンホットエンコードする必要があります。

import pandas as pd
from sklearn.tree import DecisionTreeClassifier

data = pd.DataFrame()
data['A'] = ['a','a','b','a']
data['B'] = ['b','b','a','b']
data['C'] = [0, 0, 1, 0]
data['Class'] = ['n','n','y','n']

tree = DecisionTreeClassifier()

one_hot_data = pd.get_dummies(data[['A','B','C']],drop_first=True)
tree.fit(one_hot_data, data['Class'])
7
Guillaume

Sklearnディシジョンツリーは、カテゴリ文字列の数値への変換を処理しません。 Sklearnで関数を見つけることをお勧めします(おそらく this )。そうするか、次のようなコードを手動で記述します。

def cat2int(column):
    vals = list(set(column))
    for i, string in enumerate(column):
        column[i] = vals.index(string)
    return column
3
mrwyatt