Python 使用Scikit Learn StandardScaler(带管道和不带管道)进行Keras回归

Python 使用Scikit Learn StandardScaler(带管道和不带管道)进行Keras回归,python,scikit-learn,keras,pipeline,Python,Scikit Learn,Keras,Pipeline,我正在使用Scikit LearnStandardScaler比较两个有关KerasRegressionr的程序的性能:一个程序使用Scikit Learn管道,另一个程序不使用管道 方案1: estimators = [] estimators.append(('standardise', StandardScaler())) estimators.append(('multiLayerPerceptron', KerasRegressor(build_fn=build_nn, nb_epoc

我正在使用Scikit Learn
StandardScaler
比较两个有关
KerasRegressionr
的程序的性能:一个程序使用Scikit Learn
管道
,另一个程序不使用
管道

方案1:

estimators = []
estimators.append(('standardise', StandardScaler()))
estimators.append(('multiLayerPerceptron', KerasRegressor(build_fn=build_nn, nb_epoch=num_epochs, batch_size=10, verbose=0)))
pipeline = Pipeline(estimators)
log = pipeline.fit(X_train, Y_train)
Y_deep = pipeline.predict(X_test)
方案2:

scale = StandardScaler()
X_train = scale.fit_transform(X_train)
X_test = scale.fit_transform(X_test)
model_np = KerasRegressor(build_fn=build_nn, nb_epoch=num_epochs, batch_size=10, verbose=0)
log = model_np.fit(X_train, Y_train)
Y_deep = model_np.predict(X_test)

我的问题是,程序1的R2得分为0.98(平均3次试验),而程序2的R2得分仅为0.84(平均3次试验)。有人能解释这两个程序之间的区别吗?

在第二种情况下,您调用的是
StandardScaler.fit_transform()
X\U列车上
X\U测试上
。这是错误的用法

您应该在
X\u-train
上调用
fit\u transform()
,然后在
X\u测试上只调用
transform()
。因为这就是
管道所做的。
如文件所述,将:

fit()

逐个拟合所有变换并变换数据, 然后使用最终估计器拟合转换后的数据

预测()

将变换应用于数据,并使用最终估计器进行预测

因此,它将只对测试数据应用
transform()
,而不是
fit\u transform()

请详细说明我的观点,您的代码应该是:

scale = StandardScaler()
X_train = scale.fit_transform(X_train)

#This is the change
X_test = scale.transform(X_test)

model_np = KerasRegressor(build_fn=build_nn, nb_epoch=num_epochs, batch_size=10, verbose=0)
log = model_np.fit(X_train, Y_train)
Y_deep = model_np.predict(X_test)
对测试数据调用
fit()
fit\u transform()
会错误地将其缩放到与对列车数据使用的缩放不同的缩放比例。并且是预测变化的来源

编辑:回答评论中的问题:

请参阅,
fit\u transform()
只是执行
fit()
然后执行
transform()
的快捷功能。对于
StandardScaler
fit()
不返回任何内容,只学习数据的平均值和标准偏差。然后
transform()
对数据应用学习以返回新的缩放数据

因此,您所说的将导致以下两种情况:

情景1:错误

1) X_scaled = scaler.fit_transform(X)
2) Divide the X_scaled into X_scaled_train, X_scaled_test and run your model. 
   No need to scale again.
场景2:错误(基本上与场景1相同,反向缩放和吐出操作)

您可以尝试任何一种场景,也许这会提高模型的性能

但是有一个非常重要的东西在他们身上缺失了。当您对整个数据进行缩放,然后将其划分为训练和测试时,假定您知道测试(未看到)数据,而这在实际情况中是不正确的。并将给你的结果,将不会根据现实世界的结果。因为在现实世界中,所有的数据都是我们的训练数据。这也可能导致过度拟合,因为模型已经有一些关于测试数据的信息

因此,在评估机器学习模型的性能时,建议在对其执行任何操作之前将测试数据放在一边。因为这是我们看不见的数据,我们对此一无所知。所以理想的操作路径应该是我回答的,即:

1) Divide X into X_train and X_test (same for y)
2) X_train_scaled = scale.fit_transform(X_train) [#Learn the mean and SD of train data]
3) X_test_scaled = scale.transform(X_test) [#Use the mean and SD learned in step2 to convert test data]
4) Use the X_train_scaled for training the model and X_test_scaled in evaluation.

希望这对你有意义。

亲爱的维韦克:我遵循你关于拟合变换(X_训练)和变换(X_测试)的建议,分数确实会上升。谢谢但是,我这里有两个问题。(1) 我在X_列和X_测试中都使用了fit_transform(),方法如下所示。看起来那个程序也会有类似的问题,对吧?(2) “拟合变换(X),然后变换(X_列)和变换(X_测试),其中X等于X_列加上X_测试”效果更好吗?维韦克:谢谢你的评论。我现在对这些函数有了更好的了解。如果我的答案帮助了你,你的问题得到了解决,那么请考虑把它标记为接受。你似乎在独立地对每个数据集进行重新缩放,你应该使用<代码> xyStudio=Simult.FiTyTror(XyStand)和<代码> XyTest=缩放。变换(XyTest)
1) Divide X into X_train and X_test (same for y)
2) X_train_scaled = scale.fit_transform(X_train) [#Learn the mean and SD of train data]
3) X_test_scaled = scale.transform(X_test) [#Use the mean and SD learned in step2 to convert test data]
4) Use the X_train_scaled for training the model and X_test_scaled in evaluation.