作者:黄永刚
本文旨在指引具有机器学习基础知识的工程师等人,更好的从机器学习的实践中收益。介绍一些应用机器学习需要遵循的规则,类似于Google C++ 风格指南等流行的编程指南。如果你已经上过机器学习相关课程或者正在从事相关的工作,那你已经满足阅读本文所需的背景知识了。
算法运行对于数据的时效性有差异,如热榜需要每天更新数据,点击率预估更新部分数据频率更高。
起初的时候,只要选择正确的方法所有指标都会提升,没有必要刚开始对于指标的选择过多考虑。
如评价博文的热度,首选博文近几天的浏览量,而不是博文表达的主题是不是流行。
所以你不能代表用户做判断模型的表现好坏,要做A/B Test。
如果训练特征有一个特征表示博文的浏览量,那么等到模型训练完,浏览量已经发生变化了。
要做出好的产品:用优秀工程师的做法去做机器学习,而不是优秀机器学习专家那样。
你将面对的大多数问题事实上是工程问题。即使让所有优秀的机器学习专家来做,性能的提升大多还是来自好的特征,而不是好的机器学习算法。所以,基本的方法是:
1. 确保管道可靠2。
2. 开始于一个合理(reasonable)的目标。
3. 用直观简单的方式添加经验性的特征。
4. 确认管道依然可靠。
当没有简单的方法可以使用了的时候,需要使用一些尖端的机器学习方法,可以参考第三部分。
这篇文章将会分为四个部分:
1. 第一部分将帮助你理解是否需要建立一个机器学习系统。
2. 第二部分关于部署你的第一个管道(Pipeline)。
3. 第三部分关于系统的启动,当新特征加入系统时迭代,如何评估模型及训练和服务之间的偏差。
4. 最后关于当系统停滞不前该如何处理。
5. 之后,罗列一些相关的例子。
机器学习很炫酷,但是它需要数据。理论上,你可以从不同的问题中获得数据,之后为新产品调教出模型,但是这个效率就低于基础的启发式规则方法。如果机器学习可以给你100%的提升,那么启发式规则方法起码将得到50%。
举例来说,如果你要对应用市场中的APP进行排序,你可以使用安装量或者安装率。如果判断是否为垃圾邮件,过滤掉发送过垃圾邮件的地址。不要担心使用人工规则。如果你需要对联系人排序,按照联系频次排序或者字母顺序排序。如果你的产品不是完全需要机器学习,就不要使用它,除非你有充足的数据。
在规划机器学习要做什么之前,记录当前使用的系统中尽可能多的信息。原因有以下几点:
1. 从老系统用户处获取认可更容易一些。
2. 对你认为将来有用的信息,最好现在开始记录。
3. 如果你设计系统的时候,在心里已经有了对效果的衡量,那么以后的事情就会越来越好了。尤其,当你不希望自己去系统日志中寻找信息来实现你的度量指标时候。
4. 你将能够注意到那些发生了变化哪些被保留了下来。举例来说,假如你在优化日活人数,基于老系统的操作情况,你或许注意到,用户体验的较大变化不会对此造成影响。
Google plus 团队统计了每个用户的阅读量、转发量、评论量等,他们利用这些来计算Post的质量。也可以用在整个实验当中,通过将用户分组,分组计算这些指标,这是非常重要的,原因参见Rule #12
多获取指标,你可以对你的系统有一个更宽泛的认识。如果发现问题,则增加一个指标对其进行跟踪。如果对最后一版的数量变化感兴趣,那就增加一个指标进行跟踪就好了。
一个简单的启发式规则就可以使你的产品上线了。复杂启发式的系统很难维护,因此,一旦你有了数据,并对将要完成的事情有了基本的理解,就可以上机器学习了。如多数软件工程任务一样,无论是启发式规则还是机器学习方法,你都想持续的对它进行更新。你将会发现机器学习模型更加容易更新和维护。(参见Rule #16)
开发第一版系统时将精力集中在系统结构上。思考将要构建整个机器学习系统,是一件很有趣的事情。但刚开始就不能有一个可靠的系统信息流(pipeline),对于明白系统到底发生了什么将是一件困难的事情。
第一版模型对于产品的提升是最大的,并不需要过多的考虑。但是在系统结构方面,遇到的困难比你预想的更大。在推出新的机器学习系统之前,你必须考虑一下事情:
1. 算法学习所需的数据如何得到。
2. 要大致的明白对于你的系统什么意味着好,什么意味坏。
3. 如何将你的模型融合进你的应用中。要么在线应用模型,要么提前进行离线计算,将结果存到一张表里面(译注:离线计算或实时计算)。举例来说,通常是离线对网页进行分类,然后将结果存在表格里;或许也需要实时的对在线聊天信息进行分类。
选择简单的特征,这会使得以下事情的保证更加容易:
1. 在算法里,正确的使用各个特征。
2. 模型可以学习到合理的权重。
3. 模型使用的特征在上线服务阶段也是正确的。
一旦你的系统在这三个方面是可靠的,你大部分工作就已经完成了。你这个简单模型也可以作为基准以方便尝试更加复杂的模型。一些开始就尝试复杂模型的团队在刚开始也会将从机器学习中获取收益的优先级调低,以避免混乱。
确保系统结构是可以测试的,而且对于系统来说学习算法部分是封装着的,以便对其中的所有方面进行测试。尤其一下方面:
1. 对获取数据并送入算法进行测试。检查特征的频度是否被继承了下来。如果允许,可以手动的去检查训练算法的输入。如果可以,统计系统流中的数据信息并和其他场景进行对比。
2. 对于模型从训练算法中进行抽取进行测试。确保算法在实验环境和生产环境中能够能到相同的效果(参见Rule #37).
机器学习有不可预测的一面,因此确保你已经对训练阶段和线上服务阶段的代码进行了测试;而且要保证在服务阶段能够将一个修正后的模型重新加载进来并工作正常。这对于理解你的数据是非常重要的:参见大规模复杂数据分析的实践建议。
我们经常开发pipeline时候,将原pipeline拷贝过来,但有时候原pipeline不需要而丢弃的数据在新的pipeline里面却是很有用的。Google plus 计算热榜的时候会将旧post丢弃(尝试计算出当前新的post)。这个pipeline就被拷贝之后用在了Google Plus Stream中,旧post仍然被丢弃掉了,然而在这个场景中旧post是很有用的。另一种普遍的场景,用户可见的历史记录,如果我们要对是否要展示特殊的post进行建模,那么所有的数据都是有用的,然而所有的负面post已经被删除掉了(译注:对判断帖子内容是否违规进行建模与删帖)。另一个相似的问题发生在工作Play Apps Home期间,开发的新pipeline包含了来自两个不同起始页的样例(Play Games Home and Play Home Home),没有任何特征对来源进行标识和区分。
通常机器学习尝试解决的问题大多不是完全的新问题。,应该已经存在了一个系统来做分类或者排序等,任何你正在尝试解决的问题。这意味着已经有了一套规则和方法。这些方法对于你调节机器学习具有极大的帮助作用。相对于已有信息,需要探索的信息就比较少了,原因有两点,第一,系统之间的过度比较顺利不会出现大的变动;第二,原系统的规则包含了很多对于业务的认知,这些东西你不会愿意推倒重来。这里有四种方法利用已存的知识:
1.使用原方法进行预处理。如果一个特征非常好,那么可以选择。举例来说,在垃圾邮件过滤中,如果一个邮件发送者已经进了黑名单,那么就不要再尝试重新学习获得黑名单了,直接拒收这些信息。这个方法在二值分类任务中非常重要。
2. 新建特征。直接将原方法处理的结果作为一个特征加入当前算法。例如,如果你使用原方法计算查询的相关性评分,你可以将计算的评分作为一个新的特征的值。之后运用机器学习的处理方法对这个值进行微调(如离散化或者和其他特征结合),但开始的时候可以不处理直接使用原始值。
3. 挖掘原方法的输入。如果对于APP原处理方法输入包含安装量、文本特征数、周活跃天数,那么可考虑单独的抽取去这些部分,分别应用到学习算法的输入中。应用集成方法的技巧可参考Rule # 40
4. 改变标签。如果你觉得当前的标签没有标识原方法捕获到的信息,这个方法就可以考虑。例如,如果你正在优化下载量,但你也想保证内容的质量,那么或许你可以将标签乘以每个APP获得星的平均数。这里有很多空间可以发挥。可参考 “Your First Objective” 部分。
使用原方法对于整个机器学习系统来讲增加了系统的整体的复杂度,这一点你要能清晰的认识到。在新的机器学习系统中使用原方法可以使系统的过渡比较平滑,但是可以考虑一下是否有更加简单的方法实现相同的结果。
通常,对于数据质量的预警非常必要,如可控的预警行为及控制界面(dashboard page)。
如果你模型数据都是前一天的,这到底对于性能的影响有多大?那一周前的呢?一个季度?这些信息会帮助你理解监控的重要性,如果模型有一天的滞后而损失了10%的收益,那么委派工程师进行持续的观察就十分必要了。大多的广告服务系统每天要处理很多的新广告,必须每天进行更新。例如,如果Google Play的搜索ML模型没有更新,那么月收益就会收到影响;如果Google Plus的热榜模型没有新的post识别特征,那么模型抽取的频率就会下降。其他具有这些新特征的模型就会更新的很快。随着时间的变化,模型对于数据新鲜度的要求也会发生变化,尤其当一些特征被加进来或者被剔除的时候。
很多机器学习系统在抽取模型并上线提供服务的时候都有这个阶段。如果抽取的模型存在问题,这可是直接面向用户的。如果这个问题以前就有,那就是训练问题,当然用户也不会注意到的。
在模型抽取之前做合理性检查。尤其要确保模型在提取出的数据中表现是合理的;要不,如果你还在考虑数据,那就不要抽取模型。很多团队抽取模型之前都会利用AUC进行检查。没有抽取之前的模型,针对可能存在的问题做一个邮件预警就可以,但是如果是已经直面用户的模型的问题就需要做一个页面了。所以在直面用户之前最好不要着急,慢慢来。
这个问题相比较于其他类型的系统中,在机器学习系统中发生的更加频繁。假如要用到一个不会被更新的表,机器学习系统会自己调节,进而产生的行为看起来也挺合理,只不过会缓慢的过时。过了一段时间发现很久没有更新了,然后更新了一下,或许获得的性能提升比其他花了一个季度工作时间的提升都要大。例如,一个特征的覆盖率根据实现的变化会发生变化:一个特征一直覆盖率90%,忽然降到了60%,一次Google Play有一个6个月的旧表,单独的更新了这个表就在安装率上获得了2%的提升。如果你一直跟踪数据的统计信息,或者随机的手动检查这些数据,就能减少类似的失败发生。
如果系统非常庞大,有很多的特征,要知道谁创建和维护每个特征。如果某个特征的负责人员要离职,那么确保其他人知道这个事情。虽然每个特征都有其特定的名称,但是最好还是给出一个特征的详细说明出来,阐述一下从哪里获取,有什么样的作用。
应用场景有很多的关系的计量指标,但你的机器学习算法通常只需要一个来进行优化。这里要区分一下指标和目标,指标是关于你系统报告的一个数值,或许重要或者不重要。参考 Rule #2.
你想多赚钱,想增加用户体验,想世界变得更加美好。有太多关心的衡量指标,你应该对这些进行衡量。然而机器学习过程的开始阶段,你会发现所有指标即使你没有直接优化的,也会一起上升。例如,你关心点击量、用户逗留时间、日活跃用户量。如果优化点击数,你可能会发现用户逗留时间也在增长。
所以,当你还可以较早的提升所有指标的时候,简单点不要过多的考虑不同衡量指标之间的权衡。当然,也不要将这个方法一直贯彻下去,以免扰乱了你最终的目标:整个系统最终的表现(参见Rule #39)。如果你发现自己提升了直接的优化指标,但决定了不向外推出这个模型,那么优化目标的改变就很必要了。
通常你并不知道真正的目标是什么。你会认为你自己知道,然后盯着数据,同时去分析新旧两个系统,你认为你该调整它。还有,不同的小组成员在真正的目标上是不能达成共识的。机器学习的目标应该是容易度量的,是真正的目标的一种间接指标。所以,在简单的目标上进行训练,然后考虑在这个模型之上加上一个‘逻辑层’,可以允许你添加一些逻辑(期望是简单逻辑)进去用于做出最终的排序。
对于行为相关的系统,模型可用的可直接观察和可归因的最简单的就是用户行为了:
1. 排序的链接是否被点击?
2. 排序的对象是否被下载?
3. 排序的对象是否被转发/回复?
4. 排序的对象是否被评价?
5. 展示的内容被标识为垃圾/色情/侮辱?
首先应该避免对间接的效果进行建模:
1. 明天用户是不是继续访问?
2. 用户多久访问一次?
3. 日活跃用户到底是些什么人?
间接效果可以是很好的指标,可被用在A/B测试中或者判断模型是否应该上线中。
最后,不要尝试使用机器学习来搞清楚:
1. 用户使用产品是否高兴?
2. 用户的产品体验是否满意?
3. 产品是否提高了用户的整体幸福感?
4. 这个怎么影响整个公司的形象?
这些东西也重要,但是也太不可思议了。因此,使用间接指标:如果一个用户高兴,它在站点的滞留时间就越久。如果用户满意,它很可能明天继续访问。对于用户的幸福感和公司的形象,就需要人为的判断了,产品的本质好坏,公司的计划等。
线性回归、逻辑回归、泊松回归都来源于概率模型。每预测都可以被理解为一种概率或者期望值。这使得它们debug比其它使用如0-1损失、hinge losses等更加容易,它们直接优化的是分类精度或者排序性能。例如,如果训练结果概率不同于其它预测是概率,这就说明存在问题了。
例如,在线性回归、逻辑回归、泊松回归中,有一部分数据预测值的期望均值等于标签的平均值。如果一个实例的特征是0-1特征,则特征是1的实例就被校准。如果所有实例的某个特征都为1,则需要对所有实例进行校准了。
简单模型容易处理反馈循环。(参考 Rule #36)
我们经常用预测的概率来做决策,如利用排序降低的期望值(如点击概率/下载概率)来对posts进行排序。然而,当选择哪个模型的时候,决策本身要比模型数据的概率似然度更加重要(参考 Rule #27)。
质量排序是高端艺术,而垃圾邮件过滤是a war。确定post质量使用的信息对于经常使用该系统的人来说很明显。他们很容易调整他们的posts来适应这个系统。因此,你的系统应该关注在正常内容的排序上,不应该对给予垃圾信息的算法进行降权。同样,关于种族歧视的内容不应该是质量排序关注的范围,应该被独立出来进行处理。垃圾邮件过滤就不同了。你希望产生的特征一直变化,通常系统的规则很明显(如果一个post被超过三个算法判定为垃圾邮件,就不要检索它等)。这些模型必须每天进行更新,如果更新的慢,那么内容的创作者的名声等稳定特性将会成为系统的主要判断因素了。
某些层面,这两个系统的输出不得不进行整合。请记住,在搜索结果中过滤垃圾信息应该比垃圾邮件过滤的策略更加激进。从训练数据中移除垃圾信息,对于信息质量分类,这是公认的标准化处理流程。
reference:
- http://feisky.xyz/machine-learning/resources/rules_of_ml.html
- Rules of Machine Learning: Best Practices for ML Engineering