StandardScaler适用于整个训练数据集或单个折叠以进行交叉验证

时间:2020-02-05 16:28:03

标签: python scikit-learn cross-validation k-fold

我目前正在使用cross_val_score和KFold来评估在数据预处理的不同点使用StandardScaler的影响,特别是在执行交叉验证之前缩放整个训练数据集是否会导致数据泄漏以及这在什么时候会产生什么影响与在管道中缩放数据相比(因此仅将其应用于训练折叠)。

我当前的流程如下:

实验A

  • 从sklearn.datasets导入波士顿住房数据集,并分为数据(X)和目标(y)
  • 创建管道(sklearn.pipeline),在应用线性回归之前先应用StandardScaler
  • 将交叉验证方法指定为5折KFold
  • 使用上述Pipeline和KFold方法执行交叉验证(cross_val_score),并观察得分

实验B

  • 使用与上述相同的波士顿住房数据
  • 在整个数据集上
  • fit_transform StandardScaler
  • 使用cross_val_Score再次进行5倍交叉验证,但这一次直接输入LinearRegression,而不是管道
  • 比较此处的分数以进行实验A

获得的分数相同(大约13个小数位),我敢肯定,实验B在交叉验证期间引入了数据泄漏。

我看过一些帖子,指出在交叉验证之前是否对整个训练集进行缩放都没关系,如果这是真的,我想了解为什么,如果这不是真的,我想理解为什么尽管有数据泄漏,分数仍然可以如此相似?

请参阅下面的测试代码:

import numpy as np
import pandas as pd
from sklearn.pipeline import Pipeline
from sklearn import datasets

from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC
from sklearn.model_selection import KFold, StratifiedKFold

from sklearn.model_selection import cross_val_score, cross_val_predict

from sklearn.linear_model import LinearRegression

np.set_printoptions(15)

boston = datasets.load_boston()
X = boston["data"]
y = boston["target"]
scalar = StandardScaler()
clf = LinearRegression()

class StScaler(StandardScaler):
    def fit_transform(self,X,y=None):
        print('Length of Data on which scaler is fit on =', len(X))
        output = super().fit(X,y)
#         print('mean of scalar =',output.mean_)
        output = super().transform(X)
        return output


pipeline = Pipeline([('sc', StScaler()), ('estimator', clf)])

cv = KFold(n_splits=5, random_state=42)

cross_val_score(pipeline, X, y, cv = cv)

# Now fitting Scaler on whole train data
scaler_2 = StandardScaler()
clf_2 = LinearRegression()

X_ss = scaler_2.fit_transform(X)
cross_val_score(clf_2, X_ss, y, cv=cv)

谢谢!

0 个答案:

没有答案
相关问题