互联网公司和软件公司最大的不同在于,即使对于技术团队来说,开发工作也只是一小部分工作,如何使得整个系统运营起来,才是重头戏,这是过去一年感悟最深的一点;而对于像广告质量这样的技术团队来说,运营和开发可以说是完全不可分离的。过去一年,在这点上,走了很多弯路,犯了很多错误,有很多可以总结的地方。从Quora上看到这样一个问题,“What are the keys to operationalizing a machine learning ranking system from an organization / engineering management point of view?”
觉得唯一的一个回答就很好,翻译一下以记之,虽然做不到信达雅,但是基本意思应该能描述对。
这个问题的大概内容是这样的:
如果从组织管理/工程管理的角度来看,什么是将一个机器学习的Ranking系统运营起来的关键点?
对于那些有基于机器学习或者其他方式有Ranking系统的组织,可以保证他们运行平稳,并且随着时间的推移慢慢进步?哪些监控是重要的?如何定义目标,目标由谁来定义?如何分辨效果的提升来自于Feature工程团队还是核心算法上的提升?哪些严重依赖于Ranking的组织如何为这些来构造他们的流程?
目前唯一可见的回答,来自前Google的工程师Brandon Ballinger:
我之前在Google做语音识别和广告,这两者都以机器学习作为他们的核心。下面是我从“野外”学到的如何运营一个机器学习系统的一些重要的经验和教训
- 将你的成功的指标定义为让用户高兴。传统的精确性的指标,比如precision, square error, ROC等等并不能捕捉到那些你真正关心的——用户对于你的模型是如何反应的。例如,如果你运营一个广告系统,你的指标应该是每个PV的收入以及点击率。完全有可能,由于辛普森悖论,你有一个error rate减少了的模型,但是他带来的收入却降低了。
- 核心指标下降是很严重的问题。你需要把核心指标的大幅下降当成和一个服务器当机或者数据库中数据损坏一样严重的问题。Oncall的人需要尝试尽快诊断问题,并且必要时把别人拉进来一起解决问题
- 对每次Model的Launch做A/B测试。你应当始终并行运行两个模型,给不同的用于用不同的模型,然后比较用户行为。这是唯一可以确保你知道你在做正确的事情的办法。
- 小心丑小鸭效应。机器学习系统会在从自己的错误中学习的过程中变得更加准确。这意味着,新的模型有一个与生固来的缺陷:你的历史训练数据包含着过去模型中的错误,但不是你新训练的模型的错误。导致你的新模型一开始可能像一个丑小鸭,但是如果你用他来决策用户看到的内容,他最后会变成一个漂亮的天鹅。你可以通过将一小部分流量切给新模型,来部分抵消丑小鸭效应,然后慢慢随时间提高这个百分比。
- 使得算法对于噪声Feature健壮。类似于L1 regularization这样的技术可以使得你的机器学习算法对Feature进行剪枝,修剪掉那些对于预测的准确性贡献很小的Feature。这可以帮助你很好地拆分你的团队:一些人专注于算法,另一些人写Feature喂给算法。那些寻找Feature的人,可以直接“把东西扔进锅里”,然后让算法找出他们究竟好还是不好。(类似的,你应该通过确保合理的收敛性来选择一个算法)
- 你可以部分地将架构和算法团队解耦合。基本上,大部分机器学习算法都是在累计一个分布式的hash table的统计信息,然后将这些统计信息合并成一个分数。开发一个分布式的hash table是和开发一个用于累计的算法不同的任务,可以由不同的子Team完成。然后,让这些人一起工作仍然是很重要的。例如,一些算法在写入和写入可用之前延时的“最终一致”的系统中(例如Dynamo),会有所波动。所以这只是一个部分解耦合,你仍然需要团队中有连接架构和算法的“桥梁”人员。
- 在在线系统和批处理系统之间选择的时候要小心。一个在线系统可以实时学习,对于新的用户行为,可以在发生之后的几分钟内有所反应。但是这回带来巨大的开销,一个在线系统需要2-3倍的时间区开发和维护,而且他对瞬间的变化更加敏感。举个例子,如果你突然接收到了很多垃圾信息,这些噪声会立刻被吸收进你的系统并且开始降低用户的体验。类似的,一台机器如果没有可运行的内容了,如果网络连接中断了,或者一个特定的机器变慢了(导致Feature“歪了”),模型的某个输入开始生产垃圾,等等。
- 为所有东西打上版本。一个训练过的模型依赖于稳定的标识,如果你更改了某个标识,模型立刻就过时了。例如,如果你将用户的语言(“en-us”)作为一个feature。那么当有些人提交了一个一行的修改,用下划线替换了短横线(“en_us”)。这使得模型立刻“忘记”了所有从”en-us”中学到的,使得所有的语言看起来都是一样的。所以为所有会在你模型中生成标识的代码和数据的变更都打上版本。
- 你需要咬碎100-1000倍于实时的数据。如果你的训练数据来自于整整一年的历史数据,然后你的学习过程是10倍于实时,那他需要一个月来测试一个新Feature。把所有的东西都写成Map-Reduce或者Storm Topology使得你可以在数据变得足够大的时候仍然可以扩展。
看了一下,里面有不少错误我们都犯过,包括过去一个Q我们觉得由于团队小应该快点冲而省略掉的东西,现在看来也还是省略不掉的,而之前做对的部分也都是来自老大们的经验,希望今年少走弯路效果好啊。
两个笔误:
“…这意味着你的心魔性一开始可能像一个丑小鸭…”
心魔性 => 新模型
“…使得你可以在数据变得足够达的时候可以扩展…”
达 => 大
you should try to pick an algorithm with reasonable convergence guarantees
“你可以通过合适的收敛保障来选择一个算法”
这样翻可能更好理解:你应该选择一个保证合理收敛的算法。
丑小鸭效应的一节,第一遍没看明白……看了一下英文,是不是这个意思:
新秀光训练是不够的,还得上场实战。但新秀会犯错,既要锻炼新秀又不能影响战绩,所以让新秀先打替补在垃圾时间上场几分钟感受一下气氛,等适应了实战下赛季就可以打主力了。
“…Map-Reduce或者Storm Topology…”
Storm是指twitter的那个框架吧,我觉得后面的topology(原文是小写)是同时泛指二者的,不是专有名词的一部分,翻成“…Map-Reduce或者Storm这样的范式…”更合适。
多谢指正,改了错别字,然后调整了一些词句。
收敛保障那个,我改了一下,希望更容易读一写,这里应该是和Feature选择类似的控制变量的方式,即用同一份Feature,但是通过收敛性看新模型是否可以用,而不是把新Feature和新模型混用。
关于丑小鸭效应,更应该类似于,即使是超级明星,也需要适应一段时间和场地。这里应该指在广告投放中,新的好的模型,在刚刚上线的时候效果可能不好,因为它的训练数据都来自于旧的模型造成的广告投放决策。当用新模型决策一段时间之后,它拿到的数据就来自于“自己的错误”,然后它本身就会变好。
另外,Topology的确是Storm的专有名词,参见 https://github.com/nathanmarz/storm/wiki/Concepts
一般的Map-Reduce大家都叫job或者workflow,我没有见过也叫做topology的,不符合topology的特征。
开发本来应该包括你说的运营(尤其对于广告这样需要大量反馈的系统),只是大学老师教我们的时候,告诉我们开发就是写代码,再多说一点,开发还包括文档和自动化等。
对互联网企业,运营确实非常重要,最火的技术未必是最好的技术,而是让用户觉得最熟悉,用起来最方便的技术。