2
votes

Comment enregistrer un modèle encodé à chaud et prédire de nouvelles données non encodées à l'aide de scikitlearn?

Mon ensemble de données contient 3 fonctionnalités catégoriques et j'ai utilisé un encodage à chaud pour le changer au format binaire et tout s'est bien passé. Mais lorsque je veux enregistrer ce modèle entraîné et prédire de nouvelles données brutes, l'entrée n'est pas codée comme je m'y attendais et entraîne une erreur.

combined_df_raw2= pd.concat([train_x_raw,unknown_test_df])
combined_df2 = pd.get_dummies(combined_df_raw2, columns=nominal_cols, 
drop_first=True)

encoded_unknown_df = combined_df2[len(train_x_raw):]

classifier = DecisionTreeClassifier(random_state=17)
classifier.fit(train_x_raw, train_Y)

pred_y = classifier.predict(encoded_unknown_df)

#here I use joblib to save my model and load it again
joblib.dump(classifier, 'savedmodel')
imported_model = joblib.load('savedmodel')

#here I input unencoded raw data for predict and got error that cannot             
convert 'tcp' to float, means that it is not encoded 

imported_model.predict([0,'tcp','vmnet','REJ',0,0,0,23])   

ValueError: impossible de convertir la chaîne en float: 'tcp '


5 commentaires

sklearn OHE effectue l'encodage pour vous .. En Dans le cas des mannequins , vous devez maintenir une carte pour les données de test.


@ rock321987 c'est exactement ce que je cherchais. Il y a certaines complexités où je ne pourrais pas utiliser OHE pour l'encodage. Pouvez-vous s'il vous plaît me dire comment maintenir une carte pour les données de test. Merci beaucoup!


Je vais pointer vers un lien


Ce lien utilise OHE Je veux maintenir une carte en utilisant get.dummies pour un futur encodage!


Utilisez ceci


3 Réponses :


3
votes

Le modèle est entraîné après l'encodage de la variable catégorielle, par conséquent, l'entrée doit être donnée après l'application du «codage en un instant» aux variables respectives. Exemple: l'une des colonnes est intitulée "Pays" et vous avez trois valeurs différentes dans l'ensemble de données, à savoir. ['India', Israel ',' France '], maintenant vous avez appliqué OneHotEncoding (probablement après LabelEncoder) sur la colonne country, puis vous entraînez votre modèle, enregistrez-le, faites ce que vous voulez!

La question est maintenant , vous obtenez une erreur d'entrée lorsque vous donnez directement une entrée sans la changer au format sur lequel le modèle a été formé. Par conséquent, nous voudrons toujours prétraiter l'entrée avant de la donner au modèle. Le moyen le plus courant à ma connaissance est d'utiliser Pipeline.

steps = [('scaler', StandardScaler()), ('ohe', OneHotEncoder()),('SVM', 
        DecisionTreeClassifier())]
from sklearn.pipeline import Pipeline
pipeline = Pipeline(steps) # You need to save this pipeline via joblib
pipe.fit(X_train, y_train)

Dans le cas contraire, vous ne voulez pas utiliser Pipeline, vous pouvez de toute façon utiliser OneHotEncode sur des colonnes spécifiques, puis utilisez prédire!


1 commentaires

Pouvez-vous élaborer un peu plus.



0
votes

@chintan alors par exemple pour les données brutes à venir, si vous convertissez la variable catégorielle n'ayant qu'une seule instance, alors elle ne fera qu'une colonne supplémentaire, alors qu'avant pour la colonne catégorielle que vous aviez, vod avait comme 500 colonnes. donc il ne correspondra plus. prenons un exemple de devises, une instance arrive avec INR seulement, même si vous faites l'encodage, elle la convertira en colonne, mais avant d'avoir des colonnes pour toutes les devises du monde


1 commentaires

C'est un commentaire, pas la réponse



2
votes

Utilisez fit () suivi de transform () , de cette façon vous pouvez décaper votre unique encodeur après l'avoir ajusté.

enc.transform(new_data)

Ensuite, décrochons votre encodeur, vous pouvez utiliser d'autres moyens de conserver l'encodeur. Consultez, https://scikit-learn.org/stable/modules/model_persistence.html

with open('encoder.pickle', 'rb') as f:
    enc = pickle.loads(f)

Désormais, lorsque vous avez de nouvelles données à prédire, vous devez d'abord parcourir l'ensemble du pipeline de prétraitement que vous avez effectué pour vos données d'entraînement. Dans ce cas, l'encodeur. Rechargeons-le,

import pickle
with open('encoder.pickle', 'wb') as f:
    pickle.dump(enc, f)

Une fois que vous l'avez chargé, il vous suffit de transformer les nouvelles données.

from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder(handle_unknown='ignore')
X = [['Male', 1], ['Female', 3], ['Female', 2]]
enc.fit(X)

Pour en savoir plus sur pickle, https://docs.python.org/3/library/ pickle.html


3 commentaires

Bien que cela fasse l'affaire, joblib est également une bonne façon de procéder. scikit-learn.org/stable/modules/model_persistence.html


Supposons que le niveau ne soit pas présent dans les nouvelles données entrantes. La méthode fonctionnera-t-elle toujours?


Non, seuls les mots donnés pour fit sont encodés lors d'une transformation. Notez s'il y a d'autres mots dans votre jeu de données de test qui seraient un plus gros problème. Par exemple, disons que l'ensemble de données d'entraînement contient uniquement «homme» et «femme», mais l'ensemble de données de test contient également «autre». Ce sont des données invisibles pour votre modèle. Et le modèle fonctionnera mal. De plus, OHE ne fonctionnera pas, car le nombre d'entités entre le train et le jeu de données de test varierait.