机器学习工程最佳实践
Martin Zinkevich
本文档旨在帮助具备机器学习基本知识的用户获享 Google 机器学习最佳实践的益处。该指南介绍了一种机器学习风格,类似于 Google C++ 风格指南和其他实用编程指南。如果您曾学习过机器学习课程,或者构建过机器学习模型或使用过机器学习模型,那么您具备阅读本文档所需的背景知识。
术语
在讨论有效机器学习时,我们会反复提到以下术语:
- 实例:您要进行预测的对象。例如,实例可能是您要将其分类为“与猫有关”或“与猫无关”的网页。
- 标签:预测任务的答案,即机器学习系统生成的答案,或训练数据中提供的正确答案。例如,网页的标签可能是“关于猫”。
- 特征:在预测任务中使用的实例属性。例如,网页可能具有“包含字词‘cat’”这一特征。
- 特征列:一组相关特征,例如用户可能居住的所有可能国家/地区的集合。示例中的一个或多个特征可能位于特征列中。“特征列”是 Google 专用的术语。特征列在 VW 系统(在雅虎/微软)中称为“命名空间”,也称为字段。
- 示例:实例(及其特征)和标签。
- 模型:预测任务的统计表示法。您可以使用示例训练模型,然后使用该模型进行预测。
- 指标:您关心的一个数值。不一定会直接进行优化。
- 目标:算法尝试优化的指标。
- 流水线:围绕机器学习算法的基础架构。 包括从前端收集数据、将其放入训练数据文件、训练一个或多个模型,以及将模型导出到生产环境。
- 点击率:网页访问者中点击广告中链接的访问者所占的百分比。
概览
如需打造出色的商品,请遵循以下准则:
像优秀的工程师一样做机器学习,而不是像优秀的机器学习专家一样做机器学习。
事实上,您将面临的大多数问题都是工程问题。即使拥有机器学习专家的所有资源,大部分成效也来自出色的特征,而非出色的机器学习算法。因此,基本方法如下:
- 确保您的流水线端到端都很稳健。
- 从设定合理的目标开始。
- 以简单的方式添加常识功能。
- 确保您的广告系列始终保持稳定。
这种方法将长期有效。只有在没有其他简单的技巧可以帮助您取得更大进步时,才应偏离这种方法。增加复杂性会减慢未来版本的发布速度。
在掌握了简单的技巧后,您或许会考虑使用尖端机器学习技术。请参阅第 3 阶段机器学习项目部分。
本文档的结构如下:
- 第一部分应该有助于您了解是否是构建机器学习系统的最佳时机。
- 第二部分介绍了如何部署第一个流水线。
- 第三部分介绍了如何在向流水线添加新功能的同时发布和迭代模型,以及如何评估模型和训练-服务偏差。
- 最后一部分介绍了在达到平台期时该怎么做。
- 之后,列出了相关工作和附录,其中介绍了本文档中常用作示例的系统的背景信息。
机器学习之前
规则 1:不要害怕发布未采用机器学习技术的产品。
机器学习很酷,但需要数据。从理论上讲,您可以从其他问题中获取数据,然后针对新产品调整模型,但这种方法的效果可能不如基本启发词语。如果您认为机器学习可以将效果提升 100%,那么启用启发词语可以将效果提升 50%。
例如,如果您要对应用市场中的应用进行排名,则可以使用安装率或安装次数作为启发词语。如果您要检测垃圾内容,请滤除之前发送过垃圾内容的发布商。也不要害怕使用人工编辑。如果您需要对联系人进行排名,请将最近使用过的联系人排名最高(甚至可以按字母顺序排名)。如果您的产品并非绝对需要使用机器学习,请在获得数据之前不要使用。
规则 2:首先,设计和实现指标。
在正式确定机器学习系统将执行的操作之前,请在当前系统中尽可能跟踪更多信息。这样做的原因如下:
- 这样更容易在早期从系统用户那里获得权限。
- 如果您认为未来可能会出现问题,最好现在就获取历史数据。
- 如果您在设计系统时考虑到指标插桩,日后将会更顺利。具体而言,您不希望在日志中 grep 字符串来插桩指标!
- 您会注意到哪些方面发生了变化,哪些方面保持不变。例如,假设您想直接优化日活用户数。不过,在您刚开始操控系统时,您可能会发现,对用户体验进行大幅更改并不会明显改变此指标。
Google+ 团队会衡量每次阅读的展开次数、每次阅读的转发次数、每次阅读的 +1 次数、每次阅读的评论次数、每位用户的评论次数、每位用户的转发次数等,并在投放帖子时使用这些数据来计算帖子的优质程度。另请注意,一个实验框架非常重要,您可以使用该框架将用户分组到不同的存储分区中,并按实验汇总统计数据。请参阅规则 12。
通过更灵活地收集指标,您可以更全面地了解自己的系统。发现问题?添加指标即可跟踪它!对上一个版本的一些量化变化感到兴奋?添加指标即可跟踪它!
规则 3:选择机器学习,而非复杂的启发词语。
一个简单的启发词语就可以让您的产品顺利发布。复杂的启发词语不可维护。获得数据并大致了解自己要实现的目标后,接下来就可以开始学习机器学习了。与大多数软件工程任务一样,您需要不断更新方法,无论是启发词语还是机器学习模型,您都会发现机器学习模型更易于更新和维护(请参阅规则 16)。
ML 第 I 阶段:您的第一个流水线
在构建第一个流水线时,请重点关注系统基础架构。虽然考虑您要进行的所有富有想象力的机器学习很有趣,但如果您不先信任自己的流水线,就很难弄清楚发生了什么。
规则 4:保持第一个模型的简单性,并确保基础架构正确无误。
第一个模型可为您的商品带来最大的提升,因此无需过于花哨。但您会遇到比预期更多的基础架构问题。在任何人都可以使用您新开发的炫酷机器学习系统之前,您必须确定:
- 如何向学习算法提供示例。
- 先确定“良好”和“不良”对您的系统而言意味着什么。
- 如何将模型集成到您的应用中。您可以实时应用模型,也可以离线对示例预计算模型,并将结果存储在表中。例如,您可能希望预分类网页并将结果存储在表格中,但也可能希望实时分类聊天消息。
选择简单的功能有助于确保:
- 特征正确传递给学习算法。
- 模型会学习合理的权重。
- 特征正确地传送到服务器中的模型。
一旦您拥有一个能够可靠地执行这三项操作的系统,就完成了大部分工作。简单模型可为您提供基准指标和基准行为,以便您测试更复杂的模型。有些团队的目标是实现“中性”的首次发布:在首次发布时,明确降低机器学习增益的优先级,以免分心。
第 5 条规则:独立于机器学习测试基础架构。
确保基础架构可测试,并封装系统的学习部分,以便您可以测试周围的所有内容。具体而言:
- 测试将数据传入算法。检查是否已填充应填充的特征列。在隐私保护允许的情况下,手动检查训练算法的输入。如果可能,请检查流水线中的统计信息,并将其与在其他位置处理相同数据的统计信息进行比较。
- 测试从训练算法中获取模型。确保训练环境中的模型与服务环境中的模型得出相同的分数(请参阅规则 37)。
机器学习具有不可预测性,因此请确保您对用于在训练和服务期间创建示例的代码进行了测试,并且您可以在服务期间加载和使用固定模型。此外,了解数据也很重要:请参阅关于分析大型复杂数据集的实用建议。
规则 6:复制流水线时,请注意丢失的数据。
通常,我们通过复制现有流水线来创建流水线(即Cargo Cult 编程),而旧流水线会丢弃新流水线所需的数据。例如,Google+ 时下流行的流水线会舍弃较旧的帖子(因为它会尝试对新帖子进行排名)。此流水线被复制以用于 Google+ 动态,在动态中,旧帖子仍然有意义,但该流水线仍会舍弃旧帖子。另一种常见模式是仅记录用户看到的数据。因此,如果我们想建立模型来预测用户未看到特定帖子的原因,这些数据就没有用,因为所有负例都已被舍弃。Play 中也出现了类似的问题。在开发 Play 应用首页时,我们创建了一个新流水线,其中还包含 Play 游戏着陆页中的示例,但没有任何功能来区分每个示例的来源。
规则 7:将启发词语转换为特征,或在外部处理启发词语。
通常,机器学习尝试解决的问题并不是全新的问题。您要解决的问题已经有现有系统可以用于排名、分类或处理。这意味着,存在一系列规则和启发词语。如果通过机器学习对这些启发词语进行微调,它们同样可以为您带来帮助。您应从启发词语中挖掘其所含的所有信息,原因有二:首先,向机器学习系统的过渡会更加顺畅。其次,这些规则通常包含您不想舍弃的大量系统直觉。您可以通过以下四种方式使用现有启发词语:
- 使用启发词语进行预处理。如果该功能非常出色,那么您可以选择这样做。例如,如果垃圾邮件过滤器中显示发件人已列入黑名单,请不要尝试重新学习“列入黑名单”的含义。屏蔽消息。这种方法最适合二元分类任务。
- 创建地图项。直接根据启发词语创建特征非常棒。例如,如果您使用启发词语来计算查询结果的相关性得分,则可以将得分作为特征的值包含在内。之后,您可能需要使用机器学习技术来处理值(例如,将值转换为有限个离散值中的某个值,或将其与其他特征组合),但首先要使用启发词语生成的原始值。
- 挖掘启发词语的原始输入。如果某个应用的启用次数、文本中的字符数和星期几这三个特征之间存在启发词语,请考虑将这些特征拆分开来,并将这些输入分别馈送给学习模型。适用于集成的某些技术也适用于此处(请参阅规则 40)。
- 修改标签。如果您认为启发词语捕获的信息目前不包含在标签中,可以选择此选项。例如,如果您尝试尽可能提高下载量,但同时也希望提供优质内容,那么解决方案可能是将标签乘以应用获得的平均星数。这里有很多余地。请参阅“您的第一个目标”。
在 ML 系统中使用启发词语时,请注意增加的复杂性。在新机器学习算法中使用旧启发词语有助于实现平滑过渡,但请考虑是否有更简单的方法可以实现相同的效果。
监控
一般而言,请养成良好的提醒卫生习惯,例如使提醒可操作并提供信息中心页面。
规则 8:了解系统的新鲜度要求。
如果模型已经一天了,性能会下降多少?一周大?四分之一?这些信息有助于您了解监控的优先级。如果模型一天不更新就会导致产品质量大幅下降,那么让工程师持续监控模型是明智之举。大多数广告投放系统每天都有新的广告要处理,并且必须每天更新。例如,如果Google Play 搜索的 ML 模型未更新,则可能在不到一个月的时间内产生负面影响。Google+ 中的“时下流行”部分的某些模型在模型中没有帖子标识符,因此这些模型的导出频率较低。其他具有帖子标识符的模型的更新频率要高得多。另请注意,新鲜度可能会随时间而变化,尤其是在模型中添加或移除特征列时。
规则 9:在导出模型之前检测问题。
许多机器学习系统都有一个阶段,您可以在其中将模型导出到服务端。如果导出的模型存在问题,则属于面向用户的问题。
在导出模型之前,请先进行完整性检查。具体而言,请确保模型在留出的数据上的表现合理。或者,如果您对数据仍有疑虑,请勿导出模型。许多持续部署模型的团队都会在导出前检查 ROC 曲线下面积(即 AUC)。与尚未导出的模型相关的问题需要发送电子邮件提醒,但面向用户的模型存在的问题可能需要在页面上显示。因此,最好先等待一段时间,确保一切顺利,然后再影响用户。
规则 10:监控静默失败。
与其他类型的系统相比,机器学习系统更容易出现此问题。假设要联接的特定表不再更新。机器学习系统会做出调整,行为会继续保持合理良好的水平,但会逐渐衰减。有时,您会发现表格已过时几个月,而简单地刷新表格所带来的效果提升,比该季度任何其他发布功能都更显著!特征的覆盖率可能会因实现变更而发生变化:例如,特征列可能会在 90% 的示例中填充,但突然下降到 60% 的示例。Play Once 曾有一张表格已过时 6 个月,仅仅刷新该表格就使安装率提高了 2%。如果您跟踪数据的统计信息,并不时手动检查数据,则可以减少此类故障。
规则 11:为特征列指定所有者和文档。
如果系统较大且包含许多地图项列,请了解是谁创建或维护了每个地图项列。如果您发现了解某个地图项列的人员即将离职,请确保有其他人掌握相关信息。虽然许多地图项列都有描述性名称,但最好能更详细地说明地图项的含义、来源以及预期带来的帮助。
第一个目标
您有许多指标或衡量您关注的系统的指标,但机器学习算法通常只需要一个目标,即算法“尝试”优化的数字。我在这里将目标与指标区分开来:指标是系统报告的任何数字,可能重要,也可能不重要。另请参阅规则 2。
规则 12:不要过度思考要选择哪个目标进行直接优化。
您希望创收、让用户满意,并让世界变得更加美好。您关心许多指标,因此应衡量所有这些指标(请参阅规则 2)。不过,在机器学习流程的早期,您会发现所有指标都会上升,即使您未直接优化这些指标也是如此。例如,假设您关注点击次数和在网站上停留的时间。如果您以点击次数为目标进行优化,则所花费的时间可能会增加。
因此,请保持简单,如果您仍然可以轻松提高所有指标,请不要过于纠结于如何平衡不同的指标。不过,也不要过于强调这一点:不要将您的目标与系统的最终健康状况混为一谈(请参阅第 39 条规则)。此外,如果您发现直接优化指标的效果有所提升,但决定不发布,则可能需要对目标进行一些修改。
规则 13:为第一个目标选择简单、可观察且可归因的指标。
通常,您并不知道真正的目标是什么。您认为自己知道,但当您仔细研究数据并并排分析旧系统和新机器学习系统时,您会发现自己需要调整目标。此外,不同团队成员对真正的目标往往无法达成一致。机器学习目标应易于衡量,并可用作“真实”目标的代理。 事实上,通常没有“真正的”目标(请参阅规则 39)。因此,请使用简单的 ML 目标进行训练,并考虑在其上添加“政策层”,以便您添加其他逻辑(希望是非常简单的逻辑)来进行最终排名。
最容易建模的用户行为是直接观察到的,并且归因于系统的操作:
- 用户是否点击了排名靠前的链接?
- 此排名对象是否已下载?
- 您是否转发/回复/通过电子邮件发送了此排名对象?
- 此排名对象是否已分级?
- 所显示的对象是否被标记为垃圾内容/色情内容/冒犯性内容?
一开始,请避免对间接影响进行建模:
- 用户是否在第二天进行了访问?
- 用户访问网站的时长是多少?
- 日活跃用户数是多少?
间接影响是极佳的指标,可在 A/B 测试期间和发布决策期间使用。
最后,请勿尝试让机器学习算法解决以下问题:
- 用户是否满意地使用该产品?
- 用户对体验是否满意?
- 该产品是否有助于改善用户的整体身心健康?
- 这对公司整体健康有何影响?
这些都是很重要的指标,但也非常难以衡量。请改用代理:如果用户满意,他们会在网站上停留更长时间。如果用户满意,就会在明天再次访问。就健康和公司健康而言,需要人工判断来将任何机器学习目标与您销售的产品的性质和您的业务计划联系起来。
规则 14:从可解释的模型开始,可以更轻松地进行调试。
线性回归、逻辑回归和泊松回归直接受到概率模型的启发。每个预测都可以解释为概率或预期值。与尝试直接优化分类准确性或排名性能的模型(使用零-一损失函数、各种 hinge 损失函数等目标)相比,它们更易于调试。例如,如果训练中的概率与并排比较或通过检查生产系统预测的概率不一致,这种偏差就可能表明存在问题。
例如,在线性回归、逻辑回归或泊松回归中,数据的子集存在平均预测期望等于平均标签的情况(1 阶矩量校准或仅校准)。假设您没有正则化且算法已收敛,则此结论成立;一般来说,此结论也近似成立。如果您有一个特征,每个示例的值为 1 或 0,则系统会对该特征为 1 的 3 个示例进行校准。此外,如果您有一个特征对每个示例都是 1,则所有示例的集合都会经过校准。
使用简单的模型,更容易处理反馈环(请参阅规则 36)。通常,我们会根据这些概率预测结果做出决策:例如,按预期价值(即点击/下载等概率)递减对帖子进行排名。不过,请记住,在选择要使用的模型时,决策比根据模型推断数据的可能性更重要(请参阅规则 27)。
规则 15:在政策层中将垃圾内容过滤和质量排名分开。
优质排名是一门精致的艺术,但垃圾内容过滤是一场战争。您用来确定优质帖子的信号会对使用您系统的用户显而易见,他们会调整自己的帖子以使其具有这些属性。因此,您的质量排名应侧重于对发布出于善意的内容进行排名。您不应因为质量排名学习器会将垃圾内容评为高分而忽视它。同样,应将“露骨”内容与质量排名分开处理。垃圾邮件过滤则另当别论。您必须预料到,您需要生成的特征会不断变化。通常,您会向系统中添加一些显而易见的规则(例如,如果某条帖子收到的垃圾投票超过 3 票,则不检索该帖子等)。任何学习到的模型都必须每天更新(如果不是更快的话)。内容创作者的声誉将发挥重要作用。
在某种程度上,这两个系统的输出必须集成。请注意,过滤搜索结果中的垃圾内容可能比过滤电子邮件中的垃圾内容更为严格。此外,从质量分类器的训练数据中移除垃圾内容也是一项标准做法。
机器学习第二阶段:特征工程
在机器学习系统生命周期的第一阶段,重要的问题是将训练数据纳入学习系统、对感兴趣的所有指标进行插桩,以及创建服务基础架构。在您拥有插桩了单元测试和系统测试的正常运行端到端系统后,第 2 阶段便可开始了。
第二阶段有很多简单易行的改进措施。系统中可以引入的显而易见的功能有很多。因此,机器学习的第二阶段涉及提取尽可能多的特征,并以直观的方式将它们组合起来。在此阶段,所有指标都应该仍在上升。我们将推出许多产品,这是一个非常好的时机,可以吸引大量工程师来整合您需要的所有数据,从而打造出真正出色的学习系统。
规则 16:规划发布和迭代。
不要指望您现在正在构建的模型将是您推出的最后一个模型,甚至不要指望您会停止推出模型。因此,请考虑您在此次发布中添加的复杂性是否会减慢未来的发布速度。许多团队多年来一直每季度发布一个模型,甚至更多。推出新模型有三个基本原因:
- 您正在开发新功能。
- 您正在调整正则化,并以新的方式组合旧特征。
- 您正在调整目标。
无论如何,对模型多加关心总是好的:查看馈送到示例中的数据有助于发现新信号以及旧的、已损坏的信号。因此,在构建模型时,请考虑添加、移除或重组特征的难易程度。想想创建流水线的新副本并验证其正确性是多么容易。考虑是否可以让两个或三个副本并行运行。最后,请不要担心第 35 个特征 16 是否会进入此版本的流水线。您将在下一季度收到。
规则 17:先从直接观察和报告的特征入手,而不是从学习的特征入手。
这可能是一个有争议的观点,但可以避免很多陷阱。首先,我们来介绍一下什么是学习特征。学习特征是指由外部系统(例如非监督式聚类系统)或学习器本身(例如通过分解模型或深度学习)生成的特征。这两种方法都很有用,但可能会存在很多问题,因此不应在第一个模型中使用。
如果您使用外部系统创建功能,请注意外部系统有自己的目标。外部系统的目标可能与您的当前目标只有很弱的相关性。如果您截取外部系统的快照,该快照可能会过时。如果您通过外部系统更新功能,则这些功能的含义可能会发生变化。如果您使用外部系统提供功能,请注意这种方法需要非常小心。
分解模型和深度模型的主要问题是它们是非凸的。因此,无法保证可以近似求得或找到最优解,并且每次迭代中找到的局部最小值可能不同。这种变化会导致您难以判断对系统所做的更改的影响是具有意义的还是随机的。通过创建不含深层特征的模型,您可以获得出色的基准性能。达到此基准后,您可以尝试更深奥的方法。
规则 18:使用可跨情境概括的内容特征进行探索。
机器学习系统通常只是一个更大系统的一小部分。例如,假设您认为某个帖子可能会被用于“时下流行”,那么在该帖子显示在“时下流行”之前,就会有许多人为其点赞、转发或评论。如果您向学习器提供这些统计信息,它便可以在优化环境中宣传没有数据的新帖子。YouTube“接下来观看”部分可以使用 YouTube 搜索中的观看次数或同看次数(即在观看某个视频后观看另一个视频的次数)。您还可以使用明确的用户评分。最后,如果您将某个用户操作用作标签,那么在其他上下文中在文档上看到该操作会非常有用。借助所有这些功能,您可以将新内容纳入情境。请注意,这与个性化无关:先确定用户是否喜欢此情境中的相应内容,然后再确定哪些用户更喜欢或更不喜欢。
规则 19:请尽可能使用非常具体的功能。
面对海量数据,学习数百万个简单特征要比学习几个复杂特征更容易。检索到的文档和规范化查询的标识符无法提供太多一般信息,但可让您的排名与主查询的标签保持一致。因此,不要害怕组合使用一些特征,其中每个特征都只适用于数据的一小部分,但总体覆盖率超过 90%。您可以使用正则化来消除应用于示例过少的特征。
规则 20:组合和修改现有功能,以人类能够理解的方式创建新功能。
您可以通过多种方式组合和修改地图项。借助 TensorFlow 等机器学习系统,您可以通过转换来预处理数据。最常见的两种方法是“离散化”和“交叉”。
离散化包括获取一个连续特征,并根据该特征创建许多离散特征。考虑年龄等连续特征。您可以创建一个特征,当年龄小于 18 时,该特征的值为 1;创建另一个特征,当年龄介于 18 到 35 之间时,该特征的值为 1,以此类推。不要过度思考这些直方图的边界:基本百分位数就足以让您获得最大的影响。
交叉项用于组合两个或更多特征列。在 TensorFlow 的术语中,特征列是一组同质特征(例如 {male, female}、{US, Canada, Mexico} 等)。交叉是指包含以下特征的新特征列,例如 {male, female} × {US,Canada, Mexico}。这个新特征列将包含特征(男性、加拿大)。如果您使用的是 TensorFlow,并指示 TensorFlow 为您创建此交叉项,则代表加拿大男性的示例中将包含此“男性、加拿大”特征。请注意,需要大量数据才能学习包含三个、四个或更多基本特征列的交叉项的模型。
生成非常大的特征列的交叉可能过度拟合。例如,假设您要进行某种搜索,并且有一个包含查询中字词的特征列,以及一个包含文档中字词的特征列。您可以将这些元素与交叉符号组合使用,但最终会产生很多功能(请参阅规则 21)。
在处理文本时,有两种替代方案。最严厉的惩罚是点积。点积的形式最简单,只需统计查询和文档中共同的字词数量即可。然后,此特征可以离散化。另一种方法是交集:因此,我们将得到一个特征,只有当文档和查询中都包含“pony”一词时,该特征才会出现;另一个特征则是,只有当文档和查询中都包含“the”一词时,该特征才会出现。
规则 21:您可以在线性模型中学习的特征权重数量与您拥有的数据量大致成正比。
关于模型的适当复杂性水平,有许多令人着迷的统计学习理论结果,但您基本上只需要了解这条规则。我曾与一些人交谈过,他们怀疑能否通过一千个示例学到任何东西,或者是否需要超过一百万个示例,因为他们陷入了某种学习方法的泥沼。关键在于根据数据规模扩展学习:
- 如果您正在研究搜索排名系统,并且文档和查询中包含数百万个不同的字词,并且您有 1,000 个标记示例,那么您应该使用文档和查询特征之间的点积、TF-IDF 以及六七个其他高度人工工程化的特征。1, 000 个示例,十几个特征。
- 如果您有 100 万个示例,则可以使用正则化和可能的特征选择来交叉文档和查询特征列。这将为您提供数百万个特征,但在使用正则化后,特征数量会减少。1, 000 万个示例,可能有 10 万个特征。
- 如果您有数十亿或数百亿个示例,则可以使用特征选择和正则化将特征列与文档和查询令牌交叉。您将拥有 10 亿个示例和 1, 000 万个特征。统计学习理论很少给出严格的边界,但对于起点提供了很好的指导。
最后,使用规则 28 来确定要使用哪些功能。
规则 22:清理不再使用的功能。
未使用的功能会造成技术债务。如果您发现自己没有使用某项功能,并且将其与其他功能组合使用也不起作用,请将其从基础架构中移除。您希望保持基础架构的简洁,以便尽快试用最有前景的功能。如有必要,其他人可以随时重新添加您的功能。
在考虑要添加或保留哪些功能时,请注意覆盖面。该功能涵盖了多少个示例?例如,如果您提供了一些个性化功能,但只有 8% 的用户使用了任何个性化功能,那么这些功能的效果不会太理想。
同时,某些功能的效果可能超出预期。例如,如果您有一个特征仅涵盖 1% 的数据,但具有该特征的 90% 示例都是正例,那么添加该特征会非常有用。
对系统进行人工分析
在进入机器学习的第 3 阶段之前,请务必重点关注机器学习课程中未教授的内容:如何查看现有模型并对其进行改进。这更像是一门艺术,而不是一门科学,但有几种反模式有助于避免出现此类问题。
规则 23:您不是典型的最终用户。
这可能是团队陷入困境的最简单方式。虽然鱼食测试(在团队内使用原型)和狗食测试(在公司内使用原型)有很多好处,但员工应检查性能是否正确。虽然明显不良的更改不应采用,但任何看起来接近正式版的更改都应进一步测试,方法包括付费让外行人回答众包平台上的问题,或通过对真实用户进行实时实验。
这有两个原因。第一个原因是您对代码太熟悉。您可能在寻找帖子的某个特定方面,或者只是过于情绪化(例如存在确认偏差)。其次,您的时间太宝贵了。考虑一下让 9 名工程师参加一小时会议的费用,以及在众包平台上购买多少份合同工人标签。
如果您真的想获得用户反馈,请使用用户体验方法。在流程的早期创建用户角色(Bill Buxton 的 Sketching User Experiences 中有相关说明),然后进行易用性测试(Steve Krug 的 Don’t Make Me Think 中有相关说明)。用户角色涉及创建假想用户。例如,如果您的团队全部由男性组成,不妨设计一个 35 岁的女性用户角色(包含完整的用户特征),然后查看它生成的结果,而不是查看针对 25 至 40 岁男性的 10 个结果。在易用性测试中,邀请真实用户(在本地或远程)参与,观察他们对您网站的反应,也可以让您获得全新的视角。
规则 24:衡量模型之间的差异。
在任何用户查看新模型之前,您可以进行的最简单(有时也是最有用)的衡量之一是计算新结果与生产环境中的结果有何不同。例如,如果您遇到排名问题,请针对整个系统中的一部分查询运行这两种模型,然后查看结果的对称差的大小(按排名位置加权)。如果差异非常小,那么您无需运行实验即可断定效果不会有太大变化。如果差异很大,您需要确保更改是正确的。查看对称差异较大的查询有助于您定性了解变化情况。不过,请确保系统稳定。确保模型与自身相比具有较低(最好为零)的对称差异。
规则 25:在选择模型时,实用性能胜过预测能力。
您的模型可能会尝试预测点击率。不过,归根结底,关键问题是您要如何使用该预测结果。如果您要使用该模型对文档进行排名,那么最终排名的质量比预测本身更重要。如果您预测文档是垃圾内容的概率,然后对要屏蔽的内容设置截断值,那么允许通过的内容的准确性更为重要。大多数情况下,这两者应该是一致的:如果不一致,则可能只会带来微小的收益。因此,如果某项更改可以减少日志丢失,但会降低系统性能,请寻找其他功能。如果这种情况开始变得更频繁,则表示您需要重新审视模型的目标。
规则 26:在测量的错误中寻找规律,并创建新特征。
假设您发现模型对某个训练示例的预测结果是“错误的”。在分类任务中,此错误可能是假正例或假负例。在排名任务中,错误可能是一个正例的排名低于负例的对子。最重要的一点是,这是一个很好的例子,说明机器学习系统知道自己出错了,并希望有机会进行修正。如果您向模型提供可用于修正错误的特征,模型会尝试使用该特征。
另一方面,如果您尝试根据系统认为不属于错误的示例创建特征,系统会忽略该特征。例如,假设用户在 Play 应用搜索中搜索“免费游戏”。假设前几条结果中有一款不太相关的恶搞应用。因此,您可以为“恶搞应用”创建一个功能。不过,如果您希望尽可能提高安装次数,而用户在搜索免费游戏时安装了恶搞应用,则“恶搞应用”功能就不会产生您想要的效果。
找到模型出错的示例后,请查找当前特征集之外的趋势。例如,如果系统似乎会降低篇幅较长的帖子的排名,则可以添加帖子长度。不要过于具体地说明您要添加的功能。如果您要添加帖子长度,请不要尝试猜测“长”的含义,只需添加十几个特征,然后让模型自行确定如何处理这些特征即可(请参阅规则 21)。这是实现所需结果的最简单方法。
规则 27:尝试量化观察到的不良行为。
团队中的一些成员会开始对现有损失函数无法捕获的系统属性感到不满。此时,他们应不惜一切代价将抱怨转化为可靠的数据。例如,如果他们认为 Play 搜索中显示的“恶搞应用”过多,则可以让人工评价员来识别恶搞应用。(在这种情况下,您可以使用人工标记的数据,因为占流量比例较小的查询占据了较大的比例。)如果您的问题是可衡量的,那么您就可以开始将其用作特征、目标或指标。一般规则是“先衡量,后优化”。
规则 28:请注意,短期行为相同并不意味着长期行为相同。
假设您有一个新系统,该系统会查看每个 doc_id 和 exact_query,然后计算每个查询对每个文档的点击概率。您发现,在并排测试和 A/B 测试中,新系统的行为与当前系统几乎完全相同,因此,鉴于其简单性,您决定发布该系统。不过,您发现系统没有显示任何新应用。为什么呢?由于您的系统仅根据自己对该查询的查询记录显示文档,因此无法得知应显示新文档。
要了解此类系统的长期运作方式,唯一的方法就是让其仅根据模型投入使用时获取的数据进行训练。这很难。
训练-应用偏差
训练-应用偏差是指训练期间与应用期间的性能差距。造成这种偏差的原因可能是:
- 数据在训练和服务流水线中处理方式的差异。
- 训练和应用数据之间的变化。
- 模型和算法之间的反馈环。
我们发现,Google 的生产机器学习系统存在训练-服务偏差,会对性能产生负面影响。最佳解决方案是明确监控它,以免系统和数据更改引入不易察觉的偏差。
规则 29:若要确保训练方式与服务方式一致,最好的方法是保存在服务时使用的一组特征,然后将这些特征管道化到日志,以便在训练时使用。
即使您无法对每个示例执行此操作,也请对一小部分示例执行此操作,以便验证服务和训练之间的一致性(请参阅规则 37)。在 Google 进行过此类衡量工作的团队有时会对结果感到惊讶。YouTube 首页已在投放时改用日志记录功能,质量得到显著提升,代码复杂性也降低了,目前许多团队正在改用日志记录基础架构。
规则 30:按重要性权重抽样的数据,请勿随意舍弃!
当数据过多时,您可能会想只使用文件 1-12,而忽略文件 13-99。这是错误的做法。虽然可以舍弃从未向用户显示的数据,但对于其余数据,最好使用重要性权重。重要性权重意味着,如果您决定以 30% 的概率抽样示例 X,则为其分配权重 10/3。使用重要性权重时,规则 14 中讨论的所有校准属性仍然适用。
规则 31:请注意,如果您在训练和传送时联接表中的数据,表中的数据可能会发生变化。
假设您要将文档 ID 与包含这些文档的特征(例如评论数或点击次数)的表格联接起来。在训练和部署期间,表格中的特征可能会发生变化。这样一来,模型对同一文档的预测结果在训练和应用阶段可能会有所不同。避免此类问题的最简单方法是在投放时记录特征(请参阅规则 32)。如果表格变化缓慢,您还可以按小时或每天对表格进行快照,以获取合理接近的数据。请注意,这仍无法完全解决问题。
规则 32:请尽可能在训练流水线和服务流水线之间重复使用代码。
批处理不同于在线处理。在在线处理中,您必须在每个请求到达时处理该请求(例如,您必须为每个查询进行单独的查找),而在批量处理中,您可以组合任务(例如进行联接)。在服务时,您执行的是在线处理,而训练是一项批处理任务。不过,您可以执行一些操作来重复使用代码。例如,您可以创建一个特定于您系统的对象,在该对象中,任何查询或联接的结果都可以以非常人性化的方式存储,并且错误可以轻松测试。然后,在收集到所有信息后,您可以在服务或训练期间运行一个常用方法,以便在特定于您系统的可读取对象与机器学习系统预期的任何格式之间建立桥梁。这消除了导致训练-应用偏差的一个原因。因此,请尽量不要在训练和服务之间使用两种不同的编程语言。做出此决定后,您几乎无法共享代码。
规则 33:如果您根据 1 月 5 日之前的数据生成模型,请使用 1 月 6 日及之后的数据对模型进行测试。
一般而言,应针对在训练模型时收集的数据之后收集的数据衡量模型的性能,因为这更能反映您的系统在生产环境中的表现。如果您根据 1 月 5 日之前的数据生成模型,请使用 1 月 6 日之后的数据对模型进行测试。您可能会发现,在应用于新数据时,模型的表现不会那么好,但也不会大幅下降。由于可能存在每日效果,因此您可能无法预测平均点击率或转化率,但曲线下面积(表示为正例得分高于负例得分的概率)应该会比较接近。
规则 34:在过滤的二元分类中(例如垃圾邮件检测或确定感兴趣的电子邮件),为了获得非常干净的数据,可以短期内牺牲一点性能。
在过滤任务中,系统不会向用户显示标记为负例的示例。假设您有一个过滤器,会在投放时屏蔽 75% 的负例。您可能会想要从向用户显示的实例中提取更多训练数据。例如,如果用户将您的过滤器漏过的电子邮件标记为垃圾邮件,您可能需要从中吸取教训。
但这种方法会引入采样偏差。您也可以在投放期间将 1% 的所有流量标记为“留存”,并将所有留存示例发送给用户,以便收集更清晰的数据。现在,您的过滤器会屏蔽至少 74% 的负例。这些留出的示例可以成为您的训练数据。
请注意,如果您的过滤器会屏蔽 95% 或更多负例,这种方法的可行性就会降低。即便如此,如果您想衡量投放效果,也可以使用更小的样本(例如 0.1% 或 0.001%)。十万个示例足以非常准确地估算效果。
规则 35:注意排名问题固有的偏差。
如果您对排名算法进行了彻底的更改,以致于出现不同的结果,那么您实际上就更改了算法日后会看到的数据。这种偏差会出现,因此您应围绕此偏差设计模型。有多种不同的方法。这些方法都是为了偏向模型已经见过的数据。
- 对覆盖更多查询的特征采用更高的正则化,而不是仅针对一个查询启用的特征。这样一来,模型会优先使用对一个或几个查询而言是特定特征的,而不是对所有查询而言是一般特征的。此方法有助于防止非常热门的结果渗透到不相关的查询中。请注意,这与更传统的建议相反,后者建议对具有更多唯一值的特征列进行更多正则化。
- 仅允许特征具有正权重。因此,任何好的特征都比“未知”特征要好。
- 不提供仅限文档的功能。这是第 1 种情况的极端版本。例如,即使某个给定应用是热门下载应用,无论用户搜索什么查询,您也不希望在所有位置都展示该应用。不提供仅限文档的功能,可以让事情变得简单。您不想在所有位置展示特定热门应用的原因,与确保所有所需应用均可访问的重要性有关。例如,如果用户搜索“观鸟应用”,可能会下载“愤怒的小鸟”,但这显然不是他们的意图。展示此类应用可能会提高下载率,但最终无法满足用户的需求。
规则 36:避免使用位置特征的反馈环。
内容的位置会极大地影响用户与内容互动的可能性。如果您将某款应用放在第一位,它将获得更多点击,而且您会确信它更有可能获得点击。解决此问题的一种方法是添加位置特征,即与内容在网页中的位置相关的特征。您可以使用位置特征训练模型,模型会学习对特征(例如“第 1 位”)进行加权。因此,对于“1stposition=true”的示例,模型会降低对其他因素的权重。然后,在投放时,您不向任何实例提供位置特征,或者向所有实例提供相同的默认特征,因为您是在确定展示顺序之前为候选广告评分。
请注意,由于训练和测试之间存在这种不对称性,因此请务必将任何位置特征与模型的其余部分分开。理想情况下,模型应为位置特征函数和其余特征函数的和。例如,请勿将位置地图项与任何文档地图项交叉使用。
规则 37:衡量训练/应用偏差。
从最广泛的意义上讲,有几种因素可能会导致偏差。此外,您还可以将其划分为多个部分:
- 训练数据和预留数据的效果差异。一般来说,这种情况始终存在,但并不一定是坏事。
- 预留数据和“次日”数据的效果差异。再次说明一下,此问题始终存在。您应调整正则化参数,以最大限度地提高次日效果。不过,如果预留数据和次日数据之间的效果出现大幅下降,则可能表明某些特征具有时效性,并且可能会降低模型性能。
- “次日”数据和实时数据的效果差异。如果您将模型应用于训练数据中的示例和服务时的同一示例,则应该会得到完全相同的结果(请参阅规则 5)。因此,如果出现差异,则可能表示存在工程错误。
机器学习第 III 阶段:增长放缓、优化优化和复杂模型
我们会通过一些指标来表明第二阶段即将结束。首先,您的每月收入将开始减少。您将开始在指标之间进行权衡:在某些实验中,您会看到某些指标上升,而其他指标下降。这下子有趣了。由于效果更难以实现,机器学习技术必须变得更加复杂。需要注意的是,与前面几部分相比,本部分包含的规则更为宽泛。我们见过许多团队都经历过机器学习第一阶段和第二阶段的幸福时光。进入第 III 阶段后,团队必须找到自己的路径。
规则 38:如果目标不一致已成为问题,请勿浪费时间在新功能上。
随着效果衡量结果趋于稳定,您的团队将开始关注超出当前机器学习系统目标范围的问题。如前所述,如果现有算法目标不涵盖产品目标,您需要更改目标或产品目标。例如,您可以优化点击次数、加号或下载次数,但在发布决策时,部分依据是人工评价者。
规则 39:发布决策是长期产品目标的替代指标。
Alice 有一个想法,可以减少预测安装次数时出现的逻辑损失。她添加了一项功能。逻辑损失会降低。在开展实时实验后,她发现安装率有所提高。不过,在发布审核会议上,有人指出每日活跃用户数下降了 5%。团队决定不发布该模型。Alice 感到失望,但现在意识到,发布决策取决于多种标准,其中只有部分标准可以使用机器学习直接优化。
事实是,现实世界不是《地下城与龙》:没有用于确定产品健康状况的“生命值”。该团队必须使用其收集的统计信息,尝试有效预测该系统未来的效果。他们需要关注互动度、1 日活跃用户数 (DAU)、30 日活跃用户数、收入和广告客户的投资回报率。这些在 A/B 测试中可衡量的指标本身只是更长远目标的代理指标:让用户满意、增加用户数量、让合作伙伴满意和盈利,而这些目标本身也可以视为实现五年后拥有实用、高品质产品和蓬勃发展的公司的代理指标。
只有在所有指标都有所提升(或至少没有恶化)时,才可以轻松做出发布决策。如果团队需要在复杂的机器学习算法和简单的启发词语之间进行选择,并且简单的启发词语在所有这些指标方面都表现得更好,则应选择启发词语。此外,所有可能的指标值都没有明确的排名。具体而言,请考虑以下两种场景:
实验 | 日活跃用户数 | 收入/天 |
---|---|---|
A | 100 万 | 400 万美元 |
B | 200 万 | 200 万美元 |
如果当前系统是 A,那么该团队不太可能切换到 B。如果当前系统是 B,则团队不太可能切换到 A。这似乎与理性行为相悖;不过,对指标变化的预测未必准确无误,因此这两种变化都存在很大风险。每个指标都涵盖团队关注的一些风险。
此外,没有任何指标涵盖团队的终极问题:“我的产品在 5 年后会处于什么位置?”
另一方面,个人往往更倾向于优化一个他们可以直接优化的目标。大多数机器学习工具都适合这种环境。在这种环境下,开发新功能的工程师可以持续发布新功能。一种机器学习方法(多目标学习)开始着手解决这个问题。例如,可以构建一个约束条件满足问题,为每个指标设置下限,并优化指标的某种线性组合。不过,即使如此,也并非所有指标都很容易构建为机器学习目标:如果用户点击了文档或安装了应用,那是因为系统展示了相应内容。但要想弄清楚用户访问您网站的原因,难度要高得多。如何预测整个网站未来的成功与否,是一个全 AI 范畴的问题,难度与计算机视觉或自然语言处理相当。
规则 40:让合奏保持简单。
接受原始特征并直接对内容进行排名的统一模型是最容易调试和理解的模型。不过,模型集成(即组合其他模型得分的“模型”)的效果会更好。为简单起见,每个模型都应是仅接受其他模型输入的集合模型,或者是接受许多特征的基础模型,但不能同时是这两者。如果您在单独训练的其他模型之上添加了模型,则将它们组合使用可能会导致不良行为。
使用一个简单的模型进行模型集成,该模型仅将“基础”模型的输出作为输入。您还希望对这些集成模型强制执行属性。例如,基准模型生成的得分增加不应降低集成的得分。此外,最好让传入的模型具有语义可解释性(例如经过校准),以免底层模型的更改混淆了集成模型。此外,强制执行以下操作:如果底层分类器的预测概率增加,则不降低该集成的预测概率。
规则 41:当效果出现停滞时,应寻找新的优质信息来源,而不是优化现有信号。
您添加了一些与用户相关的受众特征信息。您已添加了一些与文档中的字词相关的信息。您已完成模板探索,并调整了正则化。在几个季度内,您没有看到任何发布内容的关键指标提升幅度超过 1%。接下来该怎么做呢?
现在,您可以开始为完全不同的功能构建基础架构了,例如,此用户在过去一天、一周或一年内访问过的文档的历史记录,或来自其他媒体资源的数据。使用 wikidata 实体或贵公司内部的某些内容(例如 Google 的知识图谱)。使用深度学习。开始调整您对投资回报率的预期,并相应地加大投入。与任何工程项目一样,您必须权衡添加新功能的好处与增加的复杂性成本。
规则 42:不要期望多元化、个性化或相关性与您认为的受欢迎程度之间存在着密切的相关性。
一组内容的多元化可以有多种含义,其中最常见的是内容来源的多元化。个性化意味着每位用户都会获得自己的结果。相关性意味着,某个查询的结果比任何其他结果都更适合该查询。因此,这三个属性都被定义为与普通属性不同。
问题在于,普通内容往往很难打败。
请注意,如果您的系统衡量的是点击次数、所花时间、观看次数、+1 次数、分享次数等,则表示您在衡量内容的受欢迎程度。团队有时会尝试学习具有多样性的个人模型。为了实现个性化,他们会添加一些特征,以便系统实现个性化(一些特征代表用户的兴趣)或多样化(特征指示此文档是否与返回的其他文档有任何特征相同,例如作者或内容),但发现这些特征的权重低于预期(有时符号也不同)。
这并不意味着多样性、个性化或相关性没有价值。如上一条规则所述,您可以进行后处理以提高多样性或相关性。如果您发现长期目标有所提高,则可以断言,除了热门程度之外,多样性/相关性也很重要。然后,您可以继续使用后处理,也可以根据多样性或相关性直接修改目标。
规则 43:您在不同产品中的好友往往是相同的。您的兴趣通常不会。
Google 的团队通过将在一个产品中预测关联紧密程度的模型用于另一个产品,取得了显著成效。你的好友就是他们自己。另一方面,我发现有几个团队在跨产品部署个性化功能时遇到了困难。是的,应该可以。目前,似乎没有。有时,可以使用一个媒体资源的原始数据来预测另一个媒体资源上的行为。此外,请注意,即使知道用户在其他媒体资源上有历史记录,也可能有所帮助。例如,在两款产品上都存在用户活动本身就可能具有指示性。
相关工作
Google 和外部有很多关于机器学习的文档。
- 机器学习速成课程:应用机器学习简介。
- 阅读 Kevin Murphy 所著的机器学习:概率方法,了解机器学习领域。
- 良好的数据分析:一种数据科学方法,用于思考数据集。
- Ian Goodfellow 等人撰写的《Deep Learning》(深度学习),介绍了如何学习非线性模型。
- Google 关于技术债务的论文,其中包含许多常规建议。
- TensorFlow 文档。
致谢
感谢 David Westbrook、Peter Brandt、Samuel Ieong、Chenyu Zhao、Li Wei、Michalis Potamias、Evan Rosen、Barry Rosenberg、Christine Robson、James Pine、Tal Shaked、Tushar Chandra、Mustafa Ispir、Jeremiah Harmsen、Konstantinos Katsiapis、Glen Anderson、Dan Duckworth、Shishir Birmiwal、Gal Elidan、Su Lin Wu、Jaihui Liu、Fernando Pereira 和 Hrishikesh Aradhye 为本文档提供了许多更正、建议和实用示例。此外,感谢 Kristen Lefevre、Suddha Basu 和 Chris Berg 帮助我们改进了早期版本。如有任何错误、遗漏或(天哪!)不受欢迎的观点,均为我个人的责任。
附录
本文档中多次提及 Google 产品。为了提供更多背景信息,下面我简要介绍了最常见的示例。
YouTube 概述
YouTube 是一项在线视频服务。YouTube“接下来播放”团队和 YouTube 首页团队都使用机器学习模型对推荐视频进行排名。“接下来播放”会推荐在当前播放的视频后观看的视频,而“首页”会向浏览首页的用户推荐视频。
Google Play 概览
Google Play 提供了许多可解决各种问题的模型。Google Play 搜索、Google Play 首页个性化推荐和“用户还安装了”应用均使用机器学习技术。
Google+ 概览
Google+ 在各种情况下都使用了机器学习技术:对用户看到的帖子“信息流”中的帖子进行排名、对“时下流行”帖子(当前非常热门的帖子)进行排名、对您认识的人进行排名,等等。Google Plus 已于 2019 年关闭所有个人账号,并于 2020 年 7 月 6 日被 Google Currents 取代(适用于商家账号)。