在 R 中通过预处理为机器学习准备数据

为了从机器学习算法中获得最佳结果,需要准备数据。

在这篇文章中,您将了解如何使用 caret 包在 R 语言中转换数据,以最好地向机器学习算法展示其结构。

您将学习 8 种流行且强大的数据转换方法,并附带食谱,您可以学习或复制粘贴到您当前或下一个机器学习项目中。

使用我的新书《R 机器学习精通》**启动您的项目**,其中包括**分步教程**和所有示例的 **R 源代码**文件。

让我们开始吧。

Pre-Process Your Machine Learning Dataset in R

在 R 语言中预处理您的机器学习数据集
图片由 Fraser Cairns 拍摄,保留部分权利。

数据预处理的必要性

您希望从数据集上的机器学习算法中获得最佳准确性。

一些机器学习算法要求数据采用特定形式。而其他算法如果以特定方式准备数据可以表现得更好,但并非总是如此。最后,您的原始数据可能不是最佳格式,无法最好地揭示潜在结构和与预测变量的关系。

以一种能够使各种不同的机器学习算法在您的问题上获得最佳机会的方式准备数据非常重要。

您需要将原始数据预处理作为机器学习项目的一部分。

数据预处理方法

很难知道使用哪种数据预处理方法。

您可以使用经验法则,例如

  • 如果输入属性具有相同的比例,基于实例的方法更有效。
  • 如果输入属性经过标准化,回归方法可以更好地工作。

这些是启发式方法,而不是机器学习的硬性规定,因为有时如果您忽略它们,您可能会获得更好的结果。

您应该尝试一系列数据转换和一系列不同的机器学习算法。这将帮助您发现数据的良好表示以及更善于利用这些表示所揭示的结构的算法。

最好单独检查一些转换,以及转换的组合。

在下一节中,您将了解如何使用 caret 包在 R 语言中应用数据转换来准备数据。

需要更多关于R机器学习的帮助吗?

