深入浅出推荐系统(五):召回:人人都爱的热门

无论个性化多么重要,热门推荐都是推荐系统里不可或缺的一部分。其一、根据“二八定律”,电商系统中的20%的头部内容被80%的流量消费,因此,在产品早期,仅仅推荐热门内容,实施成本不高,且效果也会不错;其二,对于冷启动用户,由于较难获得用户兴趣信息,实施个性化推荐难度较高,热门内容池此时就会成为不错的选项,通过曝光给用户热门内容,可以捕获用户兴趣/非兴趣信息,以便进一步对用户进行个性化推荐;此外,热榜本身就是面向用户的产品,它提供了多样化兴趣,可以提升用户的活跃度。

亲爱的读者可以先思考下,如果由你来做一个热门榜单,你会考虑哪些因素?怎样的内容算是热门内容?电商的热门和信息流的热门又有怎样的不同呢?

嗯,想必大家心中已经各有答案了。这里为大家介绍下业界通用思路:热门榜单通常需要结合具体业务场景进行设计,需要考虑的维度通常有用户对物品的交互情况(点击、评论、点赞/反对、投票、收藏、购买等),时间、好评率、话题本身分类、发布者相关权重等,本文将对一些已知公开的热门算法做一个介绍。

基于时间机制

时间是热门榜单设计时需要重点考虑的因素,如果不考虑时间因素,只根据物品的累积交互量排名,就会出现越老的物品越容易长踞榜单的现象,且越热门的物品越容易被分发,也会吸引更多用户的关注,即马太效应。

Hacker News排序算法

Hacker News(news.ycombinator.com) 是一家发布有关黑客和创业公司相关新闻的网站,用户可以对赞同的文章进行投票,新闻采用如下公式进行打分: ( p 1 ) / ( t + 2 ) G (p – 1) / (t + 2)^{G} ,再针对打分进行排序。 其中,p为该新闻的投票数,减1是去除作者自己的投票。t为文章发表以来的时间,以小时计数,加2是对分母进行了平滑。G为重力指数,Hacker News取1.5,从这个公式中可以看出,随着时间的流逝,过去的热门在将来会不再热门。

G的大小决定了什么呢?我们可以看一个例子,一个刚刚发布的新闻A,假设除去作者一票,只获得了一票投票,那么24小时前发布的新闻B,需要获得几票才能与新闻A抗衡呢?需要 1 / ( 0 + 2 ) 1.5 ( 24 + 2 ) 1.5 374.98 1 / (0 + 2)^{1.5} * (24+2)^{1.5} \approx 374.98 ,即一天前发布的文章需要375票,才能排在刚发布的文章前面。若G = 0.5,则只需要 7.2 8 7.2 \approx 8 票,因此G可以看作对投票数和时间的重要性权衡参数,也可以看作是榜单的更新频率。G越大,新文章越容易出现在榜单上,G越小,旧一点的文章更容易出现在榜单上。

牛顿冷却定律

牛顿冷却定律来自于物理学领域,其原始含义是:物体冷却速度,与其当前温度与周围环境温度之差成正比。公式为: T ( t ) = α ( T ( t ) H ) T'(t) = -\alpha(T(t) - H) T'(t)为温度t随时间变化的函数,其导数即为t变化的速率。经过推导,公式可表达为: T = H + ( T 0 H ) e α ( t t 0 ) T = H + (T_0 - H)e^{-\alpha(t-t_0)} 其中,H为环境温度, T 0 T_0 为物体初始温度, t 0 t_0 为初始时间,T为当时间到达t时的物体最终温度。 α \alpha 是冷却系数,为常数,大于0,表示室温与降温速率之间的关系。一般环境温度H取0,则最终公式为: T = T 0 e α ( t t 0 ) T = T_0e^{-\alpha(t-t_0)} 将牛顿冷却定律套用到物品热门程度上,则 T 0 T_0 为物品初始分数,T为根据时间衰减后的最终分数。通常我们使用半衰期的概念来计算 α \alpha ,对于新闻类产品,半衰期较短,假设12小时,即0.5天后,热度衰减一半,则 0.5 = e α 0.5 0.5 = e^{-\alpha*0.5} ,解出 α = 1.386 \alpha=1.386 ,对于电商类产品,半衰期较长,假设为15天,则 0.5 = e α 15 24 0.5 = e^{-\alpha*15*24} ,解出 α = 0.0019254 \alpha=0.0019254 ,可以看出, α -\alpha 越小,热度衰减越慢。在实际业务应用中,精细化运营场景还需要考虑不同类目 α -\alpha 取值可以,比如母婴类产品和家具类产品,热度的半衰期其实是不一样的。针对不同场景,需要定制不同策略。

