线下 auc 涨,线上 ctr/cpm 跌的原因和解决办法
“ 这两年深度模型大火之后,各个团队都卯足了劲把网络规模做大做深,花了很大力气好不容易离线 auc 涨了不少,上线一看效果 ctr 和 cpm 反而下降。本文例举几种可能的原因和解决办法。”
作者:辛俊波 腾讯高级研究员 专注推荐/广告/深度学习原文链接:https://www.zhihu.com/question/32218407/answer/1172781649
1. 特征/数据出现穿越
一般就是使用了和 label 强相关的特征导致的数据泄漏。这种问题一般相对好查,很多时候在离线阶段就能发现。明显的表现就是训练集和测试集差异比较大
2. 线上线下特征不一致
据我所知,这种情况是导致离线涨在线跌或者没效果的最常见情况。
首先是代码不一致,例如,离线对用户特征的加工处理采用 scala/python 处理,抽取用户最近的 50 个行为,在线特征抽取用 c++ 实现只用了 30 个。只要离线和在线用不同的代码抽取就很容易存在这种代码带来的不一致。
另外一种线上线下不一致,是由于数据的不一致导致。这在离线拼接样本和特征的 pipeline 中比较常见。一般离线特征都是按照天处理的,考虑各种数据 pipeline 的流程,处理时间一般都会有延迟,离线特征处理完之后导到线上供线上模型预估时请求使用。
这种不一致都是怎么产生的?例如 4 月 15 日这天,线上预估请求用的特征是 4 月 14 号的特征数据。到了 4 月 16 日,特征 pipeline 开始处理数据,到了凌晨 4 点,离线特征处理完了导到线上。那么在 4 月 16 日 0 点-4 点,这段时间线上请求的特征使用的是老的特征数据,也就是 4 月 14 日的特征数据。4 月 16 日 4 点-24 点,线上特征使用的是 4 月 15 日的数据。而在离线样本生成过程中,到了 4 月 17 日 0 点,如果是按天拼接的,那么 4 月 16 号这天的所有样本,都会使用 4 月 15 日的特征。
这样,4 月 16 日 0-4 日的样本,在离线样本拼接的阶段,使用的是 4 月 15 日的特征数据,而在线上请求特征的时候使用的还是 4 月 14 日的特征。特征 pipeline 流程处理越长,这种不一致会越大。
要严格保证线上线下的特征一致性,最根本的方法就是同一套代码和数据源抽取特征,业内目前通用的方法就是,在线实时请求打分的时候落地实时特征,训练的时候就没有特征拼接的流程,只需要关联 label,生成正负样本即可
3. 数据分布的不一致
如果仔细排查,既不存在数据泄漏,也没有出现不一致的问题,离线 auc 明明就是涨了很多,线上就是下降,而且是离线涨的越多,线上下降越多,还有一种可能就是数据的不一致,也就是数据的“冰山效应”----离线训练用的是有偏的冰山上的数据,而在线上预估的时候,需要预测的是整个冰山的数据,包括大量冰面以下的数据!
这种情况其实在推荐系统里非常常见,但是往往非常的隐蔽,一时半会很难发现。我们看下面这张图。左边是我们的 Baseline,绿色的表示正样本,红色表示负样本,灰色部分表示线上由于推荐系统的“偏见”(预估分数较低),导致根本没有展现过的数据。
离线阶段,我们通过各种优化,新模型的离线评估表现更好了,例如图中第二列,可以发现第 4 个绿色的正样本和第 7 个绿色的正样本排到了第 3 和第 6 的位置,离线的 auc 指标涨了。
到了真正线上的预估也就是第三列,发现对于这部分离线见过的样本,模型的预估序并未改变。但是新模型给了灰色没有见过的数据更高的预估分数,这部分数据一旦表现不好,很可能造成我们前面说的情况,离线(第二列)评估指标明明涨了不少,在线(第三列)评估指标 ctr 却下降。
这种情况也不是必现的,在 LR 以特征工程为主要迭代的时代很少见。主要的原因是模型的前后迭代差异并不大。新模型对比老模型最主要的特点是新加入了一部分特征,往往模型的打分差异并不大,从图中第二列到第三列,原来那些冰山下的数据也就是旧模型预估分数偏低的部分,在新模型中能够脱颖而出拿到很高的预估分数的概率并不高。
而在模型有较大变化的时候,例如 lr-> 树模型,lr-> 深度模型,不同网络结构的深度模型变化,这种情况容易出现,原因就是新旧模型的变化较大,预估分数变化也较大。
举一个简单的例子,假设我们的 baseline 是热门模型,样本都是老的热门模型生产出的热门样本,这个时候我们用简单的 lr 模型去拟合,到了真正的线上预估的时候,对于大量之前没见过的非热门的数据,模型自然很难预估好。没有足够好的样本,模型也很难学到足够有用的信息。
说另一个很有意思的现象,之前在某个组的时候,两个 team 优化同一个场景,大家用的回流样本都是一样的,但是特征和模型都是自己独立优化和迭代。有意思的是,如果一个 team 的优化取得了比较明显的提升之后,另一个 team 哪怕什么都不做,过一段时间效果也会慢慢涨上来。
对于这种情况,最根本的手段就是解决数据的有偏问题。尤其是新模型,一开始相当于都是在拟合老模型产生的样本,刚上线效果如果比较差,经过一段时间迭代,影响的样本分布慢慢趋近于新模型,也能收敛,但效率较低。这里给下两个在我们这还比较有效的经验:
-
(1)对无偏数据进行上采样
这里的无偏是相对的,可以是随机/探索流量产生的样本,也可以是新模型产生的样本。大概意思,就是尽可能利用这些对新模型有利的样本 -
(2)线上线下模型融合
比较 trick 的方法,没有太多方法论,但是确实能 work。
新模型预估分数 和老模型预估分数 直接在线上做线性融合,刚上线的时候 a 选取比较小,随着慢慢迭代,a 慢慢放大。