Czy możemy ulepszyć model ML (plik marynowany), akceptując (lub ignorując) nowe funkcje?
- 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
Tak, nie możesz dołączyć (zaktualizować modelu) nowej kategorii lub funkcji do zestawu danych po zakończeniu części szkoleniowej. OneHotEncoder
moż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)