返回首页

Roadmap
更新于 2026年10月22日 全文 2616 字未阅读

数据集:数据的特征#

一个数据集,本质上就是一批样本的集合。

很多数据集会把数据存成表格(网格),即 $m$ 行样本 $n$ 列特征,比如逗号分隔的 CSV 文件,或者直接来自电子表格与数据库表。表格对机器学习模型来说是一种相当直观的输入格式:你可以把表格的每一行想成一个样本,每一列想成一个候选特征或标签。当然,数据集也可能来自其他形式,比如日志文件和 protocol buffer。

不管格式如何,模型的能力上限都不会超过它所训练的那份数据。这一节就来看看数据有哪几个关键特征。

数据的类型#

一个数据集里可能装着各种各样的数据类型,包括但不限于:

  • 数值型数据,课程中有一个 单独的小节专门讲它

  • 类别型数据,同样在 单独的小节里展开

  • 人类语言,从单个词语、单句话,一直到整篇文本

  • 多媒体,比如图像、视频和音频文件

  • 其他 ML 系统的输出

  • 嵌入向量,课程后面会有专门的小节介绍

数据的数量#

作为一条粗略的经验法则:模型可训练的参数有多少,样本数就至少要比它多一个数量级(最好两个)。不过实际情况是,好的模型往往用的样本远不止这个数。

在特征很少的大数据集上训练出来的模型,通常要优于在特征很多的小数据集上训练出来的模型。Google 长期以来就深谙此道——用简单的模型去喂海量的数据,往往能取得很好的效果。

不同的机器学习项目,需要的样本量可能相差得极其悬殊。有些相对简单的问题,几十个样本或许就够了;而另一些问题,一万亿个样本都可能不够用。

不过,如果你是在一个现成的模型上做微调,而且这个模型此前已经用同一套结构的海量数据训练过,那么小数据集也可能训出好结果。

数据的质量与可靠性#

人人都更喜欢高质量的数据,但「质量」这个概念实在太模糊了,可以被定义出无数种版本。课程在这里采用了一个务实的定义:

高质量的数据集,能帮助模型达成它的目标。

低质量的数据集,会妨碍模型达成它的目标。

高质量的数据集通常也是可靠的。可靠性指的是你能在多大程度上信任这份数据。用可靠数据训练出来的模型,比用不可靠数据训练出来的模型更有可能给出有用的预测。

要衡量可靠性,你需要弄清楚三件事:

  • 标签错误的普遍程度有多大?比如,如果你的数据是人工标注的,人工标注者犯错的比例有多高?

  • 你的特征是否有噪声?也就是说,特征里的数值本身是否含有错误?要现实一点——你不可能把数据集里的噪声全部清除干净。有些噪声是正常的;比如,任何位置的 GPS 测量值都会随时间有微小的波动。

  • 数据是否针对你的问题做了恰当的筛选?比如,你的数据集里该不该包含来自爬虫的搜索查询?如果你在做垃圾邮件检测系统,那答案很可能是「该包含」;但如果你想改进的是面向真人的搜索结果,那就「不该包含」。

以下几种情况,是数据不可靠的常见成因:

  • 值缺失。比如,某个人忘了填写房屋的年龄。

  • 样本重复。比如,服务器误把同一批日志上传了两次。

  • 特征值有误。比如,有人多敲了一个数字,或者温度计被落在了太阳底下。

  • 标签有误。比如,有人把一张橡树的照片错标成了枫树。

  • 数据中某一段整体有问题。比如,某个特征一向都很可靠,唯独网络持续崩溃的那一天出了岔子。

我们建议用自动化手段来标记不可靠的数据。例如,依赖外部正式数据结构信息的单元测试,就能把落在定义范围之外的值标出来。

注意: 任何足够大、足够多样的数据集,几乎必然包含落在你的数据结构信息或单元测试区间之外的异常值。如何处理这些异常值,本身就是机器学习的一道重要课题。数值型数据小节里详细讲了该怎么对付数值型异常值。

完整样本与不完整样本#

理想情况下,每个样本都是完整的,也就是说每个样本的每个特征都有值。