牛顿冷却定律不仅可以应用于各类排行榜,也可应用于如用户兴趣衰减、评论排序等时间相关场景。初始热度该如何计算呢?其实既可以使用规则(比如收藏、浏览等行为加权求和)的方式,也可以如Hacker News类似的投票累积,还可以结合使用其他算法,比如我们接下来即将介绍的投票机制。

基于投票机制

许多用户交互类网站都有用户交互机制,一般为用户的转评赞踩,用户的参与体现了话题的价值,因此一些热门榜单算法会将用户的交互行为考虑进来。

Reddit

Reddit是美国一家新闻社交类网站,用户可以发布如新闻、电影、音乐、书籍等内容的文字或链接,是美国最大的社交网站之一,月活用户超过3亿。不同于Hacker News,Reddit既可以赞,也可以踩。因此,Reddit公布的热榜算法综合考虑了交互用户的同意和反对因素。

Reddit目前在国内不可访问,但其热榜算法思路值得借鉴,其帖子得分为: s c o r e = l o g 10 z + y t 45000 score = log_{10}z + \frac{yt}{45 000} 其中,z表示赞成票与反对票的绝对差值,当差值过高时,由于log的存在而被平滑,即当差值足够高,则分数的差距不明显。这个公式下,帖子赞成与反对如果人数相当,哪怕参与的人再多,也不会认为是热帖。Reddit的算法并不一定适用于其他社区,实际上,现在社区类产品中,越是有争议的话题会认为是越有价值;公式中的y取值为{1,0,-1},当赞成票大于反对票,则为1,反之则为-1,如果赞成与反对票相等,则为0;t为发帖时间距离指定时间的差值(2005年12月8日7:46:43),以秒计,越新的帖子相应得分越高。

假设帖子A和B都是赞成票大于反对票的帖子,A为新贴,B为24小时前发布的帖子,A和B在 y t 45000 \frac{yt}{45 000} 上相差1.92分,根据公式,推导出对于B,要想排在A前面,则需要z=83.18,即赞成-反对的差值要比A大84票(注意Hacker News中,24小时需要375票)。需要注意的是,与Hacker News不同的是,Reddit发布的帖子分数,不会随着时间推移慢慢减少。可以看出,Reddit对老一点的,质量好的帖子较为重视,随着时间推移,慢慢使用新的好的帖子,替换掉老的帖子。

从工程角度看,Reddit算法的另外一个特点是由于其时间只与发布时间有关,因此帖子的热度只有当投票事件发生后,才需要更新,而不需要随着时间的流逝实时进行更新。

StackOverflow

StackOverflow是全世界最大的程序员问答平台,你可以在上面发布问题,其他人可以进行回答。其他用户可以对问题或答案投赞成票或反对票。

16510400628835.jpg

StackOverflow创始人之一的Jeff Atwood,曾公布过问题排名的公式:

16511168037205.jpg

