在Scikit Learn中为预测进行特征缩放

3
我一直在开发一个机器学习模型,目前正在使用带有GridSearchCV的Pipeline。我的数据使用MinMaxScaler进行缩放,并且我正在使用具有RBR内核的SVR。我的问题是,现在我的模型已经完成、拟合并获得了不错的评估分数,我是否还需要使用MinMaxScaler来缩放新数据以进行预测,或者我可以使用原始数据进行预测?我已经读了三本关于scikit learn的书,但它们都着重于特征工程和拟合,没有涵盖任何关于预测步骤的额外说明,除了使用predict方法。
这是代码:
pipe = Pipeline([('scaler', MinMaxScaler()), ('clf', SVR())]) 
time_split = TimeSeriesSplit(n_splits=5) 

param_grid = {'clf__kernel': ['rbf'], 
              'clf__C':[0.0001, 0.001], 
              'clf__gamma': [0.0001, 0.001]} 

grid = GridSearchCV(pipe, param_grid, cv= time_split, 
                    scoring='neg_mean_squared_error', n_jobs = -1) 
grid.fit(X_train, y_train) 

您可以使用pickle或joblib将完整的GridSearchCV或其中找到的最佳估计器保存到文件中,然后在预测时加载该文件。 - Vivek Kumar
2个回答

3
当你获取到新的(未经处理的)数据时,你需要执行与训练模型时相同的准备步骤。例如,如果你使用默认属性的MinMaxScaler,则模型用于具有每个特征零均值和标准方差的数据,如果你不对数据进行预处理,则模型无法产生准确的结果。
请记住,要使用与训练数据相同的MinMaxScaler对象。因此,如果你将模型保存到文件中,请同时保存你的预处理对象。

谢谢!那么,为了澄清一下,如果我使用Pipeline,如何使用相同的MinMaxScaler对象呢?它似乎会在每个交叉折叠上自行处理所有预处理。如果我像这样自己应用转换:scaler.fit(X_train) X_train_scaled = scaler.transform(X_train) prediction_scaled = scaler.transform(predictions)这完美地回答了我的问题。我很惊讶没有任何一本书提到这一点。 - BeaverMonkey
我没有使用管道的经验。你能提供一些代码吗? - pythonic833
pipe = Pipeline([('scaler', MinMaxScaler()), ('clf', SVR())]) time_split = TimeSeriesSplit(n_splits=5) param_grid = {'clf__kernel': ['rbf'], 'clf__C':[0.0001, 0.001], 'clf__gamma': [0.0001, 0.001]} grid = GridSearchCV(pipe, param_grid, cv= time_split, scoring='neg_mean_squared_error', n_jobs = -1) grid.fit(X_train, y_train) - BeaverMonkey
抱歉,这是我的第一篇帖子,我无法让标记工作。 - BeaverMonkey
抱歉,我无法在这方面为您提供帮助。我猜测可能有一种方法可以保存整个流程,或者至少保存应用模型于测试数据的重要步骤(并省略交叉验证部分),但我不确定。 - pythonic833

0

我想跟进我的问题,并感谢pythonic833的答案提供了解决方案。如果您使用管道对新数据进行预测,我认为正确的缩放过程是使用在管道上使用过的原始训练数据从头到尾完成整个缩放过程。即使管道在训练过程中为您执行了缩放,也需要手动缩放训练数据,以便能够通过具有MinMaxScaler对象的准确预测和正确缩放的新数据。以下是基于pythonic833答案和其他评论(例如使用Pickle保存模型)的代码。

from sklearn.preprocessing import MinMaxScaler

pipe = Pipeline([('scaler', MinMaxScaler()), ('clf', SVR())]) 
time_split = TimeSeriesSplit(n_splits=5) 
param_grid = {'clf__kernel': ['rbf'], 
          'clf__C':[0.0001, 0.001], 
          'clf__gamma': [0.0001, 0.001]} 

grid = GridSearchCV(pipe, param_grid, cv= time_split, 
       scoring='neg_mean_squared_error', n_jobs = -1) 
grid.fit(X_train, y_train)

# Pickle the data with a content manager
with open('Pickles/{}.pkl'.format(file_name), 'wb') as file:
    pickle.dump(grid, file)

# Load Pickle with a content manager
with open('Pickles/{}.pkl'.format(file_name), 'rb') as file:
    model = pickle.load(file)

scaler = MinMaxScaler()
scaler.fit(X_train)  # Original training data for Pipeline
X_train_scaled = scaler.transform(X_train)
new_data_scaled = scaler.transform(new_data)
model.predict(new_data_scaled)

在更深入地了解管道和缩放之后,我需要重新审视我之前发布的内容。当使用Pipeline进行预测时,使用GridSearchCV时,不需要使用训练数据重新缩放。只需调用grid.predict(new_data)即可运行管道并缩放数据。当它到达最后一步时,它只是运行predict而不是最后一步中的分类器。因此,在上面的示例中,打开Pickle后的所有内容都是不必要的。只需对新数据调用predict即可。 - BeaverMonkey

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接