数学之美:Reddit的排名算法

标签: 程序设计 算法 | 发表时间:2012-06-29 00:46 | 作者:标点符
出处:http://www.biaodianfu.com

上一篇文章介绍了 Hacker News 的排名规则。这次要介绍的是另外一个社会化新闻类网站 Reddit 。Reddit对文章和评论使用了不同的排名算法,这边文章要介绍的是前者,后面的关于评论的排名在后面的文章作再作介绍。 Reddit与Hacker News有很大的不同点就是,Hacker News文章标题前面只有一个向上的小箭头,即只能投赞成票,而Reddit的每个文章标题前会有两个箭头,即一个向上,一个像下。分别代表“赞成”与“反对”。 Reddit已经把他们的所有源代码进行了公开,你可通过如下地址( https://github.com/reddit/reddit)进行下载研究。具体涉及到排序部分的代码如下: https://github.com/reddit/reddit/blob/master/r2/r2/lib/db/_sorts.pyx。为了效率,由于此部分代码是使用Python的C语言扩展来写,下面是用Python重写的代码:

from datetime import datetime, timedelta
from math import log

epoch = datetime(1970, 1, 1)

def epoch_seconds(date):
    """Returns the number of seconds from the epoch to date."""
    td = date - epoch
    return td.days * 86400 + td.seconds + (float(td.microseconds) / 1000000)

def score(ups, downs):
    return ups - downs

def hot(ups, downs, date):
    """The hot formula. Should match the equivalent function in postgres."""
    s = score(ups, downs)
    order = log(max(abs(s), 1), 10)
    sign = 1 if s > 0 else -1 if s < 0 else 0
    seconds = epoch_seconds(date) - 1134028003
    return round(order + sign * seconds / 45000, 7)

从上面的代码中可以看到整个逻辑并不复杂,下面就来深入研究下起实现的方式。以下为对于代码中使用到的数学公式的描述。

从上面的代码级公式中我们可以了解到Reddit的排名算法主要与以下内容有关:

1、文章的发表时间t

t = 发表时间 – 2005 年 12 月 8 日7:46:43

在上一篇 Hacker News的文章中,用来标注文章新旧程度的单位为小时,而Reddit的单位为秒,其使用Unix时间戳(从1970年1月1日到当前时间的秒数)进行的计算,代码中的1134028003代表的日期为2005 年 12 月 8 日7:46:43。这个应该是Reddit这个网站的上线时间。通过上面的公式可以看到一旦帖子发表,t就是固定值,不会随时间改变,而且帖子越新,t值越大。

发表时间和话题排名的影响可以被概括如下:

  • 发表时间对排名有很大影响,该算法使得新的话题比旧的话题排名靠前
  • 话题的得分不会因为时间的流失而减少,但是新的话题会比旧的话题得分高。这与 Hacker New 的算法不同 (随着时间的发展降低话题的得分)

下图展示了话题得分在好评和差评的数量不变时,随着时间而变化的情况:

2、赞成票与反对票的差x

x = 赞成票 – 反对票

真是由于Reddit提供了投反对票的功能,所以可以使一些具有争议的话题会排的较后,下图展示了在好评和差评不变时,随着时间而变化的情况:

3、投票方向y

y 是一个符号变量,表示对文章的总体看法。如果赞成票居多,y就是 +1;如果反对票居多,y就是-1;如果赞成票和反对票相等,y就是0。y是文章评价的一种定性表达,0表示没有倾向,大于0表示正面评价,小于0表示负面评价。

4、帖子的受肯定程度z

z 表示赞成票超过反对票的数量。如果赞成票少于或等于反对票,那么z就等于1。

结合以上几个变量,Reddit 的最终得分计算公式如下:

这个公式可以分成两个部分来讨论:

1、logZ

这个部分表示,赞成票超过反对票的数量越多,得分越高。 需要注意的是,这里用的是以 10 为底的对数,意味着z=10可以得到 1 分,z=100可以得到 2 分。也就是说,前 10 个投票人与后 90 个投票人(乃至再后面 900 个投票人)的权重是一样的,即如果一个帖子特别受到欢迎,那么越到后面投赞成票,对得分越不会产生影响。而当反对票超过或等于赞成票,z=1,因此这个部分等于0,也就是不产生得分。

Reddit 的热排序算法使用了对数函数来衡量前面的投票与其他投票的差距使其前十个好评和之后的100个,1000个投票有相同的权重。 参见下面的图:

如果不采用对数,而使用线性函数的效果如下:

Reddit敢于如此消弱投票的作用,其实与其庞大的流量和用户参与度相关。如果没有以上因素算法很难实现很好的推荐。

2、yt/45000

这个部分表示,t越大,得分越高,即新帖子的得分会高于老帖子。它起到自动将老帖子的排名往下拉的作用。 分母的 45000 秒,等于 12.5 个小时,也就是说,后一天的帖子会比前一天的帖子多得 2 分。结合前一部分,可以得到结论,如果前一天的帖子在第二天还想保持原先的排名,在这一天里面,它得到的净赞成票必须增加100 倍。

y 的作用是用来产生正分和负分。当赞成票超过反对票时,得分为正;当赞成票少于反对票时,得分为负;当两者相等,得分为0。这就保证了得到大量净赞成票的文章,会排在前列;得到大量净反对票的文章,会排在最后。投票对于总分的贡献不大,但是当投票的意见倾向发生变化时(由正面评价转向负面评价),投票对于总分的作用却是决定性(Y的取值)。

总结

以上内容分析这么多,是该进行总结的时候了,关于Reddit的排名,基本上是由发表时间决定的,只有相同时段的文章才有可比性。晚半天,投票就要翻10倍,只能同时段的文章相比。只有超级受欢迎的文章才会排在最前面,有争议或者一般性的文章很难靠前。基于上述也就决定了 Reddit是一个符合大众胃口的网站,并不是一个很激进可以展示少数派想法的地方。

说了这么多,再来看下Reddit与Hacker News的区别,到底哪一个的算法更好一些呢?其实算法并没有优劣之分,两种方法更有千秋,重要的是你打算用在什么地方。Reddit流量大,所以可以减少投票的权重,而也因为流量大,使得每篇文章在没有收到新的投票的时候无需重新计算得分,也可大大的减少服务器的运算成本。

参考文章: http://amix.dk/blog/post/19588

Related posts:

  1. WordPress 2.7 数据字典
  2. IIS日志配置方案
  3. PHP版记录蜘蛛爬行历史

相关 [数学之美 reddit 排名] 推荐:

数学之美:Reddit的排名算法

- - 标点符
上一篇文章介绍了 Hacker News 的排名规则. 这次要介绍的是另外一个社会化新闻类网站 Reddit. Reddit对文章和评论使用了不同的排名算法,这边文章要介绍的是前者,后面的关于评论的排名在后面的文章作再作介绍. Reddit与Hacker News有很大的不同点就是,Hacker News文章标题前面只有一个向上的小箭头,即只能投赞成票,而Reddit的每个文章标题前会有两个箭头,即一个向上,一个像下.

Reddit排名算法工作原理

- - 博客园_新闻
英文原文: How Reddit ranking algorithms work. 这是一篇继《 Hacker News 排名算法工作原理》之后的又一篇关于排名算法的文章. 这次我将跟大家探讨一下 Reddit 的文章排名算法和评论排名算法的工作原理. Reddit 使用的算法也是很简单,容易理解和实现.

基于用户投票的排名算法(二):Reddit

- - 阮一峰的网络日志
(不好意思,这个系列中断了近两周,我会尽快在这几天,把后面几篇写完. 上一次,我介绍了 Hacker News的排名算法. 它的特点是用户只能投赞成票,但是很多网站还允许用户投反对票. 就是说,除了好评以外,你还可以给某篇文章差评. Reddit是美国最大的网上社区,它的每个帖子前面都有向上和向下的箭头,分别表示"赞成"和"反对".

数学之美:StackOverflow问答排名算法

- - 标点符
先前的文章介绍了 StackOverflow的系统架构,这次继续排序话题,学习的是StackOverFlow的排序算法. StackOverflow的排序共分为两类,1个是问题排序,1个是答案排序. 这里主要介绍的是关于热门问题的排序. 在分析问题前可以先考虑下,如果是你来做这个排名算法需要考虑哪些因素.

重写Reddit

- - 博客园_新闻
英文原文: Rewriting Reddit. 2012 年注:本文首发于 2005 年. 发布之后,Django 上线了一个 RemovingTheMagic 项目,提出了我的一些质疑(尽管我本人发现它仍然不可用), web.py 促进了 FriendFeed 的. tornado.web 和 Google 的.

Reddit审查“未成年少女”

- 微笑!?~ - Solidot
Reddit以“危险到社区结构完整性”为名正式关闭了一个子群组“r/jailbait”. jailbait是美国英语俚语,指未到法定年龄的年轻少女,但身体发育已经成熟,会被误以为是成年人. 关闭jailbait引发了言论自由的争论,但有人指出,Reddit是私人经营的网站,它有权阻止一些它不想要的言论.

新闻聚合网站Reddit月浏览量超20亿

- - GeekPark 捕风捉影
Reddit公布了其2011年12月的网站统计数据. 数据显示Reddit 12月的页面浏览量已超过20亿,独立访客数量接近3500万. 其中subreddit超过10万个,有8400个subreddits的订阅者超过100人. 三分之二的用户使用Chrome和Firefox,而IE浏览器只占7%左右.

深度学习大牛Bengio教授在Reddit吐槽

- - 博客园_新闻
     Deep Learning 界的三架马车,目前 Geoffrey Hinton 已被 Google 收编, Yann LeCun 已被 Facebook 收编,还留在学术界的 Yoshua Bengio 最近心情好,在 reddit 上定期回答问题. 我抽取了一些比较有料的观点在下面,希望对大家了解这方面有帮助(再不上船可就晚了).

Reddit如何可以承受每月2.7亿PV

- - 博客园_新闻
英文原文: 7 Lessons Learned While Building Reddit To 270 Million Page Views A Month.    这篇文章有点老,是 2010 年的. Reddit 在美国年轻人中很受欢迎,感觉 黃易山做 CEO 后更蒸蒸日上了. 相信这 4 年间,他们面临的 scalability 的问题更严峻,一些架构可能都推倒重来了.

深度学习大牛Bengio教授在reddit吐槽

- - 弯曲评论
转载自: http://meroa.com. Deep Learning学术界的三架马车,目前Geoffrey Hinton已被Google收编,Yann LeCun已被Facebook收编,还留在学术界的Yoshua Bengio最近心情好,在reddit上开帖定期回答问题. 我抽取了一些有料的回答在下面,希望对大家了解这方面有帮助.