1.4 机器学习系统的类型
现有的机器学习系统类型繁多,为便于理解,我们根据以下标准将它们分为大类:
· 它们在训练期间是如何受到监督(监督、无监督、半监督、自我监督等)的。
· 它们是否可以即时增量地学习(在线学习与批量学习)。
· 它们是通过简单地将新数据与已知数据进行比较来工作,还是通过检测训练数据中的模式并建立预测模型来工作,就像科学家所做的那样(基于实例的学习与基于模型的学习)。
这些标准不是唯一的,你可以按照自己喜欢的方式将其任意组合。例如,最先进的垃圾邮件过滤器可以使用深度神经网络模型来在线即时学习,该模型可以使用人类提供的垃圾邮件和非垃圾邮件样例进行训练。这使它成为一个在线的、基于模型的监督学习系统。
让我们更仔细地看看这些标准。
1.4.1 训练监督
根据训练期间得到的监督数量和监督类型,可以将机器学习系统分为以下五个主要类别:监督学习、无监督学习、自监督学习、半监督学习和强化学习。
监督学习
在监督学习中,提供给包含所需解决方案的算法的训练集,称为标签(见图1-5)。
图1-5:用于垃圾邮件分类的已标记训练集(监督学习的示例)
典型的监督学习任务是分类。垃圾邮件过滤器就是一个很好的示例:它用许多电子邮件及其类别(垃圾邮件或非垃圾邮件)来训练,并且它必须学习如何对新电子邮件进行分类。
另一个典型的任务是在给定一组特征(里程、年龄、品牌等)的情况下来预测目标数值,例如汽车的价格。这种任务称为回归(见图1-6)[1]。要训练这个系统,你需要给它许多汽车样例,包括它们的特征和目标(即它们的价格)。
请注意,某些回归模型也可用于分类,反之亦然。例如,逻辑回归通常用于分类,因为它可以输出对应于属于给定类别的概率值(例如,20%的概率是垃圾邮件)。
图1-6:一个回归问题——给定输入特征的情况下预测值(通常有多个输入特征,有时也有多个输出值)
目标(target)和标签(label)这两个词在监督学习中通常被视为同义词,但目标在回归任务中更常见,而标签在分类任务中更常见。此外,特征有时也称为预测变量或属性。这些术语可能指单个样本(例如,“这辆车的里程特征是等于15 000”)或所有样本(例如,“里程特征与价格密切相关”)。
无监督学习
在无监督学习中,正如你可能猜到的那样,训练数据是未标记的(见图1-7)。系统试图在没有老师的情况下进行学习。
图1-7:用于无监督学习的无标签训练集
例如,假设你有大量关于博客访客的数据。你可能想要运行聚类算法来检测相似访客的分组(见图1-8)。你不会告诉算法访客属于哪个组:它无须你的帮助即可找到这种关联。例如,它可能会注意到40%的访客是喜欢漫画书的青少年,通常在放学后阅读你的博客,而20%的访客是喜欢科幻小说的成年人,并通常在周末访问。如果你使用层次聚类算法,它还可以将每个组细分为更小的组。这可以帮助你针对不同的组来发布博客内容。
图1-8:聚类
可视化算法也是无监督学习的一个好示例:你提供大量复杂且未标记的数据,算法轻松绘制输出2D或3D的数据表示(见图1-9)。这些算法试图尽可能多地保留结构(例如,试图防止输入空间中的单独集群在可视化中重叠),以便于你可以了解数据的组织方式,并可能识别出一些未知的模式。
图1-9:突出显示语义集群的t-SNE可视化示例[2]
与之相关的一个任务是降维,其目标是在不丢失太多信息的情况下简化数据。一种方法是将几个相关的特征合并为一个。例如,一辆汽车的行驶里程可能与其车龄有很强的相关性,因此降维算法会将它们合并为一个代表汽车磨损的特征。这称为特征提取。
在将训练数据提供给另一个机器学习算法(例如监督学习算法)之前,先使用降维算法减少训练数据的维度通常是个好主意。算法会运行得更快,数据会占用更少的磁盘和内存空间,并且在某些情况下,它还可能表现得更好。
另一个重要的无监督任务是异常检测,例如,检测异常的信用卡交易来防止欺诈、发现制造缺陷,或者在将数据集提供给另一个学习算法之前自动从数据集中删除异常值。系统在训练期间主要使用正常实例,因此它会学习识别它们。然后,当看到一个新实例时,系统可以判断这个新实例看起来是正常的还是异常的(见图1-10)。一个非常类似的任务是新颖性检测,它旨在检测看起来与训练集中所有实例不同的新实例。这需要有一个非常“干净”的训练集,没有任何你希望算法能够检测到的实例。例如,如果你有几千张狗的照片,其中1%代表吉娃娃犬,那么新颖性检测算法不应将吉娃娃犬的新图片视为新颖。另外,异常检测算法可能认为这些狗非常稀有并且与其他狗如此不同,以至于可能会将它们归类为异常(没有对吉娃娃犬不敬的意思)。
图1-10:异常检测
最后,还有一个常见的无监督任务是关联规则学习,其目标是挖掘大量数据并发现属性之间有趣的关系。例如,假设你开了一家超市,在销售日志上运行关联规则可能会发现购买烧烤酱和薯片的人也倾向于购买牛排。因此,你可能希望将这几样商品摆放得更近一些。
半监督学习
由于标记数据通常既耗时又昂贵,因此你通常会有很多未标记的实例而很少有已标记的实例。一些算法可以处理一部分已标记的数据。这称为半监督学习(见图1-11)。
图1-11:具有两个类别(三角形和正方形)的半监督学习——未标记的样例(圆形)有助于将新实例(十字)分类到三角形而不是正方形,即使它更接近标记的正方形
一些照片托管服务(例如Google相册)就是很好的示例。一旦你将所有的家庭照片上传到该服务,它会自动识别出同一个人A出现在照片1、5和11中,而另一个人B出现在照片2、5和7中。这是算法(聚类)的无监督部分。现在系统只需要你告诉它这些人是谁。你只需为每个人添加一个标签[3],系统就可以为每张照片中的每个人命名,这对于搜索照片非常有用。
大多数半监督学习算法是无监督和监督算法的组合。例如,可以使用聚类算法将相似的实例分组在一起,然后每个未标记的实例都可以用其集群中最常见的标签进行标记。一旦标记了整个数据集,就可以使用任何监督学习算法。
自监督学习
机器学习的另一种方法可以是从完全未标记的数据集生成完全标记的数据集。同样,一旦标记了整个数据集,就可以使用任何监督学习算法。这种方法称为自监督学习。
例如,如果你有一个很大的未标记图像数据集,你可以随机屏蔽每个图像的一小部分,然后训练一个模型来恢复出原始图像(见图1-12)。在训练期间,屏蔽的图像用作模型的输入,原始图像用作标签。
生成的模型本身可能非常有用。例如,修复损坏的图像或从图片中删除不想要的对象。但通常情况下,使用自监督学习训练的模型并不是你的最终目标。你通常需要针对稍微不同的任务(你真正关心的任务)来调整和微调模型。
图1-12:自监督学习示例——输入(左)和目标(右)
例如,假设你真正想要的是一个宠物分类模型:给定一张宠物的照片,模型会告诉你这只宠物属于什么物种。如果你有大量未标记的宠物照片数据集,则可以先使用自监督学习来训练一个图像修复模型。如果模型表现良好,则它应该能够区分不同的宠物种类:当它修复一张蒙着脸的猫的图像时,它必须知道不要添加狗的脸。假设你的模型架构允许(大多数神经网络架构都允许),那么你就可以调整模型,使它能预测宠物种类而不是修复图像。最后一步是在已标记的数据集上微调模型:模型已经知道猫、狗和其他宠物的样子,因此只需要这个步骤,模型就可以学习它已知的物种和我们期望从中得到的标签之间的映射。
将知识从一项任务转移到另一项任务称为迁移学习,它是当今机器学习中最重要的技术之一,尤其是在使用深度神经网络(即由多层神经元组成的神经网络)时。我们将在第二部分详细讨论这一点。
有些人认为自监督学习是无监督学习的一部分,因为它处理的是未标记的数据集。但是 自监督学习在训练期间是使用(生成的)标签的,因此在这方面它更接近于监督学习。在处理聚类、降维或异常检测等任务时,通常会使用术语“无监督学习”,而自监督学习侧重于与监督学习相同的任务,主要是分类和回归。简而言之,最好将自监督学习视为一个单独的类别。
强化学习
强化学习是一种非常不同的“巨兽”。这个学习系统(在此上下文中称为智能体)可以观察环境,选择和执行动作,并获得回报(或负回报形式的惩罚,见图1-13)。然后它必须自行学习什么是最好的方法,称为策略,以便随着时间的推移获得最大的回报。策略定义了智能体在给定情况下应该选择的动作。
图1-13:强化学习
例如,许多机器人采用强化学习算法来学习如何走路。DeepMind的AlphaGo程序也是强化学习的一个很好的示例:它在2017年5月的围棋比赛中打败了当时世界排名第一的柯洁,成为头条新闻。它通过分析数百万场比赛,然后与自己进行多次对弈,从而习得了获胜策略。请注意,在与人类冠军的比赛中学习过程是被关闭的,AlphaGo只是在应用它学到的策略。正如你将在1.4.2节中看到的,这称为离线学习。
1.4.2 批量学习与在线学习
对机器学习系统进行分类的另一个标准是系统能否从输入数据流中进行增量学习。
批量学习
在批量学习中,系统无法进行增量学习:它必须使用所有可用的数据进行训练。这通常会占用大量的时间和计算资源,因此通常需要离线完成。首先对系统进行训练,然后将其投入生产环境运行,就不再学习了。它只是应用它学到的东西。这称为离线学习。
不幸的是,模型的性能往往会随着时间的推移而慢慢变差,因为世界在不断演进发展,而模型却保持不变。这种现象通常称为模型腐烂或数据漂移。解决方案是定期根据最新的数据重新训练模型。你需要多久做一次取决于用例:如果模型对猫和狗的图片进行分类,它的性能会衰减得很慢,但如果模型处理快速变化的系统,例如对金融市场进行预测,那么它很可能会衰减得相当快。
即使是经过训练可以对猫和狗的图片进行分类的模型也可能需要定期重新训练,这不是因为猫和狗会在一夜之间发生变化,而是因为相机会不断变化,图像格式、清晰度、亮度和大小比例也在不断变化。此外,明年人们可能会喜欢不同的品种,或者他们可能会给宠物戴上小帽子,谁知道呢?
如果你想让批量学习系统理解新数据(比如新型垃圾邮件),你需要在完整数据集(不仅是新数据,还有旧数据)上从头开始训练新版系统,然后用新模型替换旧模型。幸运的是,训练、评估和启动机器学习系统的整个过程可以相当容易地自动化(见图1-3),因此即使是批量学习系统也可以适应变化。只需要经常更新数据并从头开始训练新版系统。
这个解决方案很简单,而且通常效果很好,但使用完整数据集进行训练可能需要花费很多小时,因此通常每24小时甚至每周训练一次新系统。如果你的系统需要适应快速变化的数据(例如,预测股票价格),那么你需要一个更具反应性的解决方案。
此外,在完整的数据集上进行训练需要大量的计算资源(CPU、内存空间、磁盘空间、磁盘I/O、网络I/O等)。如果你有大量的数据,并且你让系统每天从头开始训练,那么最终会花费你很多钱。如果数据量巨大,那么甚至可能无法使用批量学习算法。
最后,如果系统需要能够自动学习并且它的资源有限(例如,智能手机应用程序或火星上的漫游机器人),那么携带大量训练数据并占用大量资源来每天训练数小时是不太可能的。
在这些情况下,更好的选择是使用能够增量学习的算法。
在线学习
在在线学习中,通过以单独的数据或小批量的小组数据方式循序地向系统提供数据实例来对系统进行增量训练。每个学习步骤都既快速又便宜,因此系统可以即时学习新数据(见图1-14)。
图1-14:在在线学习中,模型经过训练并投入生产环境,然后随着新数据的出现不断学习
在线学习对于需要快速适应变化的系统(例如,检测股票市场中的新模式)很有用。如果你的计算资源有限,例如,模型是在移动设备上训练的,那么在线学习是一个不错的选择。
此外,对于超大数据集——超出一台计算机的主存储器所能容纳的数据,在线学习算法也同样适用[这称为核外(out-of-core)学习]。该算法加载部分数据,在该数据上运行一个训练步骤,然后重复该过程,直到它在所有数据上运行完(见图1-15)。
图1-15:使用在线学习来处理庞大的数据集
在线学习系统的一个重要参数是它们适应不断变化的数据的速度:这称为学习率。如果设置的学习率很高,那么系统会快速适应新数据,但它也会很快忘记旧数据(并且你也不希望垃圾邮件过滤器只标记最新类型的垃圾邮件)。反之,如果设置的学习率很低,那么系统会有更多的惰性,也就是说,它会学习得更慢,但它对新数据中的噪声或非典型数据点(异常值)序列的敏感度也会降低。
核外学习通常是离线(即不在实时系统上)完成的,因此在线学习可能是一个容易混淆的名字。将其视为增量学习会更合适。
在线学习的一大挑战是,如果将不良数据输入系统,系统的性能可能会迅速下降(取决于数据的质量和学习率)。如果它是实时系统,那么你的客户会注意到这个现象。不良数据的来源可能是机器人的传感器故障,或者有人对搜索引擎恶意刷屏以提高搜索结果排名等。为降低这种风险,你需要密切监控系统,并在检测到性能下降时立即关闭学习(并尽量恢复到之前的工作状态)。你可能还想监控输入数据并对异常数据做出反应。例如,使用异常检测算法(见第9章)。
1.4.3 基于实例的学习与基于模型的学习
对机器学习系统进行分类的另一种方法是根据它们的泛化方式。大多数机器学习任务都与做出预测有关。这意味着在给定大量训练样例的情况下,系统需要能够对它以前未见到过的样例做出良好的预测(泛化)。在训练数据上有很好的性能是好的,但还不够,真正的目标是在新实例上表现良好。
泛化方法主要有两种:基于实例的学习和基于模型的学习。
基于实例的学习
最司空见惯的学习方式可能就是简单地背诵。如果你以这种方式来创建垃圾邮件过滤器,那么它只会标记所有与用户已标记的电子邮件相同的电子邮件——这虽然不是最坏的解决方案,但肯定不是最好的。
垃圾邮件过滤器不仅可以标记与已知垃圾邮件相同的电子邮件,还可以对其进行编程来标 记与已知垃圾邮件非常相似的电子邮件。这需要衡量两封电子邮件之间的相似性。两封电子邮件之间的(非常基本的)相似性度量可以是计算它们共有的单词数。如果一封电子邮件与已知的垃圾邮件有很多相同单词,那么系统会将其标记为垃圾邮件。
这称为基于实例的学习:系统用心学习样例,然后通过使用相似性度量将它们与学习到的样例(或它们的子集)进行比较来泛化到新实例。例如,在图1-16中,新实例被归类为三角形,因为大多数最相似的实例都属于该类。
图1-16:基于实例的学习
基于模型的学习和典型的机器学习工作流程
对一组样例进行泛化的另一种方法是为这些样例构建一个模型,然后使用该模型进行预测。这称为基于模型的学习(见图1-17)。
图1-17:基于模型的学习
例如,假设你想知道金钱是否能让人感到快乐,你可以从经合组织(OECD)网站(https://www.oecdbetterlifeindex.org)下载生活幸福指数数据,再从世界银行(https://ourworldindata.org)找到人均GDP(Gross Domestic Product)的统计数据,将数据并入表格并按人均GDP排序。表1-1展示了你得到的内容的摘录。
表1-1:金钱能让人更快乐吗
让我们绘制这些国家的数据(见图1-18)。
图1-18:你看到这里的趋势了吗
这里似乎确实有一种趋势!尽管数据有噪声(即部分随机),但看起来生活满意度随着国家人均GDP的增长或多或少呈线性增长。因此,你决定将生活满意度建模为人均GDP的线性函数。这个步骤称为模型选择:你选择了一个只有一个属性(即人均GDP)的生活满意度线性模型(见公式1-1)。
公式1-1:一个简单的线性模型
生活满意度=θ0+θ1×人均GDP
该模型有两个模型参数:θ0和θ1[4]。通过调整这些参数,你可以用这个模型表示任何线性函数,如图1-19所示。
图1-19:一些可能的线性模型
在使用模型之前,你需要定义参数值θ0和θ1。你如何知道哪些值会使你的模型表现最好?要回答这个问题,你需要指定一个性能指标。你可以定义一个效用函数(或拟合函数)来衡量模型有多好,也可以定义一个代价函数来衡量模型有多差。对于线性回归问题,人们通常使用代价函数来衡量线性模型的预测与训练样例之间的差距,目的在于最小化这个差距。
这就是线性回归算法的用武之地:通过你提供的训练样例,找到使线性模型最拟合你的数据的参数。这称为训练模型。在我们的示例中,算法发现最佳参数值为θ0=3.75和θ1=6.78×10-5。
令人困惑的是,“模型”一词可以指代模型的一种类型(例如,线性回归),也可以指代完全特定的模型架构(例如,有一个输入和一个输出的线性回归),或者指代最后准备用于预测的已训练模型(例如,有一个输入和一个输出的线性回归,参数为θ0=3.75和θ1=6.78×10-5)。模型选择包括选择模型类型和完全指定其架构。训练模型意味着运行算法来找到最拟合训练数据的模型参数,并希望对新数据做出良好的预测。
现在(对于线性模型而言)模型最拟合训练数据,如图1-20所示。
图1-20:最拟合训练数据的线性模型
现在终于可以运行模型进行预测了。例如,假设你想知道塞浦路斯人有多幸福,而经合组织的数据没有答案。幸运的是,你可以使用这个模型做出很好的预测:先查看塞浦路斯的人均GDP是多少,发现是37 655美元,然后应用这个模型,发现生活满意度大约为3.75+37 655×6.78×10-5=6.30。
为了激发你的兴趣,示例1-1展示了加载数据的Python代码,将输入X与标签y分开,创建可视化散点图,然后训练线性模型并进行预测[5]。
示例1-1:使用Scikit-Learn训练并运行一个线性模型
如果你改用基于实例的学习算法,你会发现以色列的人均GDP最接近塞浦路斯(38 341美元),并且由于经合组织数据告诉我们以色列人的生活满意度为7.2,你会预测塞浦路斯的生活满意度为7.2。如果你稍微拉远一些,看看距离很近的两个国家,你会发现立陶宛和斯洛文尼亚这两个国家的生活满意度都是5.9。对这三个值求平均值,得到6.33,这非常接近基于模型的预测。这个简单的算法称为k近邻回归(在本例中,k=3)。
在上述代码中,用k近邻回归替换线性回归模型非常简单,只需将如下代码:
替换为:
如果一切顺利,你的模型会做出很好的预测。如果不是,那么你可能需要使用更多的属性(就业率、健康、空气污染等),获得更多或更高质量的训练数据,或者选择更强大的模型(例如,多项式回归模型)。
总之:
· 研究数据。
· 选择一个模型。
· 使用训练数据进行训练(即学习算法搜索最小化代价函数的模型参数值)。
· 最后,应用该模型对新实例进行预测(这称为推断),希望该模型能够被很好地泛化。
这就是一个典型的机器学习项目。在第2章中,你将通过从头到尾完成一个项目来亲身体验这一点。
到目前为止,我们已经介绍了很多基础知识:你现在知道了机器学习的真正含义,它为什么有用,一些最常见的ML系统类别是什么,以及典型的项目工作流是什么样的。现在让我们看看在学习过程中会遇到哪些妨碍你做出准确预测的问题。