`

<转>数学之美:Reddit的排名算法

阅读更多

原文地址:http://www.woxihuan.com/53055876/1343783154126204.shtml

 

数学之美:Reddit的排名算法

上一篇文章介绍了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重写的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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 &gt; 0 else -1 if s &lt; 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

分享到:
评论

相关推荐

    cinch-reddit:用于cinch irc bot框架的reddit插件

    karma &lt;username&gt; :返回的因缘&lt;username&gt; !readers &lt;subreddit&gt; :返回的用户数量&lt;subreddit&gt; !mods &lt;subreddit&gt; :返回的MODS的&lt;subreddit&gt; 正在安装 您需要安装[cinch] [1]框架,但是一旦完成,其余的操作就很...

    Reddit_Comment_Searcher:Reddit机器人,它将查找用户注释中单词的使用次数

    u/&lt;Bot&gt; &lt;Username&gt; &lt;Word&gt; 依存关系: dotenv,请求,小暴风雨和snoowrap。 如果您还不知道如何,请通过npm i dotenv request snoostorm snoowrap在节点中安装多个软件包。 另外,非常重要:请在.env中的空白...

    reddit-history-deleter

    export RHD_USERNAME=&lt;Reddit&gt;export RHD_PASSWORD=&lt;Reddit&gt;export RHD_CLIENT_ID=&lt;Reddit&gt;export RHD_CLIENT_SECRET=&lt;Reddit&gt;可选,设置Reddit帖子应删除的旧天数。 不设置此值将默认为365天。 export RHD_...

    hot-ranking:Reddit 热门排名算法

    Reddit 热门排名算法 基于 reddit 热门排名算法计算和 item 的分数。 对于科学背后的阅读 安装 npm install hot-ranking 用法 hot(upvotes, downvotes, date) // Load library var hot = require("hot-ranking"); ...

    CmdLineReddit:简单的命令行 Reddit 阅读器

    CmdLineReddit 这是一个简单的非官方的 Perl 命令行 Reddit 阅读器。 它从 Reddit 读取 RSS 提要。... 您还可以使用 &lt;subreddit&gt;、&lt;subreddit&gt; 或 &lt;subreddit&gt;。 设置:在 1 到 100 之间设置环境变量 RED

    Reddit股票趋势:在Reddit上获取当前趋势股票

    Reddit股票趋势 :chart_increasing: 在Reddit上查看趋势股票行情自动收录器,并检查股票表现 后端 Reddit API 从获取您的reddit API凭据。 按照文章,让您的凭据。 转到back/目录。 使用以下命令创建一个praw....

    python-redditcli:Reddit API的Python CLI

    redditcli --client-id &lt;client0id&gt; --client-secret &lt;client&gt; --username &lt;username&gt; --password &lt;password&gt; my-account +--------------------+--------------+ | Field | Value | +--------------------+-------...

    reddit-top-50:Reddit排名前50位的帖子-使用Vue.js和Reddit API在Deviget进行前端挑战

    Reddit排名前50位的帖子(VueJS的概念证明)-Diogo Bernardelli 下载/克隆项目 在终端上,键入以下命令 $ git clone https://github.com/diogobernardelli/reddit-top-50.git 依存关系 Linux系统 $ sudo apt-get ...

    go-rate:Reddit使用的简单评分算法

    Hot ( upvotes , downvotes , createdAt )}按Wilson-Score间隔排序Reddit评论排名使用Wilson-Score区间Wilson-Score时间间隔公式显示如下: p-hat是赞成票占总数的分数n是赞成和反对的总数这是用go编写的算法的示例...

    my-reddit:Reddit克隆

    my-reddit:Reddit克隆

    relativeReddit:Reddit 评论相对排名

    相对 Reddit 评论 通过添加衡量相对精彩程度的颜色编码徽章来发现很棒的 Reddit 评论 介绍 Reddit评论线程很难阅读。 相对 Reddit 通过在每个评论的分数旁边添加一个颜色编码的徽章,可以很容易地在一个线程中发现...

    Reddit:Reddit克隆

    Reddit:Reddit克隆

    RemindmeBot:这是一个设置提醒的不和谐机器人

    remind &lt;user&gt; &lt;time&gt; &lt;message&gt; 在给定的&lt;time&gt;时间段之后提醒其他用户 timezone &lt;string&gt; 设置服务器的时区(用于日末计算),默认为UTC 时间解析 时间解析器允许使用多种格式来指定提醒时间。 目前,不同的...

    hreddit:Reddit命令行客户端

    用法: hreddit [&lt;subreddit&gt;]/[new|hot|controversial|top]命令清单: quit :退出程序next :转到下一页并列出previous :转到上一页并列出first :转到首页并列出hot :转到“ hot”排序new :转到“新”排序top...

    管理Reddit订阅「Manage Reddit Subscriptions」-crx插件

    在底部的状态栏将显示:已订阅的红字:&lt;subscribed&gt; / &lt;已知reddits#&gt;,已过滤:&lt;已订阅已过滤#&gt; / &lt;totlal&gt; 通过reddits过滤列表;标签;都。 显示选项还包括:显示NSFW;仅订阅仅标记 单击鼠标点击“查看”将...

    reddit-post-notifier:FirefoxChrome扩展程序,可监视给定子查询或Reddit搜索中的帖子

    并使用在Firefox或Chrome中运行它&gt; npm run buildzip:ff &gt; npm run buildzip:chrome 在/ web-ext-artifacts文件夹中创建扩展包&gt; npm run test 开玩笑地测试扩展的代码授权此扩展程序使用授权来检查reddit私人邮件。...

    RedditAPI:我的第一个内置于python的RESTful API。 提出要求以获取任何subreddit的热门帖子

    语法如下: http://127.0.0.1:5000/posts/&lt;str&gt;/&lt;int&gt;/&lt;int&gt;/&lt;int&gt; 您可以删除任何值以使用默认值,如下所示http://127.0.0.1:5000/posts/&lt;subreddit&gt; 这将使用默认的10个帖子,不显示广告,也不显示粘贴的帖子

    ModTools:Reddit Mod的主持人工具

    模组工具这些是Reddit版主的方便的小型Mod工具。 每个工具将在下面说明。 如果您希望自己运行此程序,请按照安装指南进行操作。 如果您希望将subreddit包含在这些工具中,请在reddit上与联系。配置首先,创建一个...

    RedditTextClassification:Reddit性别文本分类

    RedditTextClassification:Reddit性别文本分类

Global site tag (gtag.js) - Google Analytics