Pouvons-nous rendre le modèle ML (fichier pickle) plus robuste, en acceptant (ou en ignorant) les nouvelles fonctionnalités?

Nov 19 2020
  • J'ai formé un modèle ML et l'ai stocké dans un fichier Pickle.
  • Dans mon nouveau script, je lis de nouvelles «données du monde réel», sur lesquelles je veux faire une prédiction.

Cependant, je me bats. J'ai une colonne (contenant des valeurs de chaîne), comme:

Sex       
Male       
Female
# This is just as example, in real it is having much more unique values

Maintenant vient le problème. J'ai reçu une nouvelle valeur (unique), et maintenant je ne peux plus faire de prédictions (par exemple a 'Neutral'été ajoutée).

Depuis que je transforme la 'Sex'colonne en mannequins, j'ai le problème que mon modèle n'accepte plus l'entrée,

Le nombre de caractéristiques du modèle doit correspondre à l'entrée. Le modèle n_features est 2 et l'entrée n_features est 3

Par conséquent, ma question: y a-t-il un moyen de rendre mon modèle robuste et d'ignorer simplement cette classe? Mais faire une prédiction, sans les informations spécifiques?

Ce que j'ai essayé:

df = pd.read_csv('dataset_that_i_want_to_predict.csv')
model = pickle.load(open("model_trained.sav", 'rb'))

# I have an 'example_df' containing just 1 row of training data (this is exactly what the model needs)
example_df = pd.read_csv('reading_one_row_of_trainings_data.csv')

# Checking for missing columns, and adding that to the new dataset 
missing_cols = set(example_df.columns) - set(df.columns)
for column in missing_cols:
    df[column] = 0 #adding the missing columns, with 0 values (Which is ok. since everything is dummy)

# make sure that we have the same order 
df = df[example_df.columns] 

# The prediction will lead to an error!
results = model.predict(df)

# ValueError: Number of features of the model must match the input. Model n_features is X and n_features is Y

Remarque, j'ai cherché, mais je n'ai trouvé aucune solution utile (pas ici , ici ou ici

METTRE À JOUR

J'ai également trouvé cet article. Mais même problème ici ... nous pouvons créer le jeu de test avec les mêmes colonnes que le jeu de formation ... mais qu'en est-il des nouvelles données du monde réel (par exemple, la nouvelle valeur «Neutre»)?

Réponses

7 Venkatachalam Nov 23 2020 at 07:56

Oui, vous ne pouvez pas inclure (mettre à jour le modèle) une nouvelle catégorie ou entité dans un jeu de données une fois la partie d'apprentissage terminée. OneHotEncoderpourrait gérer le problème d'avoir de nouvelles catégories dans certaines fonctionnalités des données de test. Il veillera à garder les colonnes cohérentes dans vos données d'entraînement et de test par rapport aux variables catégorielles.

from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import OneHotEncoder
import numpy as np
import pandas as pd
from sklearn import set_config
set_config(print_changed_only=True)
df = pd.DataFrame({'feature_1': np.random.rand(20),
                   'feature_2': np.random.choice(['male', 'female'], (20,))})
target = pd.Series(np.random.choice(['yes', 'no'], (20,)))

model = Pipeline([('preprocess',
                   ColumnTransformer([('ohe',
                                       OneHotEncoder(handle_unknown='ignore'), [1])],
                                       remainder='passthrough')),
                  ('lr', LogisticRegression())])

model.fit(df, target)

# let us introduce new categories in feature_2 in test data
test_df = pd.DataFrame({'feature_1': np.random.rand(20),
                        'feature_2': np.random.choice(['male', 'female', 'neutral', 'unknown'], (20,))})
model.predict(test_df)
# array(['yes', 'yes', 'yes', 'yes', 'yes', 'yes', 'yes', 'yes', 'yes',
#       'yes', 'yes', 'yes', 'yes', 'yes', 'yes', 'yes', 'yes', 'yes',
#       'yes', 'yes'], dtype=object)