虽然看起来复杂,但仍然是由浏览数、点赞反对数以及时间因素构成的。分子中, ( l o g 1 0 Q v i e w s ) 4 (log_10Qviews) * 4 是对问题浏览数进行平滑后加权; Q a n s w e r s Q s c o r e 5 \frac{Qanswers*Qscore}{5} 中Qanswers是问题的回答数,Qscore是问题得到的赞同与反对数之差,sum(Ascores)是回答得到的点赞与反对之差的加和。分母中,原公式可以改写为 ( Q a g e + Q u p d a t e d 2 + 1 ) 1.5 (\frac{Qage+Qupdated}{2}+1)^{1.5} Qage是问题发表时间距今时长,Qupdated是最后一个回答距今时长,都以秒计,分母与HackerNews非常相似,从时间角度上看,会鼓励近期活跃的问题。

从StackOverflow可以看出,本质上鼓励参与度(回答数、浏览数),好的质量(问题点赞数与回答点赞数),以及新鲜度(近期活跃时长)。

置信与公平的考量

热榜的排序算法有一个值得探讨的问题,即如何平衡新内容与老内容。一个赞同票1000,反对票300的老内容,和赞同票100,反对票3的新内容,该如何进行比较?前面提到的算法,基本都是对票数和时间进行综合,票数上倾向于老内容,时间上倾向于新内容,两者进行折中糅合。那么是否有其他机制,也能有效地对不同的新老内容作出符合业务场景的排序呢?我们来看看接下来介绍的两个算法。

威尔逊区间

前面提到的StackOverflow,可能会让大家联想到国内一款类似的产品--知乎。虽然面向的人群不同(比起StackOverflow面向的程序员,知乎的人群范围和知识领域更广),但产品内核逻辑是类似的,用户可以提出问题,用户可以对问题点赞和回答。同时答案也可以被点赞或反对。知乎参与者众(MAU达到1亿+),是知识领域的头部产品,被看作是一个重要的引流平台,其答案的排序前后对曝光程度影响巨大,因此知乎的排序算法可以说是举足轻重。

