Sk-learnでラベルエンコーディングの不明な値を処理するにはどうすればよいですか?ラベルエンコーダーは、新しいラベルが検出されたことを除いて、爆発するだけです。
私が欲しいのはカテゴリ変数のエンコーディングone-hot-encoderです。ただし、sk-learnはそのための文字列をサポートしていません。そこで、各列にラベルエンコーダーを使用しました。
私の問題は、パイプラインの相互検証ステップで不明なラベルが表示されることです。基本的なワンホットエンコーダーには、このような場合を無視するオプションがあります。アプリオリpandas.getDummies /cat.codes
は、パイプラインが未知のラベルを含む可能性のある実際の新鮮な受信データで動作する必要があるため、十分ではありません。
この目的でCountVectorizer
を使用することは可能ですか?
編集:
Scikit-learnを使用してこの問題を処理するより最近の簡単な方法は、クラスsklearn.preprocessing.OneHotEncoder
を使用することです。
from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder(handle_unknown='ignore')
enc.fit(train)
enc.transform(train).toarray()
古い答え:
このための方法としてpandas.get_dummies
について言及している回答がいくつかありますが、labelEncoder
アプローチの方がモデルを実装するのにすっきりしています。他の同様の回答では、このためにDictVectorizer
を使用することについて言及していますが、DataFrame
全体をdictに変換することは、おそらく素晴らしいアイデアではありません。
次の問題のある列を想定します。
from sklearn import preprocessing
import numpy as np
import pandas as pd
train = {'city': ['Buenos Aires', 'New York', 'Istambul', 'Buenos Aires', 'Paris', 'Paris'],
'letters': ['a', 'b', 'c', 'd', 'a', 'b']}
train = pd.DataFrame(train)
test = {'city': ['Buenos Aires', 'New York', 'Istambul', 'Buenos Aires', 'Paris', 'Utila'],
'letters': ['a', 'b', 'c', 'a', 'b', 'b']}
test = pd.DataFrame(test)
Utilaはまれな都市であり、トレーニングデータには含まれていませんが、テストセットには含まれているため、推論時に新しいデータを検討できます。
トリックは、この値を「その他」に変換し、これをlabelEncoderオブジェクトに含めることです。その後、本番環境で再利用できます。
c = 'city'
le = preprocessing.LabelEncoder()
train[c] = le.fit_transform(train[c])
test[c] = test[c].map(lambda s: 'other' if s not in le.classes_ else s)
le_classes = le.classes_.tolist()
bisect.insort_left(le_classes, 'other')
le.classes_ = le_classes
test[c] = le.transform(test[c])
test
city letters
0 1 a
1 3 b
2 2 c
3 1 a
4 4 b
5 0 b
これを新しいデータに適用するには、Pickleで簡単に実行できる各列のle
オブジェクトを保存するだけです。
この回答はこれに基づいています 質問 完全に明確ではないので、この例を追加しました。