Czy możemy ulepszyć model ML (plik marynowany), akceptując (lub ignorując) nowe funkcje?

Nov 19 2020
  • Wytrenowałem model ML i zapisałem go w pliku Pickle.
  • W moim nowym skrypcie czytam nowe „dane ze świata rzeczywistego”, na podstawie których chcę przeprowadzić prognozę.

Jednak walczę. Mam kolumnę (zawierającą wartości ciągów), na przykład:

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

Teraz problem. Otrzymałem nową (unikalną) wartość i teraz nie mogę już przewidywać (np. 'Neutral'Został dodany).

Ponieważ przekształcam 'Sex'kolumnę w manekiny, mam problem z tym, że mój model nie akceptuje już danych wejściowych,

Liczba cech modelu musi pasować do danych wejściowych. Model n_features to 2, a wejściowe n_features to 3

Dlatego moje pytanie: czy istnieje sposób, w jaki mogę uczynić mój model solidnym i po prostu zignorować tę klasę? Ale czy przewidzieć bez konkretnych informacji?

Co próbowałem:

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

Uwaga, szukałem, ale nie znalazłem żadnego pomocnego rozwiązania (nie tutaj , tutaj ani tutaj

AKTUALIZACJA

Znalazłem również ten artykuł. Ale ta sama kwestia tutaj… możemy zrobić zestaw testowy z tymi samymi kolumnami co zbiór uczący… ale co z nowymi danymi ze świata rzeczywistego (np. Nowa wartość „Neutralny”)?

Odpowiedzi

7 Venkatachalam Nov 23 2020 at 07:56

Tak, nie możesz dołączyć (zaktualizować modelu) nowej kategorii lub funkcji do zestawu danych po zakończeniu części szkoleniowej. OneHotEncodermoże poradzić sobie z problemem posiadania nowych kategorii wewnątrz jakiejś funkcji w danych testowych. Zadba o zachowanie spójności kolumn w danych treningowych i testowych w odniesieniu do zmiennych kategorialnych.

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)