你必须熟悉你的数据。
你构建的任何机器学习模型都只与你提供的数据一样好。理解数据的第一步是实际查看一些原始值并计算一些基本统计数据。
在这篇文章中,你将发现如何通过 R 中的描述性统计示例和方法,快速掌握你的数据集。
如果你是一名刚开始使用 R 进行机器学习的开发者,这些方法非常适合你。
通过我的新书《R 语言机器学习精通》**启动你的项目**,其中包含**逐步教程**和所有示例的 **R 源代码**文件。
让我们开始吧。
- **2016 年 11 月更新**:作为有用的更新,本教程假设您已安装 **mlbench** 和 **e1071** R 包。可以通过键入以下命令进行安装:install.packages("e1071", "mlbench")

使用描述性统计在 R 中理解你的数据
摄影:Enamur Reza,保留部分权利。
你必须理解你的数据
理解你所拥有的数据至关重要。
你可以在数据上运行技术和算法,但只有当你花时间真正理解你的数据集时,你才能充分理解你所取得结果的背景。
更好地理解等于更好的结果
更深入地理解你的数据将给你带来更好的结果。
花时间研究你拥有的数据将以不那么明显的方式帮助你。你将对数据以及单个记录或观察所代表的实体建立直觉。这可能会让你偏向特定的技术(无论是好是坏),但你也可以从中获得灵感。
例如,详细检查您的数据可能会触发您探索特定技术的想法。
- **数据清洗**。您可能会发现缺失或损坏的数据,并想到执行各种数据清洗操作,例如标记或删除坏数据以及填补缺失数据。
- **数据转换**。你可能会发现一些属性具有熟悉的分布,例如高斯分布或指数分布,这会让你想到可以应用缩放、对数或其他转换。
- **数据建模**。你可能会注意到数据的属性,例如分布或数据类型,这些属性暗示了(或不暗示)使用特定的机器学习算法。
使用描述性统计
你需要查看你的数据。你需要从不同的角度查看你的数据。
检查您的数据将有助于您建立直觉,并促使您开始提出有关您拥有数据的问题。
多角度视角将挑战你从不同角度思考数据,帮助你提出更多更好的问题。
查看数据的两种方法是
- 描述性统计
- 数据可视化
首先也是最好的方法是在你的数据上计算基本的汇总描述性统计。
你需要了解你所拥有的数据的形状、大小、类型和总体布局。
让我们来看看一些你可以使用 R 总结数据的方法。
需要更多关于R机器学习的帮助吗?
参加我为期14天的免费电子邮件课程,了解如何在您的项目中使用R(附带示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
使用描述性统计在 R 中汇总数据
在本节中,您将发现 8 种快速简单的方法来汇总您的数据集。
每种方法都进行了简要描述,并包含一个 R 配方,您可以自己运行或复制并根据自己的需要进行调整。
1. 查看您的数据
首先要做的就是查看数据集中的一些原始数据。
如果您的数据集很小,您可能可以将其全部显示在屏幕上。通常情况并非如此,因此您可以取一小部分样本进行查看。
1 2 3 4 5 6 |
# 加载库 library(mlbench) # 加载数据集 data(PimaIndiansDiabetes) # 显示数据的前 20 行 head(PimaIndiansDiabetes, n=20) |
head 函数将显示数据的前 20 行供您查看和思考。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
pregnant glucose pressure triceps insulin mass pedigree age diabetes 1 6 148 72 35 0 33.6 0.627 50 pos 2 1 85 66 29 0 26.6 0.351 31 neg 3 8 183 64 0 0 23.3 0.672 32 pos 4 1 89 66 23 94 28.1 0.167 21 neg 5 0 137 40 35 168 43.1 2.288 33 pos 6 5 116 74 0 0 25.6 0.201 30 neg 7 3 78 50 32 88 31.0 0.248 26 pos 8 10 115 0 0 0 35.3 0.134 29 neg 9 2 197 70 45 543 30.5 0.158 53 pos 10 8 125 96 0 0 0.0 0.232 54 pos 11 4 110 92 0 0 37.6 0.191 30 neg 12 10 168 74 0 0 38.0 0.537 34 pos 13 10 139 80 0 0 27.1 1.441 57 neg 14 1 189 60 23 846 30.1 0.398 59 pos 15 5 166 72 19 175 25.8 0.587 51 pos 16 7 100 0 0 0 30.0 0.484 32 pos 17 0 118 84 47 230 45.8 0.551 31 pos 18 7 107 74 0 0 29.6 0.254 31 pos 19 1 103 30 38 83 43.3 0.183 33 neg 20 1 115 70 30 96 34.6 0.529 32 pos |
2. 你的数据维度
你有多少数据?你可能有一个大致的想法,但拥有一个精确的数字会更好。
如果实例很多,您可能需要处理数据的一个较小样本,以便模型训练和评估在计算上可行。如果属性数量庞大,您可能需要选择最相关的属性。如果属性数量多于实例数量,您可能需要选择特定的建模技术。
1 2 3 4 5 6 |
# 加载库 library(mlbench) # 加载数据集 data(PimaIndiansDiabetes) # 显示数据集的维度 dim(PimaIndiansDiabetes) |
这显示了你加载数据集的行数和列数。
1 |
[1] 768 9 |
3. 数据类型
你需要知道数据中属性的类型。
这非常宝贵。这些类型将指示进一步分析的类型、可视化类型,甚至可以使用的机器学习算法类型。
此外,也许某些属性被加载为一种类型(例如整数),而实际上可以表示为另一种类型(一个分类因子)。检查类型有助于暴露这些问题并及早激发想法。
1 2 3 4 5 6 |
# 加载库 library(mlbench) # 加载数据集 data(BostonHousing) # 列出每个属性的类型 sapply(BostonHousing, class) |
这列出了数据集中每个属性的数据类型。
1 2 3 4 |
crim zn indus chas nox rm age dis rad tax ptratio b "numeric" "numeric" "numeric" "factor" "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" lstat medv "numeric" "numeric" |
4. 类别分布
在分类问题中,你必须知道属于每个类值的实例的比例。
这很重要,因为它可能会突出数据显示出的不平衡,如果严重,可能需要通过重新平衡技术来解决。在多类别分类问题中,它可能会暴露出实例很少或为零的类别,这些类别可能是从数据集中删除的候选。
1 2 3 4 5 6 7 |
# 加载库 library(mlbench) # 加载数据集 data(PimaIndiansDiabetes) # 类别变量的分布 y <- PimaIndiansDiabetes$diabetes cbind(freq=table(y), percentage=prop.table(table(y))*100) |
这个方法创建了一个有用的表格,显示了属于每个类别的实例数量,以及这占整个数据集的百分比。
1 2 3 |
freq percentage neg 500 65.10417 pos 268 34.89583 |
5. 数据摘要
有一个非常有用的函数叫做 summary(),它会依次总结数据集中的每个属性。这是一个非常有用的函数。
该函数为每个属性创建一个表格并列出值的细分。因子被描述为每个类标签旁边的计数。数值属性被描述为
- 最小值
- 25th 百分位数
- 中位数
- 平均值
- 75th 百分位数
- 最大值
细分还包括属性缺失值的指示(标记为 N/A)。
1 2 3 4 |
# 加载iris数据集 data(iris) # 汇总数据集 summary(iris) |
您可以看到,这个方法会生成大量信息供您查看。请花时间逐一审阅每个属性。
1 2 3 4 5 6 7 |
Sepal.Length Sepal.Width Petal.Length Petal.Width Species Min. :4.300 Min. :2.000 Min. :1.000 Min. :0.100 setosa :50 1st Qu.:5.100 1st Qu.:2.800 1st Qu.:1.600 1st Qu.:0.300 versicolor:50 Median :5.800 Median :3.000 Median :4.350 Median :1.300 virginica :50 Mean :5.843 Mean :3.057 Mean :3.758 Mean :1.199 3rd Qu.:6.400 3rd Qu.:3.300 3rd Qu.:5.100 3rd Qu.:1.800 Max. :7.900 Max. :4.400 Max. :6.900 Max. :2.500 |
6. 标准差
上面 summary() 函数中缺少的一项是标准差。
标准差与均值一起可以帮助我们判断数据是否呈高斯分布(或近似高斯分布)。例如,它对于快速简便的异常值去除工具很有用,其中任何超出均值三倍标准差的值都超出了 99.7% 的数据。
1 2 3 4 5 6 |
# 加载库 library(mlbench) # 加载数据集 data(PimaIndiansDiabetes) # 计算所有属性的标准差 sapply(PimaIndiansDiabetes[,1:8], sd) |
这计算了数据集中每个数值属性的标准差。
1 2 |
pregnant glucose pressure triceps insulin mass pedigree age 3.3695781 31.9726182 19.3558072 15.9522176 115.2440024 7.8841603 0.3313286 11.7602315 |
7. 偏度
如果分布看起来有点像高斯分布,但偏向左侧或右侧,那么了解其偏度会很有用。
通过数据图(例如直方图或密度图)更容易感受偏度。从均值、标准差和四分位数中判断则更困难。
然而,提前计算偏度可以为你提供一个参考,如果你决定稍后纠正属性的偏度,就可以使用它。
1 2 3 4 5 6 7 8 9 |
# 加载库 library(mlbench) library(e1071) # 加载数据集 data(PimaIndiansDiabetes) # 计算每个变量的偏度 skew <- apply(PimaIndiansDiabetes[,1:8], 2, skewness) # 显示偏度,偏离 0 越大/越小表示偏度越大 print(skew) |
偏度值分布距离零越远,向左(负偏度值)或向右(正偏度值)的偏度越大。
1 2 |
pregnant glucose pressure triceps insulin mass pedigree age 0.8981549 0.1730754 -1.8364126 0.1089456 2.2633826 -0.4273073 1.9124179 1.1251880 |
8. 相关性
观察并思考属性之间如何相互关联非常重要。
对于数值属性,思考属性间交互的一种极佳方式是计算每对属性的相关性。
1 2 3 4 5 6 7 8 |
# 加载库 library(mlbench) # 加载数据集 data(PimaIndiansDiabetes) # 计算数值变量的相关矩阵 correlations <- cor(PimaIndiansDiabetes[,1:8]) # 显示相关矩阵 print(correlations) |
这会为数值数据创建所有属性对相关性的对称表。偏离零表示更强的正相关或负相关。高于 0.75 或低于 -0.75 的值可能更有趣,因为它们显示出高度相关性。1 和 -1 的值表示完全正相关或负相关。
1 2 3 4 5 6 7 8 9 |
pregnant glucose pressure triceps insulin mass pedigree age pregnant 1.00000000 0.12945867 0.14128198 -0.08167177 -0.07353461 0.01768309 -0.03352267 0.54434123 glucose 0.12945867 1.00000000 0.15258959 0.05732789 0.33135711 0.22107107 0.13733730 0.26351432 pressure 0.14128198 0.15258959 1.00000000 0.20737054 0.08893338 0.28180529 0.04126495 0.23952795 triceps -0.08167177 0.05732789 0.20737054 1.00000000 0.43678257 0.39257320 0.18392757 -0.11397026 insulin -0.07353461 0.33135711 0.08893338 0.43678257 1.00000000 0.19785906 0.18507093 -0.04216295 mass 0.01768309 0.22107107 0.28180529 0.39257320 0.19785906 1.00000000 0.14064695 0.03624187 pedigree -0.03352267 0.13733730 0.04126495 0.18392757 0.18507093 0.14064695 1.00000000 0.03356131 age 0.54434123 0.26351432 0.23952795 -0.11397026 -0.04216295 0.03624187 0.03356131 1.00000000 |
更多方法
这份数据汇总方法清单绝不完整,但它们足以让您快速对数据集有一个深刻的初步理解。
除了上述方法列表之外,您还可以进一步研究一些数据汇总方法,例如查看数据子集的统计数据。考虑研究 R 中的 `aggregate()` 函数。
你是否使用了本文未列出的数据汇总方法?请在下方留言,我很想听听你的经验。
温馨提示
本节为您提供了一些在审查数据时使用摘要统计信息的提示。
- **审查数字**。生成摘要统计数据是不够的。花点时间暂停,阅读并认真思考你看到的数字。
- **追问原因**。审查你的数据并提出大量问题。你为什么会看到这些特定的数字?思考这些数字如何与一般问题领域以及观察值相关的特定实体联系起来。
- **写下想法**。写下你的观察和想法。准备一个小文本文件或记事本,记下所有关于变量如何关联、数字意味着什么以及将来要尝试的技术的想法。你现在趁着数据新鲜时写下的东西,在你以后尝试新事物时会非常有价值。
你可以在 R 中汇总你的数据
**你不需要是 R 程序员**。R 中的数据汇总非常简单,如上面的食谱所示。如果你刚开始,你可以复制粘贴上面的食谱,并开始学习它们如何使用 R 内置帮助(例如:*?FunctionName*)工作。
**你不需要精通统计学**。本文中使用的统计数据非常简单,但你可能已经忘记了一些基础知识。你可以快速浏览维基百科,查找均值、标准差和四分位数等主题,以更新你的知识。
以下是一个简短的列表
相关文章请参阅:机器学习统计学速成班。
**你不需要自己的数据集**。上面每个示例都使用内置数据集或 R 包提供的数据集。`dataset` R 包中有许多有趣的数据集,你可以研究和使用。有关更多信息,请参阅 datasets R 包的文档。
总结
在这篇文章中,您发现了在开始机器学习项目之前描述数据集的重要性。
你发现了 8 种使用 R 汇总数据集的方法
- 查看你的数据
- 你数据的维度
- 数据类型
- 班级分布
- 数据摘要
- 标准差
- 偏度
- 相关性
你现在也有了可以复制粘贴到你项目中的方法。
行动步骤
你想提高你使用 R 的技能或在 R 中实践机器学习吗?
完成上面的每个示例。
- 打开 R 交互式环境。
- 输入或复制粘贴每个食谱并了解其工作原理。
- 深入研究并使用 ?FunctionName 了解有关所用特定功能的更多信息。
请回复并留言,我很想听听你的进展。
你有问题吗?请留言提问。
感谢这个超棒的博客!!!
很高兴你觉得它有用,Nader。
好文章,我喜欢。
第 5 节框之间“for your to review”这行应该改成“for you to review”。
第 2 节的第一句话应该以问号结尾。“温馨提示”部分“追问原因”点下的第二句话也应该如此。
抱歉,不是第 5 节。是第 1 节。
谢谢马歇尔,已修复。
太棒了,杰森!这将帮助我在 R 中动手实践!
很高兴在这里听到,Ganesh。
感谢指导。对初学者非常有用!
很高兴听到这个消息,Bao。
非常感谢你,杰森。我一直在寻找一些有条理的描述性分析方法,时间不短了。你的文章无疑很好地回答了我的许多问题。
精彩的整理和指南。感谢你的帮助。
很高兴听到这个消息!
对于完全随机分布,您推荐哪些简单的统计数据?
我有以下问题,因为我有 130,000 个系统,每个月我都会统计每个系统的错误总数,到目前为止我找不到任何适合数据分布的模式。
我的兴趣不在于每月的总金额,而在于每台机器的行为。
机器1,一月错误,二月错误,三月错误,.....
真是有趣的设置!你希望从你的 130,000 个系统中了解什么?减少错误,还是预测什么??
好的笔记,但我会添加可视化以清晰显示(直方图、箱线图和 Q-Q 图)
不错。
非常有用,非常感谢
很高兴听到这个消息。
非常有用,作为初学者我学到了很多。非常感谢您。
偏度函数 (skew <- apply(PimaIndiansDiabetes[,1:8], 2, skewness)) 对我不起作用。有什么解释吗?
听到这个消息很抱歉,我也不确定。也许可以尝试在 Stack Overflow 上发帖求助?
如此有用的指南。非常感谢!!!
很高兴听到这个消息。
如果我们的数据来自临床试验,并且存在大量缺失值,这种 summary(my_data) 方法是否有效?
缺失值怎么办?
非常感谢。
我有一些建议可能有所帮助
https://machinelearning.org.cn/faq/single-faq/how-do-i-handle-missing-data
尊敬的Jason博士,
我能够为 Pima 印第安人数据库获取同时生成的箱线图
但是
当我尝试获取同时生成的直方图时,情况就不同了。
你有什么主意吗?
谢谢你,
悉尼的Anthony
列举每一列并为每一列创建一个直方图。
你的数据集名称有一个拼写错误——Indians——缺少 s
尊敬的Jason博士,
谢谢你,
你可以在一个图中得到所有 8 个直方图。
这表明在 R 中,您可以用一行代码绘制一组箱线图,但不能用一行代码绘制一组直方图。
我相信你可以,外面有成千上万的包。
此外,一个循环也可以在两行代码中完成相同的事情。
尊敬的Jason博士,
抱歉,doo1 那一行不应该在那里。不知道它是怎么出现的。
第一行应该写成
谢谢你,
悉尼的Anthony
是的。
尊敬的Jason博士,
一个更优雅的解决方案,尽管带有标签会更优雅。
但是对于多个箱线图,你可以使用一行代码,但对于一组直方图则不行。
谢谢你,
悉尼的Anthony
谢谢 Jason。
这很有帮助。
非常感谢您,Chinasa!我们感谢您的支持!