机器学习中的人为偏差

引子

数据科学实在是一门庞大的学科,涉猎了太多领域的知识和技能。在这其中,人工进行的工作占了不小的比重,很多甚至是最关键的。比如标注数据,评判算法的优劣,指导模型的迭代等。 但是,有人的地方就有偏见(bias),就有主观上或者客观上带来的不确定性。而这种不确定性蔓延到数据科学领域,特别是机器学习领域,有时候对于我们求解问题的伤害是很大的,可能给我们带来有偏差甚至是相反的结果。这篇文章试图 把这些人工引入的 bias 列出来,并尝试给出一些建议。

这篇文章的很多经验,主要是来自百度搜索推荐机器学习团队的日常工作实践,是我这些年来浸淫数据科学研发和管理的所感所悟。 同时我也对认知行为学和心理学很感兴趣,平时会阅读一些这个领域的书籍。这里写的不一定全面,但是我敢保证足够接地气。

人工带来的偏见

证实偏见(Confirmation Bias)

认知偏见普遍存在于人类的主观意识中,说白了就是人们会倾向于去求证那些自己已经”相信”的事情,选择性的去寻找或者回忆起那些支持自己观点的证据,而对相反的证据选择漠视或者遗忘。

在认知偏见中,又数”观察着期望效应” 最容易出现在数据科学中。我们先来看下Wikipeda 对于这个效应的描述:

观察者期望效应是认知偏见的一种。在科学实验中,由于观察者预期某些测试结果,于是无意识地以某种形式操纵了实验步骤,或错误解释实验结果以达至他们希望得到的结论。观察者期望效应能严重歪曲实验结果,因此需利用双盲方式进行实验来消除这效应。

具体在机器学习日常工作中,负责某个模型的研发人员可能会倾向于给某个自己精心设计的模型以更高的”期望值”,然后在验证模型效果的的时候,倾向于去相信”最好情况”,而非”最差情况”和”平均情况”。这些行为可能根本是下意识的,但是却背离了客观和中立。

典型的例子是我们的策略效果RD自评。RD总是对于自己的模型效果更有”信心”,他们自评出来的结果往往会比客观情况更”好”。还有一个例子是我们定期进行的”推荐质量摸底”。专门的评估人员往往倾向于在产品投诉多的时候用更”严格”的标准”(其实客观标准是有的,但是靠人来解释和执行)来衡量推荐产品,而在 KPI 压力大,或者刚刚进行了一次大规模质量冲刺后,用更”宽松”的标准来验证这个质量冲刺”达成”了KPI。

解决办法其实很简单, 用双盲方式来进行评估。 比如在小流量评估中,事先不告诉评估者哪份数据是实验组,哪份是对照组。 这样会非常有效的降低期望效应带来的影响。

人为忽略方差(Variance Ignorance)

我们希望通过人工评估的方式去衡量机器学习系统的质量,比如推荐相关性。然后我们可能引入一个或几个同学来抽样评估。但是抽样是有偏差的,不同的人也有不同的认知偏差(见上)。因为工作量和工作方法的限制,大多数情况下我们的小流量质量评估和摸底评估都是靠单人单次的抽样+评估来产出结论,抽样和评估的方差被完全忽略掉了。

这样做会给线上带来一定的风险,因为我们是根据A/B test小流量结论和人工评估的结论来决定某次策略是否上线的。而如果因为方差过大,导致结果偶然性很高的话,无疑会把这种风险带到线上去。

同样因为上面的证实偏见,导致A项目负责PM在负责A项目时候,可能会有意或无意的放松评估的尺度。甚至出现过这版抽样不符合标准,那就再抽一次,直到抽到复合标准为止的情况。认知偏差再加上无视抽样方差,导致了人工评估的结果 不严谨甚至出错。

针对这种情况,我们可能需要牺牲一些短期研发效率,换取长期置信和稳定性。比如通过 多人交叉验证,多轮抽样的方式来给出更可信的评估结果,并在给出结论的同时给出方差等。同时我们要对日常线上的质量,流量等等其他指标有比较明确的方差概念,这样才好在新策略上线决策时候有更科学和合理的评判。

不严谨的工作方法

滥用测试集(Testing-set Abusing)

从机器学习教科书,到sklearn的文档,再到最新的Deep learning课程,老师们教了我们一件事情就是拿到数据后分两部分,一部分做训练集(training-set),一部分做测试集(testing-set)。我们在训练集上训练模型,然后看其在测试集上的预测效果。如果训练集上效果不错,但是测试集上效果不好,那可能是出现了过拟合(overfitting) 的情况,我们需要再去迭代模型。

这个方法本身是没错的,但是据我观察(包括原来的我也出现过),很多人会根据测试集表现不好的 case 来总结经验,去修正或者添加一些特征在模型中,然后在同样的测试集上去验证效果。效果是变好了,但是这样做其实是把原来的测试集,间接变成了你的训练集。即一些测试集的信息泄露(leak)到了你的训练集合里面。而真正的测试集,已经被污染了。在已经被污染了的测试集上面出结论,是不严谨的。

解决办法是在训练集和测试集中间引入一个开发集(developing-set)。在训练集上训模型,在开发集上验证模型的预测能力,并在这两个之间做迭代,直到达到你满意的状态。最终我们在干净的测试集上产出最终模型表现。其实这样做在外部看来,还是一个训练集(包括内部训练集+内部开发集),外加一个测试集。不过这个时候你已经可以保证测试集的纯净了。记住,测试集就像期末考试题,交了卷,就绝不能再改了。

当然,我们也要确保这三个集合的分布是一致的(分布的差异足够小),这也有一套方法来验证。

模型迭代只看case解决率

我们的系统服务在线上,会有一定比例的badcase通过各种渠道收集起来, 可能是推荐的相关性不好,可能是有一些排序的问题,作为策略下一步迭代的重要参考。很多同学在迭代策略的时候,经常会只以 降低 badcase比例作为衡量目标,或者更隐晦点的,把badcase当做负样本直接丢到历史测试集中去。殊不知这样其实或多或少的改变了测试集的抽样的分布,使其偏离了线上服务(Serving time)的真实分布。这样调出来的策略,即使badcase解决率很高,测试集表现很好,也是不准确,不严谨的。

总结

因为数据科学,特别是机器学习的特点,我们在日常工作中需要做很多的统计和估计。而人类显然并不是纯理性的动物,即使受过多年训练的机器学习工作者也不免在工作中的某些时候犯这样或那样的错误,踩这样或那样的坑。很多是不得已为之(KPI 压力,项目时间压力,晋升的压力),很多甚至是无意识的行为。为了我们做的模型能够真正产生最优的效果,产品能发挥最大的潜力,更是为了维护机器学习的科学性。我们还是值得静下心来回顾一下日常工作中可能有意无意引入的 Variance 和 Bias,从主观上或者在工作方式设计上,去尽量避免引入人为的不确定性。

参考资料

  1. 认知偏见 https://zh.wikipedia.org/wiki/%E8%AA%8D%E7%9F%A5%E5%81%8F%E8%AA%A4
  2. Andrew Ng的新书 Mechine Learning Yearning

Published: October 18 2017

blog comments powered by Disqus