Python 使用Scikit Learn StandardScaler(带管道和不带管道)进行Keras回归
我正在使用Scikit LearnPython 使用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
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.