管道预测X具有与拟合期间不同的形状

时间:2018-05-07 16:11:33

标签: python machine-learning scikit-learn pipeline grid-search

我遇到了这个错误,我理解其含义,但我不知道如何处理它。

以下是我的工作:

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的形状与拟合时不同。

据我所知,并非所有模态都出现在我的&#34;真实文件&#34;上,因为想象一下,在我的火车文件中,我有一列&#34;情侣&#34;有价值观&#34;是的,不,我不知道&#34;那么ce.BinaryEncoder将创建将所有模态存储为二进制所需的列数。 但是在我的真实生活文件中,我必须做出预测,我只有这些专栏#34; couple&#34;价值观&#34;是,否&#34;所以最后,X没有与合身期间相同的形状...... 所以我唯一要做的就是在PreProcessing中创建cols值为0的所有缺失模态......

我想我错过了一些东西。

注意:训练和测试文件来自某个数据源。我需要预测的数据来自其他来源,所以我首先&#34;转换&#34;将实际数据转换为相同的X_train / Test格式,然后我执行model.predit(df)。所以我确定之前在BinaryEncoder上我在Preprocessing.transform()上有相同数量的cols(17)但后执行BinaryEncoder如果我在运行时记录df的形状model.predict(X_test)它显示df是41个cols,而在model.predict(realData)上只有31个cols。

1 个答案:

答案 0 :(得分:0)

这似乎是您的&#34;功能选择/创建问题&#34;处理。每次将新的输入集传递给管道时,您都会重新拟合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())