导读:现有的机器学习系统种类繁多,根据以下内容将它们进行分类有助于我们理解:
- 是否在人类监督下训练(监督式学习、无监督式学习、半监督式学习和强化学习)
- 是否可以动态地进行增量学习(在线学习和批量学习)
- 是简单地将新的数据点和已知的数据点进行匹配,还是像科学家那样,对训练数据进行模式检测,然后建立一个预测模型(基于实例的学习和基于模型的学习)
这些标准之间互相并不排斥,你可以以你喜欢的方式将其任意组合。例如,现在最先进的垃圾邮件过滤器可能是使用深度神经网络模型对垃圾邮件和常规邮件进行训练,完成动态学习。这使其成为一个在线的、基于模型的、监督式学习系统。
作者:奥雷利安·杰龙(Aurélien Géron)
本文摘编自《机器学习实战:基于Scikit-Learn和TensorFlow》,如需转载请联系我们
我们来看看这几个标准。
01 监督式/无监督式学习
根据训练期间接受的监督数量和监督类型,可以将机器学习系统分为以下四个主要类别:监督式学习、无监督式学习、半监督式学习和强化学习。
1. 监督式学习
在监督式学习中,提供给算法的包含所需解决方案的训练数据,称之为标签或标记(图1-5)。
▲图1-5:监督式学习中被标记的训练集(例如,垃圾邮件分类)
分类任务是一个典型的监督式学习任务。垃圾邮件过滤器就是个很好的例子:通过大量的电子邮件示例及其所属的类别(垃圾邮件或是常规邮件)进行训练,然后学习如何对新邮件进行分类。
还有典型的任务,是通过预测变量——也就是一组给定的特征(里程、使用年限、品牌等)——来预测一个目标数值,例如汽车的价格。这种类型的任务被称为回归任务(图1-6)。要训练这样一个系统,你需要提供大量的汽车示例,包括它们的预测变量和它们的标签(也就是它们的价格)。
在机器学习里,属性是一种数据类型(例如“里程”);而特征取决于上下文,可能有多个含义,但是通常状况下,特征意味着一个属性加上其值(例如,“里程=15,000”)。尽管如此,许多人还是会交替使用属性和特征这两个名词。
▲图1-6:回归任务
值得注意的是,一些回归算法也可以用于分类任务,反之亦然。例如,逻辑回归就被广泛地用于分类,因为它可以输出“属于某个给定类别的概率”的值(例如,20%的机率是垃圾邮件)。
这里是一些最重要的监督式学习的算法:
- K-近临算法(k-Nearest Neighbors)
- 线性回归(Linear Regression)
- 逻辑回归(Logistic Regression)
- 支持向量机(Support Vector Machines,简称SVMs)
- 决策树和随机森林(Decision Trees and Random Forests)
- 神经网络(Neural networks)
2. 无监督式学习
无监督式学习,顾名思义,你可能已经猜到,训练数据都是未经标记的(图1-7)。系统会在没有老师的情况下进行学习。
▲图1-7:无监督式学习的未标记训练集
这里有一些最重要的无监督式学习的算法:
聚类算法
- k-平均算法(k-Means)
- 系统聚类分析(Hierarchical Cluster Analysis,简称HCA)
- 最大期望算法(Expectation Maximization)
可视化和降维
- 主成分分析(PCA)
- 核主成分分析(Kernel PCA)
- 局部线性嵌入(LLE)
- t-分布随机近临嵌入(t-SNE)
关联规则学习
- Apriori
- Eclat
例如,假设你现在拥有大量的自己博客访客的数据。你想通过一个聚类算法来检测相似访客的分组(图1-8)。你不大可能告诉这个算法每个访客属于哪个分组——而是要它自己去寻找这种关联,无需你的帮助。
比如说,它可能会注意到40%的访客是喜欢漫画的男性,并且通常是在夜晚阅读你的博客,20%的访客是年轻的科幻爱好者,通常是在周末访问,等等。如果你使用的是层次聚类的算法,它还可以将每组细分为更小的组。这可能有助于你针对不同的分组来发布博客内容。
▲图1-8:聚类
可视化算法也是无监督式学习算法的好例子:你提供大量复杂的、未标记的数据,得到轻松绘制而成的2D或3D的数据呈现作为输出(图1-9)。这些算法会尽其所能地保留尽量多的结构(譬如,尝试保持让输入的单独集群在可视化中不会被重叠),以便于你理解这些数据是怎么组织的,甚至识别出一些未知的模式。
▲图1-9:一个使用t-SNE算法的可视化示例,突显了各种语义丛
与之相关的另一种任务是降维,降维的目的是在不丢失太多信息的前提下简化数据。方法之一是将多个相关特征合并为一个。例如,汽车的里程与其使用年限存在很大的相关性,所以降维算法会将它们合并成一个代表汽车磨损的特征。这个过程被称之为特称提取。
通常比较好的做法是,先使用降维算法减少训练数据的维度,再将其提供给另一个机器学习算法(例如监督式学习算法)。这会使它运行得更快,数据占用的磁盘空间和内存都会更小,在某些情况下,执行性能也会更好。
另一个很重要的无监督式任务是异常检测——例如,检测异常信用卡交易从而防止欺诈,捕捉制造缺陷,或者是在提供数据给一种机器学习算法之前,自动从数据集中移除异常值。系统用正常实例进行训练,然后当它看到新的实例时,它就可以判断出这个新实例看上去是正常还是异常(见图1-10)。
▲图1-10:异常检测
最后,还有一个常见的无监督式任务是关联规则学习,其目的是挖掘大量数据,发现属性之间的有趣联系。比如说,假设你开了一家超市,在销售日志上运行关联规则之后发现买烧烤酱和薯片的人,也倾向于购买牛排。那么,你可能会将这几样商品摆放得更为靠近一些。
3. 半监督式学习
有些算法可以处理部分标记的训练数据——通常是大量未标记数据和少量的标记数据。这被称为半监督式学习(图1-11)。
有些照片托管服务(例如 Google 相册)就是很好的例子。一旦你将所有的家庭照片上传到服务后,它会自动识别出人物A出现在照片1、5和11中,另一个人B出现在照片2、5和7中。这是算法中无监督的部分(聚类)。现在系统需要你做的只是,告诉它这些人都是谁。给每个人一个标签之后,它就可以给每张照片中的每个人命名,这对于搜索图片非常重要。
▲图1-11:半监督式学习
大多数半监督式学习算法是无监督和监督式算法的结合。例如深度信念网络(DBNs),它基于一种互相堆叠的无监督式组件,这个组件叫做受限玻尔兹曼机(RBMs)。受限玻尔兹曼机以无监督的方式进行训练,然后使用监督式学习对整个系统进行微调。
4. 强化学习
强化学习则是一个非常与众不同的巨兽。它的学习系统(在其语境中被称为智能体)能够观察环境,做出选择,执行操作,并获得回报(rewards),或者是以负面回报的形式获得惩罚,见图1-12。所以它必须自行学习什么是最好的策略 (policy),从而随着时间推移获得最大的回报。策略代表智能体在特定情况下应该选择的操作。
▲图1-12:强化学习
例如,许多机器人通过强化学习算法来学习如何行走。DeepMind的AlphaGo项目也是一个强化学习的好例子——2016年3月,AlphaGo在围棋比赛中击败世界冠军李世乭而声名鹊起。通过分析数百万场比赛,然后自己跟自己下棋,它学到了它的制胜策略。要注意,在跟世界冠军对弈的时候,AlphaGo处于关闭学习状态下,它只是应用它所学到的策略而已。
02 批量学习和在线学习
还有一个给机器学习系统分类的标准,是看系统是否可以从传入的数据流中进行增量学习。
1. 批量学习
批量学习中,系统无法进行增量学习——即必须使用所有可用数据进行训练。这需要大量时间和计算资源,所以通常情形下,都是离线完成的。离线学习就是先训练系统,然后将其投入生产环境,这时学习过程停止,它只是将其所学到的应用出来。
如果你希望批量学习系统学习新数据(例如新型垃圾邮件),你需要在完整数据集(不仅仅是新数据,还要包括旧数据)的基础上重新训练一个新版本的系统,然后停用旧系统,用新系统取而代之。
幸运的是,整个训练、评估和启动机器学习系统的过程可以很轻易地实现自动化(如图1-13所示),所以即使是批量学习系统也能够适应变化。只是需要不断地更新数据,以及根据需要,频繁地训练新版本的系统。
▲图1-13:在线学习
这个解决方法比较简单,通常情况下也都能正常工作,只是每次都使用全套数据集进行训练可能需要花上好几个小时,所以,你很有可能会选择每天甚至每周训练一次新系统。如果你的系统需要应对快速变化的数据(例如,预测股票价格),那么你需要一个更具响应力的解决方案。
此外,使用完整数据训练需要耗费大量的计算资源(CPU、内存空间、磁盘空间、磁盘I/O、网络I/O等等)。如果你的数据量非常大,并且每天自动执行重新训练系统,那最终你将为此花费大量的金钱。而假如数据量更海量一些,你甚至可能无法再应用批量学习算法。
所以如果你的资源有限(例如,智能手机应用程序或者是火星上的漫游器),而系统需要实现自主学习,那么像这样携带大量训练数据,占用大量资源,动辄每天耗费几小时来进行训练的方式,肯定是心有余而力不足。
幸运的是,在所有这些情况下,我们有了一个更好的选择——也就是能够进行增量学习的算法。
2. 在线学习
在在线学习中,你可以循序渐进地给系统提供训练数据,逐步积累学习成果。这种提供数据的方式可以是单独地,也可以采用小批量(mini-batches)的小组数据来进行训练。每一步学习都很快速并且便宜,所以系统就可以根据飞速写入的最新数据进行学习(见图1-13)。
对于这类系统——需要接收持续的数据流(例如股票价格)同时对数据流的变化做出快速或自主的反应,使用在线学习系统是一个非常好的方式。如果你的计算资源有限,它同样也是一个很好的选择:新的数据实例一旦经过系统的学习,就不再需要,你可以将其丢弃(除非你想要回滚到前一个状态,再“重新学习”数据),这可以节省大量的空间。
对于超大数据集——超出一台计算机的主存储器的数据,在线学习算法也同样适用(这被称为out-of-core核外学习)。算法每次只加载部分数据,并针对这部分数据进行训练,然后不断重复这个过程,直到完成所有数据的训练(见图1-14)。
▲图1-14:使用在线学习处理超大数据集
整个过程通常是离线完成的(也就是不在live系统上),因此在线学习这个名字很容易让人产生误解。可以将其视为增量学习。
在线学习系统的一个重要参数,是看它能够多快适应不断变化的数据,这就是所谓的学习率。如果设置的学习率很高,那么系统将会迅速适应新数据,但同时也很快忘记旧数据(你肯定不会希望垃圾邮件过滤器只对最新显示的邮件进行标记)。
反过来,如果学习率很低,系统会有更高的惰性,也就是说,它学习会更缓慢,同时也会对新数据中的噪声或者非典型数据点的序列更不敏感。
在线学习面临的一个重大挑战是,如果给系统输入不良数据,系统的性能将会逐渐下降。现在某些实时系统的客户,说不定已经注意到了这个现象。不良数据的来源可能是,例如,机器上发生故障的传感器,或者是有人对搜索引擎恶意刷屏以提高搜索结果排名等等。
为了降低这种风险,你需要密切监控你的系统,一旦检测到性能下降,要及时中断学习(可能还需要恢复到之前的工作状态)。当然,你同时还需要监控数据输入,并对异常数据做出响应(例如,使用异常检测算法)。
03 基于实例与基于模型的学习
另一种对机器学习系统进行分类的方法是看它们如何泛化。大多数机器学习任务是要做出预测。这意味着,系统需要通过给定的训练示例,在它此前并未见过的示例上进行泛化。在训练数据上实现良好的性能指标固然重要,但是还不够充分;真正的目的是要在新的对象实例上表现出色。
泛化的主要方法有两种:基于实例的学习和基于模型的学习。
1. 基于实例的学习
我们最司空见惯的学习方法就是简单的死记硬背。如果你以这种方式创建一个垃圾邮件过滤器,那它可能只会标记那些跟已被用户标记为垃圾邮件完全相同的邮件——这虽然不是最差的解决方案,但肯定也不是最好的。
除了完全相同的,你还可以通过编程让系统标记与已知的垃圾邮件非常相似的邮件。这里需要两封邮件之间的相似度度量。有一种(基本的)相似度度量方式,是计算它们之间相同的单词数目。如果一封新邮件与一封已知的垃圾邮件有许多字句相同,系统就可以将其标记为垃圾邮件。
这便是基于实例的学习:系统先完全记住学习示例(examples),然后通过某种相似度度量方式将其泛化到新的实例(图1-15)。
▲图1-15:基于实例的学习
2. 基于模型的学习
从一组示例集中实现泛化的另一种方法,是构建这些示例的模型,然后使用该模型进行预测。这就是基于模型的学习(图1-16)。
▲图1-16:基于模型的学习
举例来说,假设你想知道金钱是否让人感到快乐,你可以从经合组织(OECD)的网站上下载“幸福指数”的数据,再从国际货币基金组织(IMF)的网站上找到人均GDP的统计数据,将数据并入表格,按照人均GDP排序,你会得到如表1-1显示的摘要。
国家 | 人均GDP | 生活满意度 |
---|---|---|
匈牙利 | 12 240 | 4.9 |
韩国 | 27 195 | 5.8 |
法国 | 37 675 | 6.5 |
澳大利亚 | 50 962 | 7.3 |
美国 | 55 805 | 7.2 |
▲表1-1:金钱是否让人感到快乐?
让我们随机绘制几个国家的数据(图1-17)。
▲图1-17:看出趋势了么?
这里似乎有一个趋势!虽然数据包含噪声(即部分随机),但是仍然可以看出随着国内生产总值的增加,生活满意度或多或少呈现线性上升的趋势。所以你可以把生活满意度建模成一个关于人均GDP的线性函数。这个过程称之为模型选择:你为生活满意度选择了一个线性模型,该模型只有一个属性,就是人均GDP(见以下公式)。
- 生活满意度=θ0 θ1×人均GDP
这个模型有两个参数,θ0和θ1。通过调整这两个参数,你可以用这个模型来代表任意线性函数,如图1-18所示。
▲图1-18:可能的线性模型
在使用模型之前,需要先定义参数θ0和 θ1的值。怎么才能知道什么值可以使得模型表现最佳呢?要回答这个问题,需要先确定怎么衡量模型的性能表现。要么定义一个效用函数(或适应度函数)来衡量模型有多好,要么定义一个成本函数来衡量模型有多差。
对于线性回归问题,通常的选择是使用成本函数来衡量线性模型的预测与训练实例之间的差距,目的在于尽量使这个差距最小化。
这正是线性回归算法的意义所在:通过你提供的训练样本,找出最符合所提供数据的线性模型的参数,这就是训练模型的过程。在我们这个案例中,算法找到的最优参数值为θ0 = 4.85,θ1 = 4.91× 10-5
现在,模型基本接近训练数据(对于线性模型而言),如图1-19所示。
▲图1-19:对训练数据拟合最佳的线性模型
现在终于可以运用模型来进行预测了。例如,你想知道塞浦路斯的人民有多幸福,但是经合组织的数据没有提供答案。幸好你有这个模型可以做出预测:先查查塞浦路斯的人均GDP是多少,22,587美元,然后应用到模型中,发现生活满意度可能在4.85 22587 × 4.91 × 10-5 = 5.96。
为了激发你的兴趣,下面的示例是一段加载数据的Python代码,包括准备数据,创建一个可视化的散点图,然后训练线性模型并作出预测。
示例:使用Scikit-Learn训练并运行一个线性模型
import
matplotlib
import
matplotlib.pyplot as plt
import
numpy as np
import
pandas as pd
import
sklearn
#
Load the data
oecd_bli =
pd.read_csv("oecd_bli_2015.csv", thousands=',')
gdp_per_capita =
pd.read_csv("gdp_per_capita.csv",thousands=',',delimiter='t',
encoding='latin1', na_values="n/a")
#
Prepare the data
country_stats =
prepare_country_stats(oecd_bli, gdp_per_capita)
X =
np.c_[country_stats["GDP per capita"]]
y =
np.c_[country_stats["Life satisfaction"]]
#
Visualize the data
country_stats.plot(kind='scatter', x="GDP per capita", y='Life satisfaction')
plt.show()
#
Select a linear model
lin_reg_model =
sklearn.linear_model.LinearRegression()
#
Train the model
lin_reg_model.fit(X, y)
#
Make a prediction for
Cyprus
X_new =
[[22587]] #
Cyprus' GDP per capita
print(lin_reg_model.predict(X_new)) #
outputs [[ 5.96242338]]
如果使用基于实例的学习算法,那么你会发现斯洛文尼亚的人均GDP最接近塞浦路斯(20,732美元),而经合组织的数据告诉我们,斯洛文尼亚人民的生活满意度是5.7,因此你很可能会预测塞浦路斯的生活满意度为5.7。
如果稍微拉远一些,看看两个与之最接近的国家——葡萄牙和西班牙的生活满意度分别为5.1和6.5。取这三个数值的平均值,得到5.77,这也非常接近你基于模型预测所得的值。这个简单的算法被称为k-近临回归算法(在本例中,k = 3)。
要将前面代码中的线性回归模型替换为k-近临回归模型非常简单,只需要将下面这行代码:
clf =
sklearn.linear_model.LinearRegression()
替换为:
clf =
sklearn.neighbors.KNeighborsRegressor(n_neighbors=3)
如果一切顺利,你的模型将能做出很棒的预测。如果不行,你可能需要使用更多的属性(例如就业率、健康、空气污染等等),或者是获得更多或更高质量的训练数据,再或者是选择一个更强大的模型(例如,多项式回归模型)。
简而言之:
- 学习数据。
- 选择模型。
- 使用训练数据进行训练(即前面学习算法搜索模型参数值,从而使成本函数最小化的过程)。
- 最后,应用模型对新示例进行预测(这称之为推断),祈祷模型的泛化结果不错。
以上就是一个典型的机器学习项目。到目前为止,我们已经介绍了多个领域,你已经知道了机器学习系统最常见的类别有哪些,以及典型的项目工作流程。
关于作者:奥雷利安·杰龙(Aurélien Géron)是机器学习方面的顾问。他曾是Google软件工程师,在2013年到2016年主导了YouTube视频分类工程。2002年和2012年,他还是Wifirst公司(一家法国的无线ISP)的创始人和首席技术官,2001年是Ployconseil公司(现在管理电动汽车共享服务Autolib)的创始人和首席技术官。
本文摘编自《机器学习实战:基于Scikit-Learn和TensorFlow》,经出版方授权发布。