关键点
- 真实世界中的机器学习并不是简单地训练一次模型就完了。获得训练数据通常都是很复杂的事,而且即使在第一次部署之后,也还是需要持续的监控和再训练。
- 为了获得训练数据,通常需要有一大群人,需要许多人力去为数据打标签、加注解。但这又带来了质量控制问题,你可能需要统计监测来发现问题。
- 模型选择和特征选取都非常重要,但又常常受限于你可获得得的数据量。即使一个模型或特征现在是无效的,但当你能得到更多数据之后,它们可能就变得有效了。
- 你的用户和产品都会改变,而你的机器学习模型的表现也会随着它们的改变而变化。你要重新收集训练数据,重新评估你选取的算法和特征,再重新训练模型,所以请尽量把这些步骤自动化。
机器学习技术已经催生了许多我们现在每天都会使用到的产品,从 Apple 的 Siri 和 Google 的 Now 之类的智能助手,到亚马逊的推荐大家购买新产品的推荐引擎,再到谷歌和 Facebook 用的广告排名系统,等等。最近,由于深度学习的一系列成就,机器学习开始为大众所知,这些成就包括 AlphaGo 击败了围棋大师 Lee Sedol,以及与图像识别和机器翻译有关的许多引人注目的新产品。
在这个系列的文章中,我们将介绍机器学习领域的一些强大而又普遍适用的技术,其中包括深度学习,还有许多可以满足各种现代业务需求的传统方法。在读过这个系列的文章之后,你就应该具备了必要的知识,可以开始着手在你自己的领域内进行各种具体的机器学习实验了。
这篇 InfoQ 文章是“机器学习技术介绍”系列文章中的一篇。你可以通过 RSS 订阅它们。
这个系列之前的文章关注的是机器学习的算法部分:训练简单的分类器、分类过程中的陷阱、以及神经网络基础等。但在使用一个模型去解决一个真实世界中的问题时,机器学习的算法部分只是整个流程中的一小部分。
在这篇文章中,我们会讨论开发机器学习模型的端到端的流程:从哪里获得训练数据、如何选择机器学习算法、在模型部署上线之后还要跟进解决什么问题……等等。
端到端的模型部署
在使用标准的日志数据时会有许多机器学习分类问题,尤其是有时候你得到的标签也是免费的。比如,人们通常用用户点击广告的数据来训练广告点击预测模型,而视频推荐系统则在很大程度上要依赖你之前看过的视频,等等。
可是,当这些系统达到一定的规模和复杂度时,再仅仅依靠简单的点击数据是远远不够的。比如,因为他们过于偏重点击数据,那要调节系统去为用户显示新的广告和新视频就非常困难,所以探索 - 利用式算法就非常必要了。
更重要的是,许多这样的系统最终包含了由人生成的明确的标签。比如,Netflix 雇佣了 40 多个人去手工为电影和电视节目打标签,目的就是为了更好的做推荐,并且生成“有强势女主角的外国电影”之类的标签,YouTube 会请人手工为每个广告打标签,这样在作广告点击预测时才会有更好的特征,而谷歌在训练她的搜索算法时,很大程度上要依赖于内部一个很大的专门负责给 < 查询,网页 > 对打分的团队打出来的分值。
还有另一个例子,假如你是一个像 eBay 或 Etsy 之类的电子商务网站。你就会慢慢看到许多卖伟哥、毒品和其它禁售商品的垃圾网页,这样你就会想借助机器学习之力解决这个问题。但你该如何做呢?
- 首先,你需要有人来为训练数据打标签。你不能使用日志,也不能让用户帮你给什么东西加标记,如果真的用了这些,它们肯定是有很强误导性的(那些垃圾网页本身也会把系统搞乱)。但收集训练数据这事本身就是一个大难题。你可能需要成百上千个标签,需要几千个小时的工作量,那要从哪里才能得到这些数据呢?
- 然后,你要构建和部署一个真正的机器学习算法。即使你有机器学习专家,这也是一个非常困难而又耗时的过程:你该如何选择算法,该怎样选择把怎样的特征输入算法,该怎样以一种重复的方式做这事,从而非常容易地尝试不同的模型和参数?
- 即使是在你部署了你的第一版垃圾分类器之后,你也不能就此止步。当你有了新的用户群体,或者垃圾制造者开始用新的方法时,显示在你的网站上的垃圾信息就很快会发生改变。所以你得不断地持续重复第一步和第二步,而且这两个步骤还是非常难以自动化的,特别是要维持你需要的精确度时。
- 即使你有了一套可以工作的、而且功能完备的机器学习流水线时,你的工作也还没完。你不会想不小心打上标签而删除掉合法用户。所以总会有些机器学习决策的边界情况,需要用人力去查看。你又该如何构建一套可扩展的人力流水线,可以无缝地整合进你的机器学习系统,并且实时返回结果呢?
在我们 Hybrid 公司,我们有用于机器学习和大规模人力工作的平台,我们碰上了各种各样的难题,才使得我们要一遍又一遍地构建这套复杂的流水线,所以我们定义了一个单一的 API 来隐藏背后的所有复杂度:
# Create your classifier curl https://www.hybridml.com/api/classifiers -u API_KEY: -d categories="spam, not spam" -d accuracy=0.99 # Start classifying curl https://www.hybridml.com/api/classify -u API_KEY: -d classifier_id=ABCDEFG -d text="Come buy the latest Viagra at 50% off."
在底层,这个函数调用会自动默默地判定一个机器学习分类器是不是已经足够自己做出将例子数据分类,还是需要人工介入的决定。模型是自动构建的,而且也会自动重新训练,所以调用者从来不用担心是不是需要更多的数据。
在这篇文章剩下的内容里,我们会更深入地探讨上文中提到的那些问题的细节,即部署机器学习去解决的真实世界中的各种常见问题。
获得用于训练的标签
要训练一个垃圾分类器,首先你得有一堆训练数据,而且要相应地打上“垃圾”和“非垃圾”的标签,这些该怎么得到呢?
有种方法就是使用你的网站上的访问者信息及日志。在网页上加个按钮,让访问者可以把某些网页标记为垃圾,然后再用这些做为训练数据。
但这种方法也是很有问题的,原因列举如下:
绝大多数的访问者都会直接忽略这样的按钮,所以你可用的训练数据其实非常少。
而且也很容易被利用:那些垃圾制造者只要简单地开始把合法网页标记成垃圾就好了。
由于某些原因,这样也是很片面的(毕竟,也有很多人真的被垃圾邮件骗过)。
另一种方法就是你自己来给许多网页打上标签。但这其实是对时间和资源的浪费:在所有的网页中,垃圾内容只能占 1-2%,所以你会需要成百上千种网页分类器(还要花上几千个小时的时间),这样才能打造出有效的训练数据集。
于是你就会想要有一大群工作人员来梳理许许多多的网页,再根据一系列的说明来把它们标记成“垃圾”或“非垃圾”。一般来说,要找到做这样类型工作的工人的方法有几种,比如去网上发招聘信息,或者用亚马逊 Mechanical Turk、Crowdflower 或 Hybrid 之类的众包平台。
可是,由众包或这些类似方法产生的工作成果质量是非常低的,当工作人员随便点击这些标签时,我们经常可以看到垃圾率可能高达 80-90%。所以你就要把控工人们的工作成果来保证准确性。
有种非常常见的监控手段就是使用黄金标准:你自己给若干个网页打上垃圾或非垃圾的标签,再把它们随机发给你的工人们让他们去做标记,看看他们的想法和你的是否一致。
还有种可能的办法,就是使用统计分布测试来找出那些表现异常的工人。设想一个简单的给图像打标签工作:如果大多数的工人都会把 80% 的图像标记成“猫”,把 20% 标记成“不是猫”,然后有一个工人却只把 45% 的图像标记成“猫”,那他就值得注意了。
有个难点在于工人们很可能是完全合理地相互偏差很大。比如,假如人们在某天就是多上传了一些猫的图像,或者垃圾制造者们喜欢在晚上活动,那么与那些在夜晚工作的工人们相比,白天工作的工人们就会标记出更多的“猫”和“非垃圾”。要考虑到这样的自然偏差,更精细的方法就是使用非参数贝叶斯方法来让工人们的输出聚类,然后再根据这些来衡量偏离。
模型选择
当我们有了足够的训练标签之后,我们就可以开始构建自己的机器学习模型了。我们该用哪种算法呢?以文本分类领域为例,最常用的三种算法分别是朴素贝叶斯、逻辑回归法和深度神经网络。
我们不会在这里深入地讨论该如何选择使用哪种机器学习算法,但考虑不同算法之间差别的一个好方法就是偏差- 方差权衡。简单地说,在存在大量数据的情况下,简单模型的表现往往不如复杂模型(要准确地为问题建模它们不够强大,所以它们的偏差很大),但在数据有限的情况下它们却常常会表现得很好(复杂的模型常常会过度适合,对于数据中的微小变化过于敏感,所以会表现出高偏差)。
所以,如果你手上的标签数量有限,你就可以从一个比较简单的模型和比较少的特征开始,这样就已经很好了,而且通常效果更好。等以后你的数据更多之后,你再加上更精密的算法。
这也意味着一个非常强大的算法在早期是没有那么准确的,但并不意味着在后期就不必重新评估它的表现了。
在Hybrid 我们就是用的类似这样的方法。我们的目标是不管我们的数据量有多大,500 条还是500 万条,我们都要尽力有最准确的机器学习方法。因此,我们就会自动地在不同的算法之间切换:一般来说在初期我们会使用比较简单的模型,因为在数据量少时它们会表现得更好,等有了越来越多的数据进入系统之后我们就会切换到更强大的模型上去,主要就是看这些不同的算法在做一些样本之外的测试数据集时表现如何。
关于特征选择
关于特征选择,即选择哪些特征用于机器学习算法,主要有两类方法。
相对手动一些的办法是把特征选择作为一个预处理步骤:每个特征都在机器学习模型之外独立评分,只有得分最高的N 个特征,或者那些超过了某个阈值的特征才会入选。比如,一种常见的特征选择算法就是为该特征在各个不同的种类下是否会有不同的分布而打分(比如,在垃圾邮件的分类器中考虑要不要把单词“伟哥”当成一个特征时,我们要考虑“伟哥”这个词在垃圾邮件和非垃圾邮件中会不会频率出现显著不同),并且选择那些在不同的种类间分布差异尽量大的那些特征。
另外,现在越来越流行的方式就是让机器学习算法自己自动地完成特征选择过程。比如,逻辑回归算法模型会选择那些可以有效地控制让模型系数偏离零比较多的正则参数。通过尝试赋予这个参数不同的值,并且使用一个测试集来判断准确性,模型可以自己决定抛弃哪些特征,并且保留哪些特征。
关于特征还有一点要强调:增加交叉特征的方法非常有效。比如,假设一般年轻人和伦敦人都比较会点击广告,但伦敦的年青人却不爱点击广告。那么,一个使用了“用户是年青人并且用户住在伦敦”这样特征的广告点击预测模型,它的表现会比那些只包含孤立的年青人和伦敦人这些特征的模型好得多。这就是深度神经网络的一大好处:因为它们有完全关联的、层次的结构,所以它们可以自动发现它们之间的交叉特征,而逻辑回归等模型却需要我们把交叉特征输入进去。
适应变化
我们要注意的最后一个问题是如何管理数据分布的变化。比如,假如你在构建一个垃圾分类器时,突然间你的系统在一个新的国家里用户数有了一次爆发,或者说有种新的垃圾盯上了你的网站。因为这些都是新的数据源,所以你现有的分类器就不太可能可以继续精确地处理这样的情况了。
一种常见的实践是比较频繁而且定期地收集新标签,但这样效率可能不够好:你怎么知道该收集多少种新标签,以及如果数据分布其实并没有发生明显变化,又该怎么办?
于是,另一种常见的实践就是只收集新标签,然后只将模型保留几个月。但这样问题也很多,因为在这样做的同时质量也可能会显著地变差。
有个解决方案就是随机地将一些采样数据发去给人工打标签(比如当一个模型已经可以达到足够高的准确度之后,就把少于1% 的数据继续不断地发给人工去打标签)。通过这种办法,我们就可以不断地监控一小部分采样数据的准确性,从而在某些状况发生时可以很快检测到。你也可以监测算法返回的机器学习分数,如果这些分数的分布发生了变化,那也表明底层的数据发生了变化,模型需要重新训练一次了。
关于作者
Edwin Chen工作于 Hybrid,这是一个有关机器学习和人力资源的平台。他以前曾在谷歌、Twitter、Dropbox 等公司以及定量金融学领域构建机器学习系统。
Justin Palmer现在在 Hybrid 公司工作,他也是雇主软件 topfunnel 的创办人。他的前一份工作是在 LendingHome 作数据 VP,更早曾在 Basis Technology 和 MITRE 构建过用于语音识别的机器学习以及自然语言处理的产品。
评论