web-dev-qa-db-ja.com

ValueErrorの取得:scikit learnのLabelEncoderを使用すると、yに新しいラベルが含まれます

私のようなシリーズがあります:

df['ID'] = ['ABC123', 'IDF345', ...]

私はscikitのLabelEncoderを使用して、RandomForestClassifierに入力する数値に変換しています。

トレーニング中、私は次のようにしています。

le_id = LabelEncoder()
df['ID'] = le_id.fit_transform(df.ID) 

しかし、ここでテスト/予測のために、新しいデータを渡すときに、le_idに基づいてこのデータから「ID」を変換します。つまり、同じ値が存在する場合は、上記のラベルエンコーダーに従って変換します。それ以外の場合は、新しい数値を割り当てます。

テストファイルでは、次のようにしました。

new_df['ID'] = le_dpid.transform(new_df.ID)

しかし、次のエラーが発生します:ValueError: y contains new labels

どうすれば修正できますか?ありがとう!

更新:

したがって、私が持っているタスクは、以下を(たとえば)トレーニングデータとして使用し、新しいBankNumとIDの組み合わせの'High', 'Mod', 'Low'値を予測することです。モデルは、トレーニングデータセットから「低」が与えられる「高」が与えられる場合の特性を学習する必要があります。たとえば、BankNumが同じでIDが異なるエントリが複数ある場合、以下の「高」が表示されます。

df = 

BankNum   | ID    | Labels

0098-7772 | AB123 | High
0098-7772 | ED245 | High
0098-7772 | ED343 | High
0870-7771 | ED200 | Mod
0870-7771 | ED100 | Mod
0098-2123 | GH564 | Low

そして、それを次のように予測します。

BankNum   |  ID | 

00982222  | AB999 | 
00982222  | AB999 |
00981111  | AB890 |

私はこのようなことをしています:

df['BankNum'] = df.BankNum.astype(np.float128)

    le_id = LabelEncoder()
    df['ID'] = le_id.fit_transform(df.ID)

X_train, X_test, y_train, y_test = train_test_split(df[['BankNum', 'ID'], df.Labels, test_size=0.25, random_state=42)
    clf = RandomForestClassifier(random_state=42, n_estimators=140)
    clf.fit(X_train, y_train)
5
Xavier

エラーメッセージは非常に明確だと思います。テストデータセットには、トレーニングデータセットに含まれていないIDラベルが含まれています。このアイテムの場合、LabelEncoderは適切な数値を見つけられません。この問題を解決するにはいくつかの方法があります。データセットのバランスをとって、各ラベルがテストだけでなくトレーニングデータにも存在するようにすることもできます。それ以外の場合は、提示されたアイデアの1つに従うことを試みることができます ここ

可能な解決策の1つは、最初にデータセットを検索し、すべての一意のID値のリストを取得し、このリストでLabelEncoderをトレーニングし、残りの現時点でのコードと同じです。

他の可能な解決策は、テストデータにトレーニングプロセスで確認されたラベルのみがあることを確認することです。新しいラベルがある場合は、unknown_id(またはこのようなもの)などのフォールバック値に設定する必要があります。これを行うには、すべての新しい未知のIDsを1つのクラスに入れます。このアイテムの場合、予測は失敗しますが、コードの残りの部分をそのまま使用できます。

3
zimmerrol

あなたは「以前に見たことのない値を持つsklearn.LabelEncoder」から解決策を試すことができます https://stackoverflow.com/a/48169252/9043549 クラスで辞書を作成し、列をマップして新しいものを埋めることです「既知の値」を持つクラス

from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
suf="_le"
col="a"
df[col+suf] = le.fit_transform(df[col])
dic = dict(Zip(le.classes_, le.transform(le.classes_)))
col='b'
df[col+suf]=df[col].map(dic).fillna(dic["c"]).astype(int) 
2
Yury Wallet

このようにして、テスト/目に見えないデータのすべての目に見えないラベルを0でマッピングできます。

for feat in ['BankNum', 'ID']:

    lbe = LabelEncoder()
    lbe.fit(X_train[feat].values)
    diz_map_train = dict(Zip(lbe.classes_, lbe.transform(lbe.classes_)+1))

    for i in set(X_test[feat]).difference(X_train[feat]):
        diz_map_train[i] = 0

    X_train[feat] = [diz_map_train[i] for i in X_train[feat].values]
    X_test[feat] = [diz_map_train[i] for i in X_test[feat].values]
0
Marco Cerliani