本章中的主题对于塑造你的数据,以便从中获得最大价值,尤其是在监督学习环境中,对于模型来说是非常重要的。特别是标签化,通常是机器学习应用创建、维护和演化过程中最昂贵且最耗时的活动之一。充分理解可用的选项将帮助你更好地利用资源和预算。
为此,本章将讨论数据增强,一类通过向训练数据集中添加更多数据来改善训练的方法,通常是为了改善泛化能力。数据增强几乎总是基于操控当前数据来创建新的但仍然有效的样本变体。
我们还将讨论数据预处理,但本章将重点讨论特定领域的预处理。不同的领域,如时间序列、文本和图像,具有专门的特征工程形式。我们在“考虑实例级与全数据遍历转换”中讨论了其中的一种——文本的分词。在本章中,我们将回顾处理时间序列数据的常见方法。
但首先,让我们解答一个重要问题:如何以其他方式为样本分配标签,而不是逐个手动完成?换句话说,是否可以在不完全准确标签化的情况下自动化这个过程?答案是肯定的,我们通过高级标签化来实现这一目标。
高级标签化
为什么高级标签化很重要?随着机器学习(ML)在全球范围内的应用增长,机器学习需要训练数据。如果你正在进行监督学习,那么这些训练数据就需要标签,而监督学习占据了当前生产中大多数的机器学习应用。
但手动标签化数据通常既昂贵又困难,而未标记的数据通常便宜且容易获得,并且包含大量有助于改善模型的信息。因此,高级标签化技术帮助我们降低数据标签化的成本,同时利用大量未标记数据中的信息。
在本节中,我们将首先讨论半监督标签化的工作原理,以及如何通过将标签数据集扩展到提供最多预测信息的方向来提高模型的性能。接着,我们将讨论主动学习,它通过智能采样根据现有数据为未标记数据分配标签。然后,我们将介绍弱监督,这是通过使用由领域专家设计的启发式方法来程序化标签数据的高级技术。
半监督标签化
在半监督标签化中,你从一个相对较小的数据集开始,这个数据集已经通过人工标注。然后,你将这些已标注的数据与大量未标注的数据结合,通过查看不同人工标注类别在特征空间中的聚类情况来推断标签。接着,你使用这两个数据集的结合进行模型训练。这种方法基于这样的假设:不同的标签类别会在特征空间中聚集在一起,通常——但并非总是——这一假设是合理的。
使用半监督标签化有两个主要优势。首先,将标注数据与未标注数据结合可以增加特征空间的覆盖范围,正如在《特征选择》一节中所描述的,这可以提高机器学习模型的准确性。其次,获取未标注数据通常非常便宜,因为不需要人工分配标签。未标注数据通常可以轻松获得大量。
顺便说一句,不要将半监督标签化与半监督训练混淆,它们是非常不同的概念。我们将在后续章节中讨论半监督训练。
标签传播
标签传播是一种为之前未标记示例分配标签的算法。这使它成为一种半监督算法,其中一部分数据点有标签。该算法根据已标记数据点和未标记数据点的相似性或社区结构,将标签传播给未标记的数据点。这种相似性或结构用于为未标记数据分配标签。
在图5-1中,你可以看到一些已标记的数据(用三角形表示)和大量未标记的数据(用圆圈表示)。通过标签传播,你可以根据未标记数据与邻居的聚类情况为它们分配标签。
标签然后被传播到其余的簇中,如不同的阴影所示。我们应该提到,标签传播有许多不同的实现方式——基于图的标签传播只是其中的一种技术。标签传播本身被认为是一种传递学习(transductive learning),意味着我们是从示例本身进行映射,而不是为映射学习一个函数。
采样技术
通常,已标记的数据集会比可用的未标记数据集小。如果你打算通过标记新数据来扩展已标记的数据集,你需要一种方法来决定标记哪些未标记示例。你可以随机选择它们,这种方法称为随机采样。或者,你可以尝试以某种方式选择最好的示例,即那些能最大程度提升你模型的示例。对于选择最佳示例,有各种技术,我们接下来将介绍其中的一些。
主动学习
主动学习是一种智能化的数据采样方式,选择那些能为你的模型带来最大预测价值的未标记数据点。这在多种情况下非常有帮助,尤其是在数据预算有限时。标记数据是需要花费成本的,特别是当你使用人工专家查看数据并为其分配标签时。主动学习帮助你确保将资源集中在那些能为你带来最大效益的数据上。
如果你的数据集不平衡,主动学习是训练阶段选择稀有类别的高效方式。如果标准的采样策略不能帮助提高准确性和其他目标指标,主动学习通常能够提供实现所需准确度的方法。
主动学习策略依赖于能够选择哪些示例进行标记,这些示例最有助于模型学习。在完全监督的环境中,训练数据集仅包含那些已经标记的示例。在半监督环境中,你利用已标记的示例来标记一些额外的、之前未标记的示例,以增加已标记数据集的大小。主动学习则是一种选择哪些未标记示例进行标记的方法。
一个典型的主动学习循环如下进行:
- 你从一个已标记的数据集开始,使用这些数据训练模型,同时还有一个未标记的数据池。
- 主动学习通过智能采样选择一些未标记的示例(在接下来的章节中将详细描述)。
- 你用人工标注者或利用其他技术标记被选中的示例,这样你就得到了一个更大的已标记数据集。
- 使用这个更大的已标记数据集重新训练模型,可能会启动新的主动学习循环。
但这引出了一个问题:我们如何进行智能采样?
边际采样
边际采样是进行智能采样的广泛使用的技术之一。边际采样是一种有价值的主动学习技术,专注于查询最不确定的样本,即那些最接近决策边界的样本,以提高模型的学习效率和性能。
在图5-2中,数据属于两类。此外,还有未标记的数据点。在这种设置下,最简单的策略是基于已标记数据训练一个二元线性分类模型,从而输出一个决策边界。
通过主动学习,你选择下一个最不确定的点进行标记,并将其添加到数据集中。边际采样将最不确定的点定义为最接近决策边界的点。
如图5-3所示,使用这个新的标记数据点,你重新训练模型以学习新的分类边界。通过移动边界,模型能更好地学习区分不同的类别。接下来,你找到下一个最不确定的数据点,然后重复这一过程,直到模型不再提升。
图5-4展示了不同采样技术下,模型准确性与训练样本数量的关系。底部的线条显示了随机采样的结果。顶部的两条线显示了使用主动学习的两种边际采样算法的表现(此时两者之间的差异并不重要)。
从x轴可以看出,边际采样在使用更少的训练样本时比随机采样达到更高的准确性。最终,随着更多未标记数据通过随机采样被标记,随机采样的准确性追赶上了边际采样。这与我们预期的结果一致,如果边际采样智能地选择最好的示例进行标记的话。
其他采样技术
边际采样只是其中一种智能采样技术。如你所见,在边际采样中,你根据数据点与决策边界的距离来为最不确定的点分配标签。另一种技术是基于聚类的采样,其中通过对特征空间进行聚类方法来选择多样化的数据点。还有一种技术是“委员会查询”(query by committee),在这种方法中,你训练多个模型,并选择它们之间最大分歧的数据点。最后,基于区域的采样是一种相对较新的算法。从高层次来看,该算法通过将输入空间划分为不同的区域,并在每个区域上运行主动学习算法来工作。
弱监督
手动为机器学习问题标注训练数据是有效的,但非常劳动密集且耗时。本文探讨了如何利用依赖于其他知识来源的算法标签系统,这些系统可以提供更多标签,但它们是噪声性的。
——杰夫·迪恩,谷歌研究与AI高级副总裁,2019年3月14日
弱监督是一种通过使用一个或多个来源的信息来生成标签的方法,通常是领域专家和/或启发式方法。生成的标签是噪声性的和概率性的,而不是我们习惯的确定性标签。它们提供了实际标签应该是什么的信号,但不要求它们100%正确。相反,它们有一定的概率是正确的。
更严格地说,弱监督包括一个或多个未标记数据上的噪声条件分布,主要目标是学习一个生成模型,该模型决定这些噪声源的相关性。
从没有真实标签的未标记数据开始,你将加入一个或多个弱监督源。这些源是一组启发式程序,执行噪声性和不完美的自动标签。领域专家是设计这些启发式方法的最常见来源,这些启发式方法通常包括一个覆盖集和该覆盖集上的真实标签的预期概率。我们所说的“噪声性”意味着标签有一定的正确概率,而不是我们通常在监督学习标记数据中习惯的100%确定性。主要目标是学习每个弱监督源的可信度。这通过训练一个生成模型来完成。
Snorkel框架于2016年由斯坦福大学推出,是实现弱监督的最广泛使用的框架。它不需要手动标签,因此系统可以程序化地构建和管理训练数据集。Snorkel提供了清理、建模和集成弱监督管道生成的训练数据的工具。Snorkel使用新颖的、理论上有依据的技术,能够快速有效地完成工作。Snorkel还提供数据增强和切片功能,但我们这里重点关注的是弱监督。
使用Snorkel,你从未标记的数据开始,应用标签函数(由领域专家设计的启发式方法)生成噪声标签。然后,你使用生成模型去噪声标签并为不同的标签函数分配重要性权重。最后,你使用去噪后的标签训练一个判别模型——即你的模型。
让我们看一下几个简单的标签函数在代码中的实现。下面是一个使用Snorkel标注垃圾邮件的简单方法:
from snorkel.labeling import labeling_function
@labeling_function()
def lf_contains_my(x):
# 许多垃圾评论提到“我的频道”、“我的视频”等
return SPAM if "my" in x.text.lower() else ABSTAIN
@labeling_function()
def lf_short_comment(x):
# 非垃圾评论通常较短,例如“酷视频!”
return NOT_SPAM if len(x.text.split()) < 5 else ABSTAIN
第一步是从Snorkel导入labeling_function。第一个函数(lf_contains_my)如果消息中包含“my”一词,则标记为垃圾邮件。否则,函数返回ABSTAIN,表示它不对标签应该是什么发表意见。第二个函数(lf_short_comment)如果消息少于五个单词,则将其标记为非垃圾邮件。
高级标签化回顾
监督学习需要标注数据,但数据标签化通常是一个昂贵、困难且缓慢的过程。让我们回顾一下高级标签化技术的关键点,这些技术相比于传统的监督学习提供了更多的优势:
半监督学习 介于无监督学习和监督学习之间。它通过将少量已标注数据与大量未标注数据结合来工作,从而提高学习准确性。
主动学习 依赖智能采样技术,选择最重要的示例进行标注并添加到数据集中。主动学习提高了预测准确性,同时最小化了标签化成本。
弱监督 在监督学习环境中,利用噪声、有限或不准确的标签来源,测试标签准确性。Snorkel是一个紧凑且用户友好的系统,用于管理所有这些操作并通过弱监督建立训练数据集。
数据增强
在上一节中,我们探讨了通过标注未标记数据来获取更多标注数据的方法,但另一种方法是通过增强现有数据来创建更多的标注示例。通过数据增强,你可以通过添加现有数据的轻微修改副本,或从现有数据中创建新的合成数据,来扩展数据集。
通过现有数据,可以通过对现有示例进行小的修改/扰动来创建更多的数据。简单的变化,例如图像的翻转或旋转,是一种轻松将数据集中图像数量翻倍或三倍的方式,同时保持所有变体的相同标签。
数据增强是一种提升模型性能的方法,通常也能提高其泛化能力。它添加了新的有效示例,这些示例落在特征空间中现实示例没有覆盖的区域。
请记住,如果你添加无效的示例,就有可能学习到错误的答案,或者至少引入不必要的噪声,因此要小心仅以有效的方式增强数据!例如,考虑图5-5中的图像。
让我们从使用CIFAR-10数据集的一个具体示例开始,CIFAR-10是一个著名且广泛使用的数据集。接下来,我们将继续讨论一些其他的增强技术。
示例:CIFAR-10
CIFAR-10数据集(来自加拿大高级研究所)是一个常用于训练机器学习模型和计算机视觉算法的图像集合。它是机器学习研究中最广泛使用的数据集之一。
CIFAR-10包含60,000张32 × 32像素的彩色图像。数据集包括10个不同的类别,每个类别有6,000张图像。让我们实际看看如何使用CIFAR-10数据集进行数据增强:
def augment(x, height, width, num_channels):
x = tf.image.resize_with_crop_or_pad(x, height + 8, width + 8)
x = tf.image.random_crop(x, [height, width, num_channels])
x = tf.image.random_flip_left_right(x)
return x
这段代码创建了新的有效示例。它首先通过裁剪填充后的图像来达到给定的高度和宽度,并添加8像素的填充。接着,它通过再次裁剪来创建随机平移的图像,然后随机水平翻转图像。
其他增强技术
除了简单的图像处理外,还有一些其他的高级数据增强技术,你可能需要考虑。虽然我们在这里不会详细讨论它们,但以下是一些你可以自行研究的技术:
- 半监督数据增强
- 无监督数据增强(UDA)
- 基于策略的数据增强(例如,使用AutoAugment)
虽然生成有效的图像变体很容易想象并且相对容易实现,但对于其他类型的数据,增强技术和生成的变体类型可能并不那么直观。不同增强技术的适用性通常取决于数据的类型,有时还与所处的领域相关。这是另一个领域,机器学习工程团队的技能和对数据及领域的了解至关重要。
数据增强回顾
数据增强是增加数据集中标注示例数量的好方法。数据增强增加了数据集的大小和样本多样性,从而更好地覆盖特征空间。数据增强可以减少过拟合并提高模型的泛化能力。
预处理时间序列数据:一个示例
数据有很多不同的形状、大小和格式,每种数据的分析、处理和建模方法都不同。常见的数据类型包括图像、视频、文本、音频、时间序列和传感器数据。每种数据的预处理通常是非常专业化的,且内容丰富,足以填满一本书。因此,我们不会讨论所有类型的数据,而是专注于其中的一种:时间序列数据。
时间序列是按时间顺序排列的数据点序列,通常来自事件,其中时间维度表示事件发生的时间。原始数据中的数据点可能是无序的,但你几乎总是希望根据时间对它们进行排序以便建模。从本质上讲,时间序列问题几乎总是关于预测未来的。
预测是困难的,尤其是关于未来的预测。 ——丹麦谚语
时间序列预测正是做这一件事:它试图预测未来。它通过分析过去的数据来实现这一目标。时间序列通常是许多商业应用中非常重要的数据类型和建模方法,例如金融预测、需求预测和其他对业务规划和优化至关重要的预测类型。
例如,要预测某个位置的未来温度,我们可以使用其他气象变量,如大气压力、风向和风速,这些变量之前已经被记录下来。事实上,我们可能会使用类似于由马克斯·普朗克生物地球化学研究所记录的天气时间序列数据集。该数据集包含14个不同的特征,包括气温、大气压力和湿度。这些特征从2003年开始每10分钟记录一次。
让我们更详细地看看这些数据是如何组织和收集的。数据包括14个变量,其中包括与湿度、风速和风向、温度和大气压力相关的测量值。预测目标是温度。采样率是每10分钟记录一次,因此每小时有6个观察值,每天有144个观察值(6 × 24)。时间维度给出了数据的顺序,而顺序对这个数据集很重要,因为每个天气特征在观察值之间变化的信息非常丰富。对于时间序列,顺序几乎总是很重要的。
图5-6显示了一个温度特征随时间变化的图表。你可以看到,这里有一个在特定时间间隔内重复的模式。这种重复的模式称为季节性,但它可以是任何种类的重复模式,不一定与季节相关。这里显然有季节性,这在对该数据进行特征工程时需要考虑。
我们应该考虑进行季节性分解,但为了简化示例,我们在这里不进行季节性分解。相反,我们将重点讨论窗口化和采样,这些方法可以在有或没有季节性分解的情况下使用。季节性分解用于改善数据并关注残差,通常用于异常检测。
窗口化
使用窗口化策略来查看过去数据的依赖关系似乎是一个自然的路径。时间序列数据中的窗口化策略变得非常重要,它们在时间序列和类似类型的序列数据中具有独特性。图5-7中的示例展示了一个窗口化策略,假设你有六小时的历史数据,并希望用它来预测未来一小时的情况。
在图5-8中,偏移大小也是24,因此你可以使用总窗口大小为48,这将是历史数据加上输出偏移。还需要考虑“现在”是何时,并确保你省略与未来相关的数据(即时间旅行)。在这个示例中,如果“现在”是t = 24,我们需要小心不要将t = 25到t = 47的数据包含在训练数据中。我们可以在特征工程中处理,或者通过减少窗口只包含历史数据和标签来实现。如果在训练期间我们将未来的数据包含在特征中,那么在使用模型进行推理时我们将无法使用这些数据,因为未来尚未发生。
采样
设计采样策略也很重要。你已经知道,在我们的示例中,每小时有六个观察值,每10分钟一个观察值。一天将有144个观察值。如果你以过去五天的数据作为输入,并预测未来六小时的情况,那么我们的历史数据大小将是5 × 144,即720个观察值,输出偏移量将是6 × 6,即36,整个时间窗口的大小将是792。图5-9直观地展示了我们所说的总窗口大小、历史数据和偏移量。
由于一个小时内的观察数据变化不大,我们可以每小时采样一个观察值。我们可以选择该小时的第一个观察值作为样本,或者更好的是,我们可以取每小时观察值的中位数。
那么我们的历史数据大小变为5 × 24 × 1,即120,输出偏移量为6,因此总窗口大小变为126。通过在每小时内进行采样或通过取中位数汇总每小时的数据,我们将特征向量的大小从792减少到了126。
这个示例旨在简要介绍时间序列数据。若想深入了解时间序列数据,可以参考TensorFlow文档。
结论
本章提供了标签化和预处理在成功建模中的重要性背景和视角,同时介绍了数据增强作为扩展数据集信息的一种方法的优势。随着生成AI和新型深度学习建模技术的快速发展,标签化、预处理和数据增强的新技术也在不断涌现。虽然本章没有涵盖所有现存的技术,但它应该能够帮助你理解应该采用的不同方法,并思考这些重要领域。请记住,你的模型好坏取决于数据中的信息,任何能够让你的模型更容易从数据中学习的做法,都将有助于构建更好的模型。