【问题标题】:Normalize data before or after split of training and testing data?在训练和测试数据拆分之前或之后规范化数据?
【发布时间】:2018-09-01 19:29:04
【问题描述】:

我想将我的数据分成训练集和测试集,我应该在拆分之前还是之后对数据应用归一化?在构建预测模型时有什么不同吗?

【问题讨论】:

    标签: machine-learning data-science normalization training-data train-test-split


    【解决方案1】:

    您首先需要将数据分成训练集和测试集(验证集也可能有用)。

    不要忘记测试数据点代表真实世界的数据。 解释(或预测)变量的特征归一化(或数据标准化)是一种通过减去均值并除以方差来对数据进行中心化和归一化的技术。如果您采用整个数据集的均值和方差,您将在训练解释变量(即均值和方差)中引入未来信息。

    因此,您应该对训练数据执行特征归一化。然后也对测试实例执行归一化,但这次使用训练解释变量的均值和方差。通过这种方式,我们可以测试和评估我们的模型是否可以很好地泛化到新的、看不见的数据点。

    更全面的阅读,可以阅读我的文章Feature Scaling and Normalisation in a nutshell


    举个例子,假设我们有以下数据:

    >>> import numpy as np
    >>> 
    >>> X, y = np.arange(10).reshape((5, 2)), range(5)
    

    X 代表我们的功能:

    >>> X
    [[0 1]
     [2 3]
     [4 5]
     [6 7]
     [8 9]]
    

    Y包含对应的标签

    >>> list(y)
    >>> [0, 1, 2, 3, 4]
    

    第 1 步:创建训练/测试集

    >>> X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)
    
    >>> X_train
    [[4 5]
     [0 1]
     [6 7]]
    >>>
    >>> X_test
    [[2 3]
     [8 9]]
    >>>
    >>> y_train
    [2, 0, 3]
    >>>
    >>> y_test
    [1, 4]
    

    第 2 步:规范化训练数据

    >>> from sklearn import preprocessing
    >>> 
    >>> normalizer = preprocessing.Normalizer()
    >>> normalized_train_X = normalizer.fit_transform(X_train)
    >>> normalized_train_X
    array([[0.62469505, 0.78086881],
           [0.        , 1.        ],
           [0.65079137, 0.7592566 ]])
    

    第 3 步:标准化测试数据

    >>> normalized_test_X = normalizer.transform(X_test)
    >>> normalized_test_X
    array([[0.5547002 , 0.83205029],
           [0.66436384, 0.74740932]])
    

    【讨论】:

    • 一个很好的答案,你可以分享更新你的帖子的例子“然后对测试实例执行标准化,但这次使用训练解释变量的均值和方差。”这部分。谢谢
    • @jax 更多详情可以参考这篇博文:medium.com/@giorgosmyrianthous/…
    • 我仍然对此感到困惑。在机器学习圣经“统计学习要素”中,它说在拆分之前执行任何形式的无监督预处理都是可以的。论点是,由于您没有使用标签,因此您不会对估算器产生偏见。此外,任何 ML 模型的基本假设是训练、验证、测试分割都是来自相同总体的样本。所以总体均值(或方差或任何时刻)是唯一的,无论我们使用我们的整个可用数据集还是它的一个子集来估计它只会影响我们有多好估计一下
    • 但后来我也理解另一个实用的观点,就是在现实世界中我们无法访问测试集,所以我们不应该真的用它来计算人口平均值等。
    【解决方案2】:

    你可以使用 fit 然后变换 学习

    normalizer = preprocessing.Normalizer().fit(xtrain)
    

    变换

    xtrainnorm = normalizer.transform(xtrain) 
    xtestnorm = normalizer.transform(Xtest) 
    

    【讨论】:

    【解决方案3】:

    根据您是在拆分之前还是之后进行转换,问问自己您的数据是否会有所不同。如果您正在进行log2 转换,则顺序无关紧要,因为每个值都独立于其他值进行转换。如果您要对数据进行缩放和中心化,那么顺序确实很重要,因为异常值会极大地改变最终分布。您允许测试集“溢出”并影响您的训练集,可能会导致性能指标过于乐观。

    对于R 的使用,caret 包擅长处理测试/训练拆分。您可以将参数 preProcess = c("scale", "center") 添加到 train 函数中,它会自动将任何从训练数据转换到测试数据上。

    Tl;dr - 如果数据因拆分前后的标准化而有所不同,请在拆分之前进行

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-01
      • 2020-11-01
      • 2021-05-13
      • 2020-10-21
      • 2015-10-09
      • 1970-01-01
      • 2019-06-14
      • 2021-12-28
      相关资源
      最近更新 更多