参加我为期14天的免费电子邮件课程,了解如何在您的项目中使用R(附带示例代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

使用 R 语言中的 Caret 包进行数据预处理

R 语言中的 caret 包提供了许多有用的数据转换功能。

这些转换可以通过两种方式使用。

  • **独立使用**:可以根据训练数据对转换进行建模,并将其应用于多个数据集。转换模型使用 *preProcess()* 函数准备,并使用 *predict()* 函数应用于数据集。
  • **训练时使用**:可以在模型评估期间自动准备和应用转换。在训练期间应用的转换使用 *preProcess()* 函数准备,并通过 preProcess 参数传递给 *train()* 函数。

本节介绍了许多数据预处理示例。它们使用独立方法呈现,但您也可以在模型训练期间轻松使用准备好的预处理模型。

本节中的所有预处理示例均针对数值数据。请注意,预处理函数将跳过非数值数据而不会引发错误。

您可以通过阅读 preProcess 函数的帮助文档(键入 ?preProcess)和阅读 Caret 预处理页面来了解有关 caret 包提供的数据转换的更多信息。

所呈现的数据转换更可能对回归算法、基于实例的方法(如 kNN 和 LVQ)、支持向量机和神经网络等算法有用。它们不太可能对基于树和规则的方法有用。

转换方法总结

以下是 caret 包中 *preProcess()* 函数的 method 参数支持的所有转换方法的快速摘要。

  • "BoxCox":应用 Box-Cox 变换,值必须为非零正数。
  • "YeoJohnson":应用 Yeo-Johnson 变换,类似于 BoxCox,但值可以为负数。
  • "expoTrans":应用幂变换,如 BoxCox 和 YeoJohnson。
  • "zv":删除方差为零的属性(所有值都相同)。
  • "nzv":删除方差接近零的属性(接近相同的值)。
  • "center":从值中减去均值。
  • "scale":将值除以标准差。
  • "range":标准化值。
  • "pca":将数据转换为主成分。
  • "ica":将数据转换为独立成分。
  • "spatialSign":将数据投影到单位圆上。

以下各节将演示一些更流行的方法。

1. 缩放

缩放转换计算属性的标准差,并将每个值除以该标准差。

运行该配方,您将看到

2. 居中

居中变换计算属性的平均值并从每个值中减去它。

运行该配方,您将看到

3. 标准化

结合缩放和居中变换将标准化您的数据。属性的平均值将为 0,标准差为 1。

请注意,在 caret 中定义 preProcess 过程时,我们如何在列表中列出多个方法。运行该配方,您将看到

4. 归一化

数据值可以缩放到 [0, 1] 的范围,这称为归一化。

运行该配方,您将看到

5. Box-Cox 变换

当属性具有高斯分布但发生偏移时,这称为偏斜。可以对属性的分布进行偏移以减少偏斜并使其更接近高斯分布。BoxCox 变换可以执行此操作(假设所有值均为正)。

请注意,我们将转换仅应用于两个似乎有偏斜的属性。运行该配方,您将看到

有关此变换的更多信息,请参阅 Box-Cox 变换维基百科

6. Yeo-Johnson 变换

另一种类似于 Box-Cox 变换的幂变换,但它支持等于零和负数的原始值。

运行该配方,您将看到

7. 主成分分析

将数据转换为主成分。该转换保留方差阈值(默认=0.95)之上的成分,或者可以指定成分数量(pcaComp)。结果是属性不相关,这对于线性回归和广义线性回归等算法非常有用。

请注意,当我们运行食谱时,只选择了两个主成分。

8. 独立成分分析

将数据转换为独立成分。与 PCA 不同,ICA 保留独立成分。您必须使用 *n.comp* 参数指定所需的独立成分数量。对于朴素贝叶斯等算法很有用。

运行该配方,您将看到

数据转换技巧

以下是一些充分利用数据转换的技巧。

  • **实际使用它们**。如果您正在考虑并使用数据转换来准备数据,您就领先一步。这是一个很容易忘记或跳过的步骤,但通常对最终模型的准确性有巨大影响。
  • **使用多种方法**。使用一系列不同的机器学习算法对您的数据尝试多种不同的数据转换。
  • **回顾总结**。最好在转换前后总结您的数据,以了解其产生的影响。*summary()* 函数非常有用。
  • **可视化数据**。在转换前后可视化数据分布也是一个好主意,以便对转换效果有一个空间直觉。

总结

在本节中,您通过 caret 包发现了 8 种可以在 R 中对数据使用的预处理方法

  • 数据缩放
  • 数据居中
  • 数据标准化
  • 数据归一化
  • Box-Cox 变换
  • Yeo-Johnson 变换
  • PCA 变换
  • ICA 变换

您可以使用本节中提供的食谱进行练习,或将其应用于您当前或下一个机器学习项目。

下一步

您是否尝试过这些食谱?

  1. 启动您的 R 交互式环境。
  2. 键入或复制粘贴上述食谱并进行尝试。
  3. 使用 R 中的内置帮助来了解有关所用函数的更多信息。

您有问题吗?在评论中提问,我将尽力回答。

在R中发现更快的机器学习!

Master Machine Learning With R

在几分钟内开发您自己的模型

...只需几行R代码

在我的新电子书中探索如何实现
精通 R 语言机器学习

涵盖自学教程端到端项目,例如
加载数据、可视化、构建模型、调优等等...

最终将机器学习应用到您自己的项目中

跳过学术理论。只看结果。

查看内容

对《在 R 语言中使用预处理技术为机器学习准备数据》的 61 条回复

  1. yash 2016 年 7 月 2 日晚上 9:01 #

    你好,

    在“转换方法总结”部分中提到:
    “中心”:将值除以标准差。
    “缩放”:从值中减去均值。
    但是,在方法演示中,“中心”和“缩放”的功能互换了,即:

    1. 缩放

    缩放转换计算属性的标准差,并将每个值除以该标准差。

    2. 居中

    居中变换计算属性的平均值并从每个值中减去它。

    那么这些方法的正确功能是什么?

    • Jason Brownlee 2016 年 7 月 3 日上午 7:36 #

      说得对,我已经修改了错别字。抱歉。

      中心:从值中减去均值。
      缩放:将值除以标准差。

  2. Michael 2016 年 11 月 2 日上午 11:13 #

    嗨 Jason

    如果我的一些变量是类别或因子,预处理会忽略它们吗?

    • Jason Brownlee 2016 年 11 月 3 日上午 7:49 #

      嗨,Michael,好问题。

      它可能会忽略它们,我相信这是默认行为。

  3. Michael 2016 年 11 月 2 日下午 3:55 #

    嗨 Jason

    我喜欢你的书,它们写得很好,而且

    我正在参加 Kaggle 竞赛,例如

    https://www.kaggle.com/c/allstate-claims-severity

    许多预测变量都是分类的,我已将它们转换为因子等,例如 a,b,c 等,还有一些连续变量。

    请指点我如何使用 caret 预处理这些数据。

    我想在模型上使用随机森林。

    谢谢

    Michael

  4. Zoraze 2016 年 11 月 4 日上午 12:48 #

    你好,

    预处理后,我如何将数据转换回原始值?

    诚挚的问候,
    Zoraze

    • Jason Brownlee 2016 年 11 月 4 日上午 9:10 #

      很好的问题,Zoraze。

      您需要手动执行转换,例如归一化。然后使用相同的系数稍后反转转换。

      如果您使用 caret,它可以在训练期间自动执行这些操作(如果需要)。

  5. Goran 2017 年 1 月 20 日晚上 10:02 #

    你好,

    我们什么时候应该应用标准化?
    我目前正在应用归一化(变量以不同单位表示)。我接下来应该应用标准化吗?

    • Jason Brownlee 2017 年 1 月 21 日上午 10:33 #

      好问题,Goran。

      严格来说,当您的单变量分布是高斯分布,特征之间的单位不同,并且您的算法假设单位不变化且单变量分布是高斯分布时,标准化会有所帮助。

      当您打破这个严格的启发式规则时,结果可能会很好甚至更好。

      通常,我建议为问题尝试一系列不同的数据缩放和转换,以找出哪些表示形式适合您的问题。

      • Goran 2017 年 1 月 23 日晚上 9:30 #

        此外,这是正确的流程吗?

        异常值移除 -> 缺失值填充 -> 数据处理(归一化等) -> 检查相关性?

        • Jason Brownlee 2017 年 1 月 24 日上午 11:04 #

          在我看来不错,Goran!

          • Goran 2017 年 1 月 24 日晚上 9:43 #

            谢谢你,Jason。

          • Skylar 2020 年 6 月 5 日下午 3:12 #

            嗨,Jason,

            我对流程有些疑问:我们是否应该首先检查预测变量之间的相关性以查看共线性,然后进行数据处理(归一化等)?我读了你的书,它遵循这个流程。谢谢!

          • Jason Brownlee 2020 年 6 月 6 日上午 7:45 #

            是的。

            或者,也许无论如何都要进行处理,并与原始数据拟合的模型进行比较,看看它是否能提高性能。

  6. Natasa 2017 年 6 月 27 日晚上 9:49 #

    Jason,我使用预处理(归一化)数据训练了我的 NN 模型,然后使用该模型进行预测(我输入的数据也已归一化)。我如何将预测结果转换为非归一化,使其有意义?谢谢。

    • Jason Brownlee 2017 年 6 月 28 日上午 6:24 #

      考虑查阅文献,了解其他实验中如何准备此类数据。

  7. Grace 2017 年 8 月 4 日上午 5:28 #

    嗨,Jason,我用预处理(归一化)数据训练了我的 NN 模型,然后用该模型进行预测(我输入的数据也经过归一化)。我如何将预测结果转换为未归一化的形式,使其有意义?谢谢。

    • Jason Brownlee 2017 年 8 月 4 日上午 7:04 #

      是的,您可以反转缩放转换。抱歉,手头没有示例。

  8. Vaibhav Nellore 2017 年 9 月 6 日下午 5:28 #

    嗨,Jason,

    我使用 preProcess 来标准化我的训练数据集(数据框)。然后,我使用它并开发了一个模型。

    然后,为了在我的测试数据集(数据框)上测试我的模型,我需要使用训练数据集中变量的相同均值和标准差来标准化测试数据集中的变量。(只是,如果我错了请纠正我!?)如果是这样,有没有什么包或方法可以做到这一点?

    • Jason Brownlee 2017 年 9 月 7 日下午 12:50 #

      我在 Python 中有这方面的示例,但在 R 中没有,抱歉。

  9. moumtana 2017 年 10 月 22 日下午 3:33 #

    亲爱的 Brownlee,

    非常感谢您的食谱,它们帮助我很多。我想问是否有 R 语言食谱可以使用

    ISOMAP(非线性)预处理。

    提前感谢你

    Moumtana

  10. abdal 2017 年 11 月 20 日晚上 7:39 #

    嗨 Jason,感谢您的教程,但我遇到了一个问题,在训练和测试之后,我向神经网络提供标准化形式的新输入以获取新的已知输出,这些输出也在标准化范围内,我如何将输出恢复到原始的非标准化范围。

  11. Noelia 2017 年 12 月 15 日晚上 11:11 #

    嗨,Jason,

    如果我有一个分类变量数据集,它们具有相同的单位但值差异很大(比如 8 岁和 25 岁时的身高):建议对它们进行标准化吗?我的意思是,我不知道该怎么做,因为对于所有这些变量,单位都代表相同的距离。

    另外,是否有哪种数据集强烈建议应用归一化?

    我正在努力理解所有这些概念,尽管现在我开始理解它们了,但我不知道何时应该应用每个概念。

    • Jason Brownlee 2017 年 12 月 16 日上午 5:27 #

      这些听起来像数值而不是分类值。

      如果变量是高斯分布,标准化是一个好主意,尝试一下,看看它如何影响模型技能。如果不是,请尝试归一化。

  12. Abdou 2018 年 6 月 6 日上午 3:35 #

    嗨,Jason,

    在对测试集进行预测后,我正在努力反转这些转换。R 语言中是否有类似于 Python 的 fit_transform() 和 inverse_transform() 的方法来执行反转操作?谢谢。

    • Jason Brownlee 2018 年 6 月 6 日上午 6:42 #

      通常 caret 包会为您处理这个问题。

      • Marcin 2018 年 11 月 6 日晚上 8:57 #

        您是否可以编辑当前文章或另外撰写一篇博文,介绍如何使用 caret 在预测后反转预处理转换。这将极大地增强本文的价值。

  13. Vijaya 2018 年 7 月 6 日上午 11:31 #

    嗨,Jason,
    我只想知道 SVM 使用 R 和 Python 的降维技术有哪些。

    • Jason Brownlee 2018 年 7 月 7 日上午 6:10 #

      与其他方法相同,pca、svd、特征选择、sammons、som、tsne 等。

  14. ani_weck 2018 年 11 月 3 日上午 10:06 #

    嗨,Jason,
    我如何查看预处理结果对我的输入数据的影响?我只是想检查不同的参数对我的数据集(例如,范围与缩放)做了什么。

    • Jason Brownlee 2018 年 11 月 4 日上午 6:24 #

      您可能需要单独执行数据准备操作。

  15. Ton 2019 年 2 月 21 日下午 6:21 #

    亲爱的 Jason!
    如果我使用独立方法进行数据预处理,预处理步骤会在训练步骤中作为默认选项再次执行吗?

    • Jason Brownlee 2019 年 2 月 22 日上午 6:15 #

      抱歉,我不太明白,您能详细说明一下吗?

  16. laz 2019 年 6 月 29 日上午 10:33 #

    亲爱的 Jason,感谢您撰写的精彩文章。

    我有一个关于 caret 包在时间切片模式下进行预处理的问题。

    我们像这样将数据分成相等的训练/测试折叠:

    1] “———————————- 训练折叠[1] | 长度 861”
    # 从 1 2 3 4 5 6
    ### 到 856 857 858 859 860 861
    [1] “———————————- 训练折叠[2] | 长度 861”
    # 从 431 432 433 434 435 436
    ### 到 1286 1287 1288 1289 1290 1291
    [1] “———————————- 训练折叠[3] | 长度 861”
    # 从 861 862 863 864 865 866
    ### 到 1716 1717 1718 1719 1720 1721

    [1] “———————————- 测试折叠[1] | 长度 430”
    # 从 862 863 864 865 866 867
    ### 到 1286 1287 1288 1289 1290 1291
    [1] “———————————- 测试折叠[2] | 长度 430”
    # 从 1292 1293 1294 1295 1296 1297
    ### 到 1716 1717 1718 1719 1720 1721
    [1] “———————————- 测试折叠[3] | 长度 430”
    # 从 1722 1723 1724 1725 1726 1727
    ### 到 2146 2147 2148 2149 2150 2151

    等等…

    现在 caret 开始在“训练折叠[1]”上训练。使用“center+scale”时,它使用“训练折叠[1]”来获取“训练折叠[1]”中所有训练数据的均值和标准差。

    Caret 从完整的训练数据中计算均值和标准差,那么如果 caret 训练一个模型,这个模型是否已经知道未来的均值和标准差了?

    我的模型过度拟合了训练数据,我知道有很多可能的原因。但这是否也可能是由这种数据窥探造成的?这算是数据窥探吗?

    谢谢!

  17. Mano Brown 2019 年 6 月 29 日下午 7:21 #

    嗨,Jason,

    您能否写一篇关于如何在“R 语言中您的第一个机器学习项目:一步一步(未来项目的教程和模板)”中执行标准化技术的帖子。

    诚挚的问候,

    Mano Brown

    • Jason Brownlee 2019 年 6 月 30 日上午 9:38 #

      谢谢你的建议,Mano。也许以后会写。

  18. Tanuja Joshi 2019 年 7 月 1 日下午 3:13 #

    嗨 Jason,我目前正在处理贷款数据集,其中包含属性“利率”(以 % 为单位的条目)。我想对数据进行归一化。那么我应该如何处理这个属性呢?
    在归一化之前需要删除百分比吗?

    • Jason Brownlee 2019 年 7 月 2 日上午 7:28 #

      是的,机器学习算法必须处理数字。

  19. Anupam Mukherjee 2019 年 7 月 9 日晚上 7:16 #

    非常感谢您在机器学习教学上所做的一切努力 :)

    我如何将训练数据上的缩放信息应用到测试集?或者我们可以独立缩放训练和测试数据?

  20. Shivendra 2019 年 7 月 24 日晚上 8:49 #

    Jason,太棒了!但是您有没有关于 R 语言中独热编码的教程,类似于您为 Python 编写的教程?那将非常棒,并且能让我(我)比较两种语言中的某些差异。

    祝好,
    Shivendra

  21. John 2019 年 8 月 15 日上午 11:44 #

    Python 有 StandardScaler,它似乎是 Center 和 Scale 的组合
    输出 = (x – u)/s
    这是否等同于您所说的
    method=c(“center”, “scale”))
    谢谢!

  22. Bharat 2019 年 10 月 11 日下午 2:57 #

    嗨,Jason,

    您有没有遇到过针对混合数据类型的 KNN 算法示例?如何处理只有 0 和 1 的因子(分类数据)。性别“男”和“女”。这是一个分类问题。

    谢谢
    Bharat

    • Jason Brownlee 2019 年 10 月 12 日上午 6:46 #

      是的,通常汉明距离或布尔值(相同 == 0,不同 == 1)对于分类数据很有用,可以将其添加到标准化数值的欧几里德距离中。

  23. Sunil Kappal 2019 年 10 月 19 日上午 12:05 #

    非常感谢这篇精彩的文章,我正在考虑是否存在一种可能性或方法,可以使用中位数和中位数绝对离差来居中数据,尤其是在存在极端异常值的情况下。我还没有看到任何明确针对这种现象进行归一化处理的数据归一化技术或例程。

    • Jason Brownlee 2019 年 10 月 19 日上午 6:45 #

      当然,也许在您的问题上尝试一下,看看是否有帮助?

  24. Huaichao 2020 年 4 月 29 日下午 6:45 #

    谢谢您的分享,我有一个问题,每次我们进行居中处理时,都会出现负值,这是不希望的,但这种方法是否存在错误?

    • Jason Brownlee 2020 年 4 月 30 日上午 6:40 #

      如果你不想要负值,可以使用归一化代替。

  25. Balaji Sundararaman 2020 年 5 月 24 日下午 3:10 #

    嗨,Jason,
    谢谢你。在建模和预测之后,如何将预处理(例如缩放、居中、范围)的值转换回原始值。caret 包中有没有这样的方法。
    谢谢。

  26. Ajax 2021 年 6 月 14 日上午 10:27 #

    嗨,Jason,
    您在下面的预测步骤中做了什么?
    library(caret)
    # 加载数据集
    data(iris)
    # 总结数据
    summary(iris[,1:4])
    # 从数据集中计算预处理参数
    preprocessParams <- preProcess(iris[,1:4], method=c("range"))
    # 总结转换参数
    print(preprocessParams)
    # 使用参数转换数据集
    transformed <- predict(preprocessParams, iris[,1:4])<—–这里预测的是什么?
    # 总结转换后的数据集
    summary(transformed)

    • Jason Brownlee 2021 年 6 月 15 日上午 6:02 #

      我们正在转换输入变量,具体来说,我们正在缩放它们的值。

发表回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。