web-dev-qa-db-fra.com

Obtention de ValueError: y contient de nouvelles étiquettes lors de l'utilisation de LabelEncoder de scikit learn

J'ai une série comme:

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

J'utilise LabelEncoder de scikit pour le convertir en valeurs numériques à introduire dans le RandomForestClassifier.

Pendant la formation, je fais comme suit:

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

Mais maintenant, pour les tests/prévisions, lorsque je transmets de nouvelles données, je veux transformer l'ID de ces données en fonction de le_id c'est-à-dire que si les mêmes valeurs sont présentes, transformez-les conformément au codeur d'étiquette ci-dessus, sinon affectez une nouvelle valeur numérique.

Dans le fichier de test, je faisais ce qui suit:

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

Mais, j'obtiens l'erreur suivante: ValueError: y contains new labels

Comment puis-je réparer ça?? Merci!

METTRE À JOUR:

Donc, la tâche que j'ai est d'utiliser les données ci-dessous (par exemple) comme données d'entraînement et de prédire le 'High', 'Mod', 'Low' valeurs pour les nouvelles combinaisons BankNum, ID. Le modèle devrait apprendre les caractéristiques où un "haut" est donné, où un "bas" est donné à partir de l'ensemble de données d'apprentissage. Par exemple, ci-dessous un "High" est donné lorsqu'il y a plusieurs entrées avec le même BankNum et différents 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

Et puis prédisez-le sur quelque chose comme:

BankNum   |  ID | 

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

Je fais quelque chose comme ça:

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

Je pense que le message d'erreur est très clair: votre jeu de données de test contient ID étiquettes qui n'ont pas été incluses dans votre jeu de données d'entraînement. Pour ces éléments, LabelEncoder ne peut pas trouver une valeur numérique appropriée à représenter. Il existe plusieurs façons de résoudre ce problème. Vous pouvez soit essayer d'équilibrer votre ensemble de données, de sorte que vous êtes sûr que chaque étiquette est non seulement présente dans votre test mais également dans vos données d'entraînement. Sinon, vous pouvez essayer de suivre l'une des idées présentées ici .

L'une des solutions possibles consiste à rechercher dans votre ensemble de données au début, à obtenir une liste de toutes les valeurs uniques de ID, à former les LabelEncoder sur cette liste et à conserver le reste de votre code tel qu'il est en ce moment.

Une autre solution possible consiste à vérifier que les données de test n'ont que des étiquettes qui ont été vues dans le processus de formation. S'il existe une nouvelle étiquette, vous devez la définir sur une valeur de secours comme unknown_id (ou quelque chose comme ça). Doin ceci, vous mettez tous les nouveaux IDs inconnus dans une classe; pour ces éléments, la prédiction échouera alors, mais vous pouvez utiliser le reste de votre code tel qu'il est maintenant.

3
zimmerrol

vous pouvez essayer la solution de "sklearn.LabelEncoder avec des valeurs jamais vues auparavant" https://stackoverflow.com/a/48169252/9043549 La chose est de créer un dictionnaire avec des classes, de mapper la colonne et de remplir de nouvelles classes avec une "valeur connue"

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

De cette façon, vous pouvez mapper avec 0 toutes les étiquettes invisibles dans vos données de test/invisibles

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