机器学习法则:ML工程的最佳实践
机器学习法则:ML工程的最佳实践
作者:无邪
机器学习研究者,人工智障推进者。
Martin Zinkevich 在 2016 年将 Google 内部多年关于机器学习相关的经验分享了出来。本文是对该分享的翻译 + 解读。
原文参见:https://developers.google.com/machine-learning/rules-of-ml/
术语
在说到具体的相关经验之前,先来了解下常用的术语。
- 示例(Instance):那些你要为其做出预测的事物称为示例。例如,示例可能是一个网页,你要将其归为“关于猫的”网页或者“不是关于猫的”网页。
- 标签(Label):预测任务的答案或结果称为标签。无论是机器学习系统的答案或结果,还是训练数据的答案或结果,都可以称为标签。例如,将网页标记为“关于猫的”。
- 特征(Feature):预测任务中示例的属性即为“特征”。例如,网页可以有“包含词汇‘猫’”的特征。
- 特征栏(Feature Column):特征栏是相关特征的集合,如用户所住地区存在的所有可能国籍的集合。在同一个样本的同一个特征栏中可能有一个或多个特征。特征栏相当于(雅虎或微软的)虚拟机系统的 “命名空间(namespace)”或“域(field)”。
- 样本(Example):样本包含示例(具有各种特征)和一个标签。
- 模型(Model):模型是预测任务的数学表达形式。先是通过样本训练模型,而后利用模型做出预测。
- 指标(Metric):指标是指一系列的数字,这些数字直接或间接的都被优化过。
- 目标(Objective):目标是指算法经过优化,努力要达到的度量标准。
- 工作流(Pipeline):工作流指的是围绕机器学习算法而存在的基础架构。从前端搜集数据、将搜集到的数据放入训练数据文件夹、训练一个或多个模型以及将模型用于生产等过程,都属于工作流。
- 点击率(Click-through Rate):用户浏览网页时对包含广告链接的点击次数占浏览次数的百分比。
概述
要想创造出优秀的产品:
你需要以一位优秀工程师的身份去运用深度学习!记住!你不单单是一位机器学习的研究者!
事实上,你所面临的大多数问题都是工程问题。即便拥有足以媲美机器学习专家的理论知识,要想有所突破,大多数情况下都在依赖示例的良好特征,而非优秀的机器学习算法。因此,基本方法如下:
- 确保你的工作流各连接端十分可靠
- 从树立合理的目标开始
- 用简单的方式,添加符合常识的特征
- 确保你的工作流始终可靠
这种方法能带来相当多的盈利,也能在较长时间里令许多人都满意,甚至还可能实现双赢。只有在简单技巧不发挥任何作用的情况下,才考虑使用更复杂的方法。方法越复杂,产品最终输出速度越慢。
当所有的简单技巧用完后,很可能就要考虑最前沿机器学习术了。
本文档主要由四部分组成:
- 帮助你明白是否到了需要构建一个机器学习系统
- 部署你的第一个工作流
- 往工作流增加新特征时的发布和迭代,以及如何评价模型和训练-服务倾斜(training-serving skew)
- 达到稳定阶段后该继续做什么
在机器学习之前
Rule #1: Don’t be afraid to launch a product without machine learning.
法则 1: 不要害怕发布一款没有用到机器学习的产品
机器学习是很酷,但它需要数据。如果你认为机器学习可以提高 100% 收益,那么启发式规则可以获得 50% 收益。
Rule #2: First, design and implement metrics.
法则 2:首先需要设计和实现评估指标
在构建具体的机器学习系统之前,首先在当前系统中记录尽量详细的历史信息。原因如下:
- 在早期,更容易获得系统用户的权限许可(获得系统用户权限后,更容易收集各种数据)。
- 如果你觉得某个问题以后会受到关注,最好是从现状开始就搜集历史数据。
- 如果设计系统的时候考虑了评估指标,这对将来会大有益处。具体来说,这是为了让你以后不用在日志文件中寻找相关的字符串。
- 你能够注意到什么(随着时间)改变了,什么(随着时间)没有改变。举个例子,假设你想要直接优化一天的活跃用户量。然而在早期对系统的处理中可能会发现用户体验的变化并没有显著改变活跃用户量的度量。
Rule #3: Choose machine learning over a complex heuristic.
法则 3:优先选择机器学习而不是复杂的启发式规则
简单的启发式方法可以轻松应用到产品上,而复杂的启发式方法却难以维护。一旦你拥有了足够的数据,并且对要实现的目标有了基本的概念,那就转向机器学习吧。在大多数软件工程中,不管使用的是启发方法还是机器学习模型,都需要经常更新算法。但是你会发现,使用机器学习的模型更容易更新和维护。
机器学习阶段 1:第一条工作流
构建第一个机器学习工作流时,一定要更多关注系统基础架构的建设。虽然机器学习的算法令人激动,但是因为基础架构不给力找不到问题时会令人抓狂。
Rule #4: Keep the first model simple and get the infrastructure right.
法则 4:第一个模型要简单,但是基础架构要正确
第一个模型对你的产品提高最大,因此它不需要有多花哨。相反,你会碰到比你想象的多的基础架构方面的问题。在别人使用你的新机器学习系统前,你需要确定:
- 如何为你的学习算法得到样本
- 为你的系统初步定义“好”与“坏”的标准
- 如何将模型集成到应用程序中。你可以直接将模型应用到在线应用程序中,也可以在离线样本的基础上对模型进行预计算(pre-compute),然后把预计算的结果储存在表格中。
选择简单的特征,这样会更容易确保:
- 特征正确应用到算法中
- 模型能够学习到合理的权重
- 特征正确应用到服务器模型(也就是生产环境的模型)中
你的系统如果能够可靠地遵守这三点,你就完成了大多数工作。你的简单模型能够提供基准指标和基准行为,你可以用来测量更加复杂的模型。
Rule #5: Test the infrastructure independently from the machine learning.
法则 5:独立于机器学习来测试架构流程
不仅需要确保基础架构的可测试性,还需要确保系统的学习部分(learning part)是封装好的(encapsulated),这样才能测试所有与之相关的部件。具体来说:
- 测试输入到算法中的数据。检查应该填充的特征栏是否正确填充。
- 测试模型在训练算法之外的运行情况。确保模型的训练环境中和服务环境中的得分相同。
机器学习的一个特点就是不可预测性。因此,你必须确保在训练和实际运行中创造样本的代码能被测试,并且在实际运行中始终使用同一个固定的模型。
Rule #6: Be careful about dropped data when copying pipelines.
法则 6:复制工作流时留意丢失的数据
我们有时候会通过复制已经存在的工作流来创建一个新的工作流。在新的工作流中需要的数据,很可能在旧的数据流就丢弃了。
Rule #7: Turn heuristics into features, or handle them externally.
法则 7: 将启发规则转化为特征,或者在外部处理它们
机器学习系统解决的问题通常都不是新问题,而是对已有问题的进一步优化。这意味着有很多已有的规则或者启发式规则可供使用。下面是几种启发式规则可以被使用的方式:
- 用启发式规则进行预处理。若特征相当完美,则可以采用这个方法。例如,在垃圾邮件过滤器中,如果发件人已经被加入黑名单了,则可以直接阻止该信息。
- 创建特征。直接从启发式规则中创建特征会很便捷。例如,若要用启发式规则为某个查询结果计算相关度,你可以把分数纳入特征的值中。
- 挖掘启发式方法的原始输入数据。对于某款 app,若存在一个启发式方法,其包含安装量、文本字符数和当天日期等要素,可以考虑将这些原始信息单独作为特征使用。
- 修改标签。当你发觉启发式方法捕捉了一些信息,而这些信息没有包含在标记中,这时可以考虑该选项。例如,如果你想让下载量达到最大,但同时对内容的质量有要求,那么可以用 app 的平均评级乘以标记来解决问题。
监控
一般来说,所有系统都要设置良好的警示程序,警报系统需要顺利执行,或者设置一个仪表板页面(dashboard page)。
Rule #8: Know the freshness requirements of your system.
法则 8: 了解你系统对新鲜度的要求
如果你使用的是一天前的旧模型,运行状况会下降多少?如果是一周前的呢?或一个季度前的呢?知道何时该刷新系统能帮助你划分监控的优先级。如果你的模型一天没有更新,受益便下降 10%,因此有必要指派一名工程师时时关注它的动态。大多数广告服务系统每天都会有新的广告需要处理和更新。此外,要留意系统对新鲜度的要求会随着时间变化,特别是在添加或移除特征栏的时候,需要尤为注意。
Rule #9: Detect problems before exporting models.
法则 9: 输出(发布)模型前发现问题
许多机器学习系统都存在这样一个阶段:直接把模型输出运行。如果问题出现在模型输出之后,那么这个问题就是用户所面临的问题。而如果问题出现在模型输出之前,就是训练过程中的问题,用户不会发现。
输出模型之前请做好完整性检查(sanity check)。具体来讲,确保模型在留存数据上运行合理,例如 AUC。
Rule #10: Watch for silent failures.
法则 10:注意隐藏性故障
比起其它系统,机器学习系统更容易出现潜在的问题。假设系统的某个特定的表格不再进行更新,整个系统通过调整仍会保持良好的运行水准,但是会慢慢衰减。有时有些表格几个月都不会刷新一次,而只需简单的刷新就能大幅度提升系统的运行水准,效果甚至超过该季度最新发布的那些模型!
例如,由于系统实现(implementation)发生变化,特征的覆盖范围也会发生相应的变化:比如,某个特征栏刚开始可能包含 90% 的样本,接下来却可能突然下降到 60%。解决方法是对关键数据的统计信息进行监控,并且周期性对关键数据进行人工检查。
Rule #11: Give feature columns owners and documentation.
法则 11:为特征栏指定负责人并记录文档
如果系统的规模比较大,并且特征栏比较多,那么必须清楚每个特征栏的创建者或者维护者。如果某个了解该特征栏的人离开了,一定要确保另外还有人了解这部分信息。虽然很多特征栏的名字非常直观,但最好还是使用更详尽的文档来描述这些特征的内容、来自哪里以及它们的作用。
你的第一个目标(Objective)
objective 是模型试图优化的值,而 metric 指的是任何用来评估系统的值。
Rule #12: Don’t overthink which objective you choose to directly optimize.
法则 12: 不要过于纠结该优化哪个目标
你有成千上万关心的指标,这些指标也值得你去测试。但是,在机器学习过程的早期,你会发现,即使你并没有直接去优化,他们也都会上升。比如,你关心点击次数、停留时间以及每日活跃用户数。如果仅优化了点击次数,通常也会看到停留时间增加了。
所以,当提高所有的指标都不难的时候,就没必要花心思来如何权衡不同的指标。不过过犹不及:不要混淆了你的目标和系统的整体健康度。
Rule #13: Choose a simple, observable and attributable metric for your first objective.
法则 13:选择一个简单、可观测并且可归类的评估指标(metric)作为你的第一个目标(objective)
最容易建模的是那些可以直接观察并可归属到系统的某个动作的用户行为:
- 排序的链接被点击了吗?
- 排序的物品被下载了吗?
- 排序的物品被转发/回复/邮件订阅了吗?
- 排序的物品被评价了吗?
- 展示的物品是否被标注为垃圾/色情/暴力?
最开始要避免对间接效果建模:
- 用户第二天会来访吗?
- 用户访问时间是多长?
- 每日活跃用户是什么样的?
间接效果是非常重要的指标,在 A/B test 和发布决定的时候可以使用。
最后,不要试图让机器学习来回答以下问题:
- 用户使用你的产品是否开心
- 用户是否有满意的体验
- 产品是否提高了用户的整体幸福感
- 这些是否影响了公司的整体健康度
这些都很重要,但太难评估了。与其如此,不如考虑其他代替的:比如,用户如果高兴,那停留时间就应该更长。如果用户满意,他就会再次造访。
Rule #14: Starting with an interpretable model makes debugging easier.
法则 14:从容易解释的模型入手会让调试过程更加容易
线性回归、逻辑回归和泊松回归直接由概率模型激发。每个预测可解释为概率或期望值。这使得他们比那些使用目标来直接优化分类准确性和排序性能的模型要更容易调试。
Rule #15: Separate Spam Filtering and Quality Ranking in a Policy Layer.
法则 15:在策略层将垃圾信息过滤和质量排名分开
质量排名是一门艺术,而垃圾过滤是一场战争。那些使用你系统的人非常清楚你采用什么来评价一篇帖子的质量,所以他们会想尽办法来使得他们的帖子具有这些属性。因此,质量排序应该关注对哪些诚实发布的内容进行排序。
机器学习阶段 2:特征工程
在机器学习系统研发周期的第一阶段,重点是把训练数据导入学习系统,得到感兴趣的评价指标,并创建基础架构。当你有了一个端对端的系统,并且该系统的单元和测试都仪表化之后,第二阶段便开始了。
第二阶段需要纳入尽可能多的有效特征,并依据直观的感觉组合起来。在这个阶段,所有的评估指标仍然会上升。
Rule #16: Plan to launch and iterate.
法则 16:做好持续迭代上线的准备
不要期望现在发布的这个模型是最终的模型。因此,考虑你给当前这个模型增加的复杂度会不会减慢后续的发布。许多团队每季度推出一个模型或者更多年。之所以不断发布新模型,有三个基本原因:
- 你会不断地想到新的特征。
- 你会不断地调整并以新的方式组合旧的特征。
- 你会不断调优目标。
Rule #17: Start with directly observed and reported features as opposed to learned features.
法则 17:优先使用直接观测或收集到的特征,而不是学习出来的特征(learned features)
先描述一下什么是学习出来的特征(learned features)。学习出来的特征是由外部系统(比如无监督聚类系统)或学习者本身(比如因子模型、深度学习)生成的特征。两种方式生成的特征都很有用,但也有很多问题,因此不应当用在第一个模型中。
Rule #18: Explore with features of content that generalize across contexts.
法则 18:探索使用可以跨场景的内容特征
通常情况下,机器学习只占到一个大系统中的很小一部分,因此你必须要试着从不同角度审视一个用户行为。
Rule #19: Use very specific features when you can.
法则 19:尽量使用非常具体的特征
在海量数据的支持下,即使学习数百万个简单的特征也比仅仅学习几个复杂的特征要容易实现。
Rule #20: Combine and modify existing features to create new features in human–understandable ways.
法则 20: 用人类可理解的方式对已有特征进行组合和修改
有很多种方法组合和改良特征。像 TensorFlow 这样的机器学习系统,它允许通过 transformations 预处理数据。其最标准的两种方法分别是“discretization(离散化)”和“crosses(叉积)”。
- Discretization:根据一个连续的特征创建许多离散的特征。
- Cross:由两个或多个特征栏组成。会产生庞大的特征栏,有可能导致过拟合现象。
Rule #21: The number of feature weights you can learn in a linear model is roughly proportional to the amount of data you have.
法则 21:线性模型中的特征权重的数量应大致和样本数量形成一定的比例
Rule #22: Clean up features you are no longer using.
法则 22:清理不再使用的特征
当决定要清除哪些特征时,需要考虑其覆盖率,即该项特征覆盖了多少样本。
系统的人工分析
在进入机器学习第三阶段前,有一些在机器学习课程上学习不到的内容也非常值得关注:如何检测一个模型并改进它。这与其说是门科学,还不如说是一门艺术。
Rule #23: You are not a typical end user.
法则 23: 你并非典型终端用户
Rule #24: Measure the delta between models.
法则 24:测量模型间的差异
Rule #25: When choosing models, utilitarian performance trumps predictive power.
法则 25: 选择模型时,性能表现比预测力更重要
Rule #26: Look for patterns in the measured errors, and create new features.
法则 26: 在错误中寻找规律,然后创建新特征
Rule #27: Try to quantify observed undesirable behavior.
法则 27:尝试量化观察到的异常行为
Rule #28: Be aware that identical short-term behavior does not imply identical long-term behavior.
法则 28:短期行为相同并不代表长期行为也相同
训练偏差(Training–Serving Skew)
训练偏差是指训练时的表现和在生产环境中实际运行时的表现的差别。
Rule #29: The best way to make sure that you train like you serve is to save the set of features used at serving time...
法则 29:要让实际产品和训练时表现一样好,最好的方法是实际运行中保留特征集,并记录到日志中以便训练中使用
Rule #30: Importance-weight sampled data, don’t arbitrarily drop it!
法则 30:给抽样数据按重要性赋权重,不要随意丢弃它们
Rule #31: Beware that if you join data from a table at training and serving time, the data in the table may change.
法则 31:如果要从表格中组合数据,注意训练时和实际运行时表格可能发生改变
Rule #32: Re-use code between your training pipeline and your serving pipeline whenever possible.
法则 32: 尽量在训练流和实际运行流中使用重复代码
Rule #33: If you produce a model based on the data until January 5th, test the model on the data from January 6th and after.
法则 33: 如果训练数据是1月5日之前的,那么测试数据要从1月6日开始
Rule #34: In binary classification for filtering... make small short-term sacrifices in performance for very clean data.
法则 34:在过滤类的任务中……为了干净数据,可牺牲短期性能
Rule #35: Beware of the inherent skew in ranking problems.
法则 35: 注意排序问题存在固有偏差
Rule #36: Avoid feedback loops with positional features.
法则 36:用位置特征来避免反馈回路
Rule #37: Measure Training/Serving Skew.
法则 37: 衡量训练和服务之间的差异
机器学习第三阶段:放慢速度、优化细化和复杂的模型
一般会有一些明确的信号来标识第二阶段的尾声。首先,每月的提升会逐步降低。你开始在不同指标之间做权衡,有的上升有的下降。
Rule #38: Don’t waste time on new features if unaligned objectives have become the issue.
法则 38:如果目标没有达成一致,就不要在新特征上浪费时间
Rule #39: Launch decisions are a proxy for long-term product goals.
法则 39:模型发布决策是长期产品目标的代理
Rule #40: Keep ensembles simple.
法则 40: 保持模型集合(ensembles)的简单性
Rule #41: When performance plateaus, look for qualitatively new sources of information to add rather than refining existing signals.
法则 41:当效果进入瓶颈期,寻找本质上新的信息源,而不是优化已有的信号。
Rule #42: Don’t expect diversity, personalization, or relevance to be as correlated with popularity as you think they are.
法则 42:不要期望多样性、个性化、相关性和受欢迎程度之间有紧密联系
Rule #43: Your friends tend to be the same across different products. Your interests tend not to be.
法则 43: 在不同的产品中,你的朋友可能相同,但兴趣却不尽然