我被这个错误所困扰,我理解其含义,但是我不知道如何处理。
这是我的工作:
class PreProcessing(BaseEstimator, TransformerMixin):
def __init__(self):
pass
def transform(self, df):
#Here i select the features and transform them for exemple:
age_band=0
if age<=10
age_band=1
else #... etc to 90
age_band=9
....
other feature engineering
....
encoder = ce.BinaryEncoder(cols=selectedCols)
encoder.fit(df)
df = encoder.transform(df)
return df.as_matrix()
def fit(self, df, y=None, **fit_params):
return self
pipe = make_pipeline(PreProcessing(),
SelectKBest(f_classif,k=23),
RandomForestClassifier())
param_grid = {"randomforestclassifier__n_estimators" : [100,400],
"randomforestclassifier__max_depth" : [None],
"randomforestclassifier__max_leaf_nodes": [2,3,5],
"randomforestclassifier__min_samples_leaf":[3,5,8],
"randomforestclassifier__class_weight":['balanced'],
"randomforestclassifier__n_jobs":[-1]
}
grid_search = GridSearchCV(pipe,param_grid,cv=5,scoring='recall',verbose=1,n_jobs=15)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
grid_search.fit(X_train,y_train)
grid_search.predict(X_test)
filename = 'myModel.pk'
with open(filename, 'wb') as file:
pickle.dump(grid_search, file)
因此,这里的一切都像魅力一样。
但是使用现实世界的数据:(不是火车测试文件)
modelfile = 'MyModel.pk'
with open(modelfile,'rb') as f:
loaded_model = pickle.load(f)
print("The model has been loaded...doing predictions now...")
predictions = loaded_model.predict(df)
我收到错误:ValueError:X的形状与拟合期间的形状不同。
我了解的是,并非所有模态都在我的“真实文件”中表示,因为想象在我的火车文件中,我的列“夫妇”的值是“是,否,我不知道”,那么ce.BinaryEncoder将创建将所有模态存储为二进制所需的列数。
但是在我的现实生活文件中,我只需要对这些列“ couple”值“ yes,no”进行预测,因此最后,X的形状与拟合过程中的形状不同...
所以我唯一要做的就是在预处理中创建所有cols值为0的缺失模态...
我想我缺少了一些东西。
注意:训练和测试文件来自某些数据源。我需要预测的数据来自其他来源,因此我首先将那些真实数据“转换”为相同的X_train / Test格式,然后执行model.predit(df)。所以我确定在BinaryEncoder之前我在Preprocessing.transform()上具有相同的cols(17)数,但是在BinaryEncoder执行后,如果我在运行model.predict(X_test)时记录df的形状,则显示df为41 cols,并且在model.predict(realData)上只有31个列。
最佳答案
这似乎与您的“功能选择/创建”过程有关。每次将新的一组输入传递到管道时,您都要重新拟合BinaryEncoder
。这意味着,只要指定列中的唯一值数量不同,代码就会因该错误而中断。
我的猜测是,如果将BinaryEncoder
保存为PreProcessing
实例的一部分,那么假设您的训练数据具有该列可以承担的所有可能的值,这将不是问题。
class PreProcessing(BaseEstimator, TransformerMixin):
def __init__(self):
self.encoder = ce.BinaryEncoder(cols=selectedCols)
def fit(self, df, **kwargs):
self.encoder.fit(df)
def transform(self, df):
# ...
# No fitting, just transform
df = self.encoder.transform(df)
return df
更好的是,您可以仅将BinaryEncoder插入管道中,然后完全将其保留在
PreProcessing
之外吗?pipe = make_pipeline(PreProcessing(),
BinaryEncoder(cols=selectedCols),
SelectKBest(f_classif,k=23),
RandomForestClassifier())
关于python - 管道预测X与拟合期间的形状不同,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50218408/