Fra*_*ank 3 python pipeline scikit-learn keras
我正在比较两个关于KerasRegressor使用Scikit-Learn的程序的性能StandardScaler:一个程序与Scikit-Learn Pipeline和一个程序没有Pipeline.
计划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)
Run Code Online (Sandbox Code Playgroud)
计划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)
Run Code Online (Sandbox Code Playgroud)
我的问题是,程序1可以使R2得分为0.98(平均3次试验),而程序2只能达到R2得分为0.84(平均3次试验).有谁可以解释这两个程序之间的区别?
在第二种情况下,你正在呼唤StandardScaler.fit_transform()两者X_train和X_test.它的错误用法.
你应该叫fit_transform()上X_train,然后只调用transform()上X_test.因为那是Pipeline做什么的.在Pipeline作为文档状态,将:
fit():
一个接一个地拟合所有变换并转换数据,然后使用最终估算器拟合变换后的数据
预测():
将变换应用于数据,并使用最终估算器进行预测
所以你看,它只适用transform()于测试数据,而不是fit_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)
Run Code Online (Sandbox Code Playgroud)
调用fit()或fit_transform()测试数据错误地将其缩放到与列车数据上使用的不同的比例.并且是预测变化的来源.
编辑:回答评论中的问题:
看,fit_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.
Run Code Online (Sandbox Code Playgroud)
场景2:错误(基本上等于场景1,反转缩放和随地吐痰操作)
1) Divide the X into X_train, X_test
2) scale.fit_transform(X) [# You are not using the returned value, only fitting the data, so equivalent to scale.fit(X)]
3.a) X_train_scaled = scale.transform(X_train) #[Equals X_scaled_train in scenario 1]
3.b) X_test_scaled = scale.transform(X_test) #[Equals X_scaled_test in scenario 1]
Run Code Online (Sandbox Code Playgroud)
您可以尝试任何方案,也许它会提高模型的性能.
但是有一件非常重要的事情在他们身上缺失.当你对整个数据进行缩放然后将它们分成训练和测试时,假设你知道测试(看不见的)数据,这在现实世界的情况下是不正确的.并会给你不符合现实世界结果的结果.因为在现实世界中,整个数据将是我们的训练数据.它也可能导致过度拟合,因为模型已经有一些关于测试数据的信息.
因此,在评估机器学习模型的性能时,建议您在对其执行任何操作之前保留测试数据.因为这是我们看不见的数据,所以我们对它一无所知.理想的操作路径就是我回答的那个,即:
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.
Run Code Online (Sandbox Code Playgroud)
希望对你有意义.
| 归档时间: |
|
| 查看次数: |
3057 次 |
| 最近记录: |