새로운 기능을 수용 (또는 무시)하여 ML 모델 (피클 파일)을 더 강력하게 만들 수 있습니까?
Nov 19 2020
- ML 모델을 훈련하고 Pickle 파일에 저장했습니다.
- 새 대본에서 나는 예측을하고 싶은 새로운 '실제 데이터'를 읽고 있습니다.
그러나 나는 고군분투하고있다. 다음과 같은 열 (문자열 값 포함)이 있습니다.
Sex
Male
Female
# This is just as example, in real it is having much more unique values
이제 문제가 발생합니다. 새로운 (고유) 값을 받았는데 이제 더 이상 예측을 할 수 없습니다 (예 : 'Neutral'
추가됨).
'Sex'
컬럼을 Dummies로 변환하기 때문에 모델이 더 이상 입력을 받아들이지 않는다는 문제가 있습니다.
모델의 기능 수가 입력과 일치해야합니다. 모델 n_features는 2이고 입력 n_features는 3입니다.
따라서 내 질문 : 내 모델을 견고하게 만들고이 클래스를 무시할 수있는 방법이 있습니까? 그러나 특정 정보없이 예측을합니까?
내가 시도한 것 :
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
참고로 검색했지만 유용한 솔루션을 찾을 수 없습니다 ( 여기 , 여기 또는 여기가 아님).
최신 정보
이 기사 도 찾았습니다 . 하지만 여기서도 같은 문제입니다. 학습 세트와 동일한 열로 테스트 세트를 만들 수 있습니다.하지만 새로운 실제 데이터 (예 : 새로운 값 'Neutral')는 어떻습니까?
답변
7 Venkatachalam Nov 23 2020 at 07:56
예, 학습 부분이 완료된 후에는 새 카테고리 또는 기능을 데이터 세트에 포함 (모델 업데이트) 할 수 없습니다. OneHotEncoder
테스트 데이터의 일부 기능 내에 새 카테고리가있는 문제를 처리 할 수 있습니다. 범주 형 변수와 관련하여 학습 및 테스트 데이터에서 열을 일관되게 유지합니다.
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)