管道预测 X 的形状与拟合期间的形状不同
Pipeline predict X has a different shape than during fitting
我遇到了这个我明白意思但不知道如何处理的错误。
我是这样做的:
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 的形状与拟合期间的形状不同。
我的理解是,并非所有模态都在我的 "real file" 上表示,因为想象一下在我的火车文件中,我有 "couple" 列,其值 "yes, no, I don't know" 然后是 ce.BinaryEncoder 将创建将所有模态存储为二进制所需的尽可能多的列。
但是在我必须做出预测的现实生活文件中,我只有这些列 "couple" 值 "yes, no" 所以最后,X 的形状与拟合期间的形状不同......
所以我唯一要做的就是在 PreProcessing 中创建所有缺失的模态,cols 值为 0...
我想我错过了什么。
注:训练和测试文件来自某个数据源。我需要预测的数据来自其他来源,所以我首先 "transform" 将那些真实数据转换为相同的 X_train/Test 格式,然后我执行 model.predit(df)。所以我确定 before BinaryEncoder 我在 Preprocessing.transform() 上有相同数量的 cols (17) 但是 after BinaryEncoder 执行如果我记录 df 的形状,而 运行 model.predict(X_test) 它显示 df 是 41 列,而在 model.predict(realData) 上只有 31 列。
这似乎是您的 "feature selection/creation" 流程的问题。每次将一组新的输入传递到您的管道时,您都会重新安装 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())
我遇到了这个我明白意思但不知道如何处理的错误。
我是这样做的:
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 的形状与拟合期间的形状不同。
我的理解是,并非所有模态都在我的 "real file" 上表示,因为想象一下在我的火车文件中,我有 "couple" 列,其值 "yes, no, I don't know" 然后是 ce.BinaryEncoder 将创建将所有模态存储为二进制所需的尽可能多的列。 但是在我必须做出预测的现实生活文件中,我只有这些列 "couple" 值 "yes, no" 所以最后,X 的形状与拟合期间的形状不同...... 所以我唯一要做的就是在 PreProcessing 中创建所有缺失的模态,cols 值为 0...
我想我错过了什么。
注:训练和测试文件来自某个数据源。我需要预测的数据来自其他来源,所以我首先 "transform" 将那些真实数据转换为相同的 X_train/Test 格式,然后我执行 model.predit(df)。所以我确定 before BinaryEncoder 我在 Preprocessing.transform() 上有相同数量的 cols (17) 但是 after BinaryEncoder 执行如果我记录 df 的形状,而 运行 model.predict(X_test) 它显示 df 是 41 列,而在 model.predict(realData) 上只有 31 列。
这似乎是您的 "feature selection/creation" 流程的问题。每次将一组新的输入传递到您的管道时,您都会重新安装 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())