图 1. 一个样本,它五个特征全部都有取值。
图 1. 一个完整的样本

遗憾的是,现实中的样本经常是不完整的,也就是至少有一个特征值缺失。

图 2. 一个样本,五个特征里有四个有取值,剩下一个特征被标记为缺失。
图 2. 一个不完整的样本

不要拿不完整的样本去训练模型。相反,应该用下面两种方式之一把它们修复或者剔除掉:

  • 删除不完整的样本。

  • 插补缺失值,也就是为那些缺失的值提供有依据的猜测,把不完整样本补成一个完整样本。

MLWM: 最简单的插值策略可以说最值、最大值、最小值等方法。

图 3. 一个包含三个样本的数据集,其中两个是不完整样本,有人把这两个不完整样本从数据集里划掉了。
图 3. 从数据集中删除不完整的样本
图 4. 一个包含三个样本的数据集,其中两个是含有缺失数据的不完整样本。某个主体(人或插补软件)插入了新值,用来替换那些缺失的数据。
图 4. 为不完整的样本插补缺失值

如果数据集里的完整样本已经足够训练出一个有用的模型,那就考虑删掉那些不完整样本。同理,如果只有一个特征缺失的数据量很大,而这一个特征大概也帮不上模型多少忙,那就考虑把这个特征从模型输入里去掉,看看去掉之后质量掉了多少;模型照样好用或者几乎一样好用,那就是个皆大欢喜的结果。反过来,如果你的完整样本不够训出一个有用的模型,那或许可以考虑插补缺失值。

删掉无用或者冗余的样本当然没问题,删掉重要样本则是糟糕的做法。 不过不幸的是,要区分「无用样本」和「有用样本」并不容易。如果你实在拿不定主意该删还是该插,不妨构建两份数据集:一份由删除不完整样本得到,另一份由插补得到。然后比较一下,看哪一份能训出更好的模型。

精明的算法确实能插补出相当不错的缺失值;但插补出来的值,几乎总是比不上真实值。所以,一份好数据集应该让模型分得清哪些值是插补来的、哪些是真实的。一种做法是在数据集里额外加一个布尔列,用它标明某个特征的值是否为插补而来。

比如,对于一个叫 temperature 的特征,你可以再加一个类似 temperature_is_imputed 的布尔特征。这样在训练时,模型多半会逐渐学会:对 temperature 这个特征,含有插补值的样本可信度要低于含有真实值的样本。


插补是生成有依据的数据,而不是编造随机或有欺骗性的数据。要当心:好的插补能改善模型,坏的插补则可能伤害模型。

一种常见的插补算法,是用均值或中位数作为插补值。因此,当你用 Z-score 来表示一个数值特征时,插补出来的值通常就是 0(因为 0 一般就是平均 Z-score)。

练习:检验你的理解#

像下面这个练习里按 Timestamp 排好序的数据集,有时确实能让插补变简单。但拿一个排好序的数据集去训练模型是个坏主意。所以,插补完之后,记得把训练集中样本的顺序打乱。

下面是某个数据集的两列数据,已按 Timestamp 排好序:

TimestampTemperature
June 8, 2023 09:0012
June 8, 2023 10:0018
June 8, 2023 11:00missing
June 8, 2023 12:0024
June 8, 2023 13:0038

下面哪个取值,是那个缺失的 Temperature 比较合理的插补值?

  • 23

  • 31

  • 51

点击查看答案

23 比较合理。 23 是相邻几个值(12、18、24 和 38)的均值。不过我们只看到了数据集的一小部分,所以也有可能 23 在别的日子对应 11:00 时会是个异常值。

31 不太可能。 从我们能看到的这部分数据集来看,31 对于 11:00 的温度来说高得多了。但除非把插补建立在大得多的样本量之上,否则我们无法确定。

51 非常不可能。 51 比这里显示的任何一个取值都高得多(因此也比均值高得多)。

关键术语:

  • 数据集

  • 嵌入向量

  • 样本

  • 特征

  • 模型

  • 值插补

  • Z-score 标准化

阅读 --