知乎对答案的排序,采用的是威尔逊区间算法 [ 7 ] ^{[7]} 。它不考虑时间因素,而只考虑点赞与反对的分布情况。一般来说,包含点赞及反对功能的内容,直观上我们会用点赞数-反对数,或是点赞数/总票数来计算内容得分,但这两种计算均有问题,前者会出现新内容很难被排上来的问题,后者会出现新内容只要有个别点赞,就会快速蹿升的问题。威尔逊区间则综合考量了点赞率与点赞数,其公式如下: s c o r e = ( p + z 1 α / 2 2 2 n z 1 α / 2 2 n 4 n ( 1 p ) p + z 1 α / 2 2 1 + z 1 α / 2 2 n score = \frac{(p + \frac{z_{1-\alpha/2}^2}{2n}-\frac{z_{1-\alpha/2}}{2n}\sqrt{4n(1-p)p+z_{1-\alpha/2}^2}}{1 + \frac{z_{1-\alpha/2}^2}{n}} 其中 n = u + v n = u + v p = u / n p = u / n ,u为点赞数,v为反对数,p为点赞率,需要注意的是,知乎中的点赞率是加权点赞率,每个用户的领域权重不同(取决于用户的答案质量) [ 8 ] ^{[8]} ,其点/踩的份量就不一样。一个答案快速蹿升的原因不一定是因为有大量点赞,而是可能被大V点赞了。 z 1 α / 2 z_{1-\alpha/2} 表示针对置信水平的统计量,可以通过如下的python代码获得: i n t e r v a l = s t a t s . n o r m . i n t e r v a l ( a l p h a , m e a n , s t d ) interval = stats.norm.interval(alpha,mean,std) 一般mean=0,std=1,在置信下限取90%和95%时, z 1 α / 2 z_{1-\alpha/2} 为1.64和1.96。

使用威尔逊区间的思路为:点赞率越高,得分会越大,但是点赞率的可信度,取决于多少人为之投票。投票总数越高,置信区间越窄,而置信程度越高,反之亦然。比如[80%,50%]的置信区间要比[70%,90%]的置信区间窄,且置信下限要比后者低,因此认为后者是更可信的。从公式中可以看出,当n越大,得分越趋近于p;如果n非常小,则得分会远小于p。即投票人数多且赞成票比例高的回答,会被认为是高质的。

点赞率与点赞数的综合考量取决于 z 1 α / 2 z_{1-\alpha/2} z 1 α / 2 z_{1-\alpha/2} 越大,绝对赞同数越重要,反之则赞同率越重要。 z 1 α / 2 = 0 z_{1-\alpha/2}=0 时,得分完全取决于赞同率,当 z 1 α / 2 = 0.5 z_{1-\alpha/2}=0.5 时,91赞10反对的帖子,略优于180赞20反对的帖子;而当 z 1 α / 2 = 2 z_{1-\alpha/2}=2 时,后者会优于前者。为了防止用户刷榜, z 1 α / 2 z_{1-\alpha/2} 一般是保密的。

知乎的这一投票机制会对答案的倾向性产生影响。除去各领域内专业知识类的回答,知乎还有很多人生观世界观类的回答。一个较为偏激的答案起初会获得一些同好的赞同,从而排名快速提升,当排名提升后会得到更多的曝光,被更多的人群看见,持不同意见的人会开始变多,此时反对票也会开始变多,从而不断拉低回答的排名。而较为平和的回答则不会受到太多干扰。由此可以看出,威尔逊区间在知乎答案排名中的运用,可以帮助知乎打造一个相对平和的社区氛围。

由于威尔逊区间比较适用于二值场景下的排名,与支持点赞/反对的社区类产品较为契合,因此非常适用于此类产品的内容排名。前文中所述的Reddit社区,对于评论,也采用了威尔逊区间算法。

贝叶斯平均

相较于威尔逊区间,贝叶斯平均的思路要简单的多,它为冷启动的项目提供了一个补偿值。其公式为: x = C m + i = 1 n x i n + C \overline{x} = \frac{C * m + \sum_{i=1}^{n}{x_i}}{n+C} 其中, x \overline{x} 表示最终得分,C是全局项目数,m是全局项目平均投票数, i = 1 n x i \sum_{i=1}^{n}{x_i} 是目标项目的投票数总和,n为该项目接收到的投票次数。贝叶斯平均的思路是:当项目得到足够多的投票次数,则其分数接近于其真实投票平均数;反之,其分数接近于全局平均数。全局平均就是对投票数较小的项目的得分补偿。 [ 9 ] ^{[9]}

著名的IMDB电影评分网站就使用了贝叶斯平均作为排名算法,来排名top250的电影:

16512134630208.jpg

其公式为:

WR = \frac{v}{v+m}R+\frac{m}{v+m}C
复制代码

其中,v是该电影的投票数,m是top250的榜单需要的最少投票数(目前为25000),R是该电影用户的平均投票得分, 此处有一些细节需要提一下:(1)top250对评选影片的得分要求超过一定基础数,以避免非大众电影上榜;(2)该算法仅用于top250的排名,而top250排名与该网站正常电影排名不同;(3)为了避免刷票行为,只取可信用户的投票(可信用户为经常投票的人群)。

贝叶斯平均给了冷启动项目以一定的补偿分,对投票数少的项目更为公平,但是其本身也有一定问题,由于存在时间较长的项目(电影)会得到更多的投票,因此得分差不多的情况下,老电影会更占优势。即,贝叶斯平均虽然对新启动项目给予一定公平性和曝光机会,但优秀的老的项目在贝叶斯平均的背景下仍然会更容易占据榜单。

算法之外

热门榜单虽然是基于算法的,但算法本身并不是完全中立的。作为曝光量极大的产品组成部分,热门榜单的设计要综合考虑面向的用户群体,公司的价值理念以及社会文化等多种因素。

前面所述的算法,所考虑的维度多集中于投票和时间机制,事实上真正的热门榜单会考虑更多的因素,比如用户的可信度(比如微博会通过用户是否只转不发,是否发有图片内容等行为来判断用户真实度,知乎会给予用户以不同的领域权重),以防止刷榜行为;比如用户的投票外其他行为,如苹果的App Store除了app评分,还会考虑下载量,用户日活、月活等因素;比如类目本身权重,是否给予娱乐类抑或社会新闻类以更高的权重,这本身是由运营导向的。

公司的价值理念也会影响到热门榜单的设计,前面对于知乎案例的探讨,如果公司热衷于将情绪化有煽动性的帖子给予更多曝光,则可以将同时有大量赞同反对的帖子给到更高分,从而引发更多人的讨论,但由于这样的帖子通常具有较大争议,如“女权”,“中医”类话题,极易引发社区内争议的大规模发酵。不同的价值观导向/商业化导向会使得不同领域被给予不同权重,从而会增加不同领域的曝光度。

此外,体量较大的产品,尤其是新闻、资讯及社交类产品,都不可避免的受到政策监管,热榜之后的人工审核是必需的。2018年微博下架整改,2019年小红书下架整改,都与此相关。政策及文化导向也决定了热榜的整体价值走向。

从用户偏好角度讲,热榜应该更多地展现时新的内容,但是由于优质老的内容有更长时间的曝光,因此还是更容易霸居榜单之上,如App Store上,微信、微博等app会长期占据榜首。解决之路一是可以通过缩短榜单更新时长来保证新内容的曝光;二是可以另外设计最新榜、蹿升榜、类目热门榜等其他榜单,与热榜做互相补充。

实践应用

本文所介绍的各类热门榜单的召回算法,各有所长。算法的应用并不是单一化的,它们之间可以互相结合应用。比如以贝叶斯平均来计算物品得分,再以牛顿冷却定律进行分数衰减。

为了防止刷榜,大部分公司的热榜算法是保密的(或是参数保密的)。而在一般实践应用中,在参考别家公司的算法的情况下,更多要融合业务本身的思考与理解。针对不同的场景,需要综合考量维度、算法、及权重的选择,此处做一个小小总结: (1)倾向于展现新内容,则缩短数据采集时长,使用牛顿冷却定律,或Hacker News排序算法; (2)倾向于展示热门内容,则可以考虑用户参与度、点击、点赞、评论、收藏等行为; (3)倾向于展示优质内容,则可以在点赞率、点赞数绝对数之间进行综合考量,使用威尔逊区间算法; (4)对冷启动项目给予一定公平保证,则使用贝叶斯平均,引入更多维度;增加其他榜单作补充; (5)考虑热门榜单的攻防,则要引入用户权重,引入更多计算维度。

如果亲爱的读者们有其他更好的热门榜单策略,欢迎留言探讨。

参考文献 [1]基于用户投票的排名算法(一):Delicious和Hacker News。www.ruanyifeng.com/blog/2012/0… [2]基于用户投票的排名算法(四):牛顿冷却定律。www.ruanyifeng.com/blog/2012/0… [3]如何用牛顿冷却定律计算热度。zhuanlan.zhihu.com/p/43776710 [4]基于用户投票的排名算法(二):Reddit。www.ruanyifeng.com/blog/2012/0… [5] 知乎推荐算法-知乎算法攻略。zhuanlan.zhihu.com/p/397859140 [6] 基于用户投票的排名算法(三):Stack Overflow。www.ruanyifeng.com/blog/2012/0… [7] 知乎如何对回答进行排序?你的一票很重要。zhuanlan.zhihu.com/p/19902495。 [8] 知乎如何计算用户在某个领域下的权重。www.zhihu.com/question/21… [9] 基于用户投票的排名算法(六):贝叶斯平均。www.ruanyifeng.com/blog/2012/0…

猜你喜欢

转载自juejin.im/post/7111640808742191140