【问题标题】:Is it correct to use a single StandardScaler before splitting data?在拆分数据之前使用单个 StandardScaler 是否正确?
【发布时间】:2020-11-12 04:12:53
【问题描述】:

我见过一些使用两个不同StandardScaler 的实验,如下所示:

scaler_1 = StandardScaler().fit(X_train)
train_sc = scaler_1.transform(X_train)

scaler_2 = StandardScaler().fit(X_test)
test_sc = scaler_2.fit(X_test)

我知道不应该对混合训练/测试数据的分类器产生偏见,但我想知道这种其他情况是否正确:

# X_all represents X feature vector before splitting (train + test)
X_scaled = StandardScaler().fit_transform(X_all)

X_train, y_train, X_test, y_test = train_test_split(X_scaled,y_all)

此外,我想知道这个案例如何扩展到KFold 交叉验证。

【问题讨论】:

    标签: machine-learning scikit-learn


    【解决方案1】:

    在拆分数据之前执行标准化是不正确的。一般来说,您不应该在整个数据集上拟合任何预处理算法(PCA、StandardScaler...),而只能在训练集上拟合,并使用拟合的算法对测试集进行变换。 p>

    因此,您提出的两种体验都不正确。你应该做的是:

    scaler = StandardScaler().fit(X_train)
    train_sc = scaler.transform(X_train)
    
    test_sc = scaler.transform(X_test)
    

    如果你这样想就很容易理解了:测试集是用来估计模型在unseen数据上的表现。所以你应该表现得好像你在训练算法时没有访问测试集,这对于交叉验证也是有效的。

    当您在整个数据集上拟合标准缩放器时,来自测试集的信息用于对训练集进行归一化。这是“数据泄漏”的常见情况,这意味着在训练模型时会使用来自测试集的信息。这通常会导致高估模型的性能。

    请注意,在 scikit-learn 中,您可以使用 Pipelines 将预处理步骤与估计器链接起来,并在交叉验证过程中使用它。这将确保对交叉验证过程的每个折叠重复相同的步骤。

    【讨论】:

    • 您好@A Co,如果您使用 cross_val_score 之类的东西或其他您不知道测试或训练数据的算法(即 KFold)怎么办?
    • Scikit-learn's Pipelines 是您需要的工具。您可以阅读此answer (and the associated post),它解决了完全相同的问题,并举例说明在这种情况下如何使用管道。
    【解决方案2】:

    最好的做法是假设您已经部署了模型,并且正在使用它来预测事物。想象一下,为您的模型提供了一个测试用例进行测试,或者您的模型倾向于在部署后预测输入。在这种情况下,您只有一个输入,因此将其用作标准 Scaler 的拟合数据是没有意义的,标准 Scaler 将这个单一实例作为其训练(拟合)数据,因为在这种情况下,缩放器的输出在缩放方面会与其他所有输入不同。因此,您最好使用训练集(即拆分后)训练(拟合)Standard Scaler,并使用安装标准定标器。

    此外,在机器学习项目的每个阶段,您最好只使用训练数据来拟合和训练您需要的任何东西(例如缩放器、预测器、回归器等),而将验证和测试数据仅用于验证和测试。

    对于交叉验证的情况,您最好安装一个缩放器并在交叉验证中转换您的数据,但它通常不会有太大的区别。不过你可以测试一下。

    【讨论】:

    • 很好的解释,但是如果您使用内置的 cross_val_score 或其他无法控制训练/测试数据集的 scikit-learn 函数怎么办?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-16
    • 2017-04-10
    • 2022-10-04
    • 1970-01-01
    • 2018-05-11
    • 2019-01-05
    • 2020-04-12
    相关资源
    最近更新 更多