推荐系统, 多目标模型的多个目标怎么融合?

2022-09-22 14:38:59 浏览数 (1)

作者 | 梁唐

出品 | 公众号:Coder梁(ID:Coder_LT)

大家好,我是梁唐。

前两天写了一篇关于多目标排序模型的文章,有小伙伴给我留言说,多个目标好理解, 但是排序的时候怎么融合多个目标呢?

我仔细一想,的确没有说清楚,没有相关工作经验的小伙伴可能还是有些迷糊。没有关系,我们今天就来单独聊聊这个话题。

排序问题

在说清楚多目标之前,我们先来看看排序。

排序是算法工程师做的最多的问题之一,其实从原理角度来说,搜索、广告和推荐本质上都是排序问题。区别在于使用的场景不同,排序的目标不同。

这一点我们之前在相关文章当中讲过,搜索主要看重相关性,用户想看的一定是和搜索词相关的内容,然后才是商品质量以及兴趣。

广告的目标当然是盈利,作为电商平台以及互联网公司的核心收入来源之一,广告的核心目的没有之一就是盈利。当然盈利也分,不同业务场景的广告盈利方式也不同。大部分广告是按用户的点击收费,也有的按曝光和成交收费。不管按什么收费,在广告排序的时候一律按照期望收益排序,将最有可能赚钱的排在前面。

对于搜索和广告来说,排序的目标都是相对比较明确的,但推荐不同,推荐的目标就没那么明确了。可能会有同学说,推荐目标不是用户喜欢么,当然是按照用户兴趣排序啦。

没这么简单,先不说用户的兴趣千差万别,即使能够找到大胸妹一样的公共兴趣,效果也不一定会好。毕竟死直男们愿意看,但真让他们花钱去买女性用品,大多数还是做不出来。

所以在推荐领域,工程师们的目标其实是比较迷茫的。但建模的过程当中又必须要有一个明确的目标,所以业内还是用点击率和转化率来作为推荐的目标。大家可以思考一个问题,点击率高转化率高就意味着推荐效果好吗?这两者真的等价吗?所有推荐场景都适合用点击和转化作为目标吗?

接着,我们来看看排序本身的问题。

从技术上来说排序本身并不复杂,就是按照模型预测的分数进行排序,把分数高的排在前面。比如如果模型的预测结果是CTR,那么就是预测点击率高的排在前面。如果模型的效果好的话,那么真实的点击率就会上涨,同样,如果我们以转化率CVR排序,那么就是转化率高的在前,由于转化率和点击率并不一定吻合,所以转化率涨了,点击率不一定也会涨。

难道不能同时按照多个值排吗?

翻一下算法导论就知道,不能。所谓的多关键字排序也是按照顺序依次比较关键字,在关键字都是浮点数几乎不会出现相等的情况下,多关键字排序毫无意义。

所以如果我们同时预测了多个目标,也没办法在排序的时候按照多个目标排序,除非我们想办法把它们融合到一起。这也就是今天文章的主题,多目标的情况下怎么进行融合排序的问题。

融合方案

融合方案本身非常简单,大家都和拍脑袋差不太多,并没有高下之分,只有效果好不好的差别。

比如你可以按照pctr pcvr排,也可以pctr * pcvr排,也可以各自设置一个权重排,也可以设计一些奇怪的公式把它们融合到一起排。无论怎么操作,都是可以的。

但如果我们从实际意义来看,pctr * pcvr的方案更有物理意义,因为它代表着点击转化率,即用户看到商品的前提下他会下单的概率。

为什么这种方案排序要比单纯按照pctr或者pcvr排序效果好呢?因为很简单,因为我们是按照乘积排序的,这两个值里面只要有一个拉胯,就不会被排到前面。比如图片是大胸妹的商品,可能点击率很高,但转化率不行,那么它也不会被排在前面。

相当于我们做了一个权衡,过滤掉了一些转化率奇高点击率奇低和点击率奇高转化率奇低的极端case,可能会牺牲一些指标,但整体上对于平台的内容是有利的。实际上从最终实验的结果来看,点击率影响并不大,但转化率能得到非常巨大的提升。

细节和常见错误

不管我们设计怎么样的多目标融合方案,有一个细节一定要注意,就是这个目标要和模型训练的目标一致。

体现在我们计算损失函数的时候,我们要拿最终的方案来计算loss,并且更新模型参数。

这张图大家都能看得懂,但是很多人在实现模型的时候出了问题。比如说设计了一个融合方案是x* pctr y * pcvr,即给pctrpcvr各自设置了一个权重。这本身也没什么问题,但是在损失函数的实现里面,它还是用的pctrpcvr本身计算损失更新模型的,这就有问题了。

比如,训练的时候计算pcvr转化率的时候,计算损失函数是按照pcvr得到的,那么模型对于转化率这个目标的学习都是通过pcvr这个值控制的。但是实际线上排序的时候用的又是x * pctr y * pcvr,这个公式模型从没见过,那么肯定就会有偏差。

另外一个常见的问题是分开训练,和之前的例子差不多。线上预测的时候用的是pctcvr,但是训练的时候,多个目标是分开训练的,比如pctr的loss是用pctr算的,pcvr的loss是用pcvr算的。

细想会发现一个问题,我们排序的时候用的是pctr * pcvr,这是两个目标融合的结果。理想情况下,对于这个目标,两个塔都应该有所感知,体现在反向传播的时候,彼此的结果会互相影响梯度,两个塔会同时更新参数。但是我们loss是分开的,也就是说我们在反向传播的时候,两个塔是各自更新参数的,彼此不知道对方的存在,那么这里的协同性就没有了。

常规的做法是对于点击率的更新,我们只训练pctr这个塔,由于转化的前提是点击,所以我们按照pctcvr去计算转化率目标的loss,这样在反向传播的时候,可以同时更新这两个塔的参数,起到一个协同的效果。

ESMM这篇论文看起来非常简单,好像就只是多了一个塔,里面的细节还是蛮多的。

如果想把这个模型吃透,非常推荐大家去仔细读一下论文或者是相关实现的代码。魔鬼都藏在细节里,仔细推敲,一定会大有收获。

0 人点赞