一种更好的社区文章帖子排名算法 - Herman


不管我们喜不喜欢,排名算法都会影响我们看待世界的方式。它们是信息网站(无论是搜索引擎、新闻聚合器还是社交媒体)最重要的部分之一,因为它们从字面上决定了人们所看到的内容,从而决定了人们的体验和想法。

我是Bear的创建者,这是一个最小的博客平台(主要针对对网络当前状态感到失望的技术人员)。在过去的几个月里,我一直在广泛地考虑(并试验)发现提要的排名算法,并且有一些想法要分享。

一个好的排名算法的剖析
1、它优先考虑好的内容
优质内容是排名算法最重要的属性(显然)。我们需要确保排名靠前的内容具有一定的标准。尽管声明很简单,但"好"的定义是什么?

解决这个问题的一个方法是由具有权威性(希望是好的品味)的内容策划编辑者对内容进行分类。然而,这是一个资源密集型的过程,很少有聚合者有这样的特权。

最常见的方法是记录加分(或赞/减分/愤怒的脸/转发/臭鸡蛋/等等)的数量,并通过算法来确定一个帖子的质量。这种民主显然对平台上的用户类型有偏见,但这在没有策划的情况下是不可避免的(如果你想迂腐的话,有了策划编辑也是如此)。

2、它使内容保持新鲜
一个好的排名算法的第二个属性是,它优先考虑新的内容。如果做得好,这意味着每次用户进入平台时,他们都会有新鲜的东西(希望是好的)来阅读或互动。这种平衡(我们将在后面探讨)是 "新鲜度 "和 "质量 "之间的权衡。

3、它调整了 "Katamari卡塔玛里球 "效应
一旦一个帖子在Twitter、Hacker News、Reddit或任何其他非平台上传播,它就有可能形成一个 "Katamari球",因为它有加分项(这意味着它得到更多的加分项,因为它有更多的加分项,这意味着......好吧,你懂的)。这也被称为 "网络效应",但我觉得Katamari球更好地说明了这一点。这些帖子通常比其他提交的帖子有几个数量级的加分。这是否意味着它有几个数量级的价值?也许吧,但为了新鲜感,我们需要对它进行不相称的降级,而不是把它粘在聚合器的顶部,但是时间老了,是其他好帖子的100到1000倍。

4、它避免了错误的否定
如果一个质量不错的投稿没有得到任何关注,并且在没有人阅读的情况下衰减,那么它就被认为是 "假阴性"。Hacker News在这方面特别糟糕,因为Newest并没有得到很多关注。就我个人而言,每当我完成一篇文章,我把它发到Hacker News上,就会听到蟋蟀的叫声,但几天后却看到我的帖子被别人发到头版上的趋势。他们知道什么而我不知道?这是一个时间问题吗?

一个好的算法会在保留质量的同时,努力减少假阴性的数量。这是一个难以取舍的问题。

5、它在计算上是友好的
在这种情况下,计算友好意味着:它不会使你的服务器崩溃。从本质上讲,该算法受到可用计算资源的限制。Facebook有大量昂贵的服务器,因此,可以运行机器学习算法,为你的愤怒进行优化,同时向你出售鞋子。在较小的情况下(如Bear),这意味着我最好是将其作为一个SQL查询来运行。

黑客新闻的算法
这个算法相当直截了当(尽管在涉及到审核、影子禁言和帖子钉子的时候,表面下有一些魔法)。

Score = Upvotes / Time since submission ^ Gravity

Where Gravity = 1.7

分数 = 支持率 / 提交后的时间 ^ 权重

其中权重 = 1.7

随着支持率的积累,分数会上升,但会被提交后的时间所抵消。随着时间的推移,重力使得排名的难度成倍增加。

这可以作为一条简单的SQL语句来运行:

SELECT 
post.id,
post.upvote_count,
post.published_date
    (
        (
            post.upvote_count / (

                    EXTRACT(
                        EPOCH
                        FROM (
                                STATEMENT_TIMESTAMP() - post.published_date
                            )

                ) ^ 1.8
            )
        )
    ) AS "score"
FROM posts
ORDER BY
"score" DESC

在Hacker News的背景下,这实际上已经满足了一个体面的排名算法的大部分要求(除了错误的负面因素)。然而,它并没有向下扩展,正如我们在后面看到的Bear。

Reddit的 "热门 "算法
同样,Reddit用一个民主系统对帖子进行排名(使用向上和向下的投票),然而在计算分数的时间时,它被颠覆了。它不使用自发布以来的时间,而是使用自最古老的帖子日期时间以来的12.5小时的间隔数(我们将挖掘这一点)。帖子随时间推移的算法衰减是通过使用加分和减分之和的对数来处理的,这也修正了由于Katamari球效应造成的加分的放大性质。

同样,为了简洁起见,我已经简化了这一点。

Score = log(Upvotes - Downvotes) / (EpochSeconds - 1134028003) / 45000

Where:
EpochSeconds = number of seconds since Jan 1, 1970 to the published date/time
1134028003 = Unix timestamp for the oldest post (essentially the birth of the platform)
45000 = 12.5 hour interval (originally this was 25 hours)

分数 = log(Upvotes - Downvotes) / (EpochSeconds - 1134028003) / 45000

其中。
EpochSeconds = 自1970年1月1日到发表日期/时间的秒数
1134028003 = 最早的帖子的Unix时间戳(基本上是平台的诞生时间)
45000 = 12.5小时的间隔(原来是25小时)。

简而言之,一篇文章的积分必须是比它早12.5个小时的东西的10倍,才能超过它的排名。

Reddit的评论算法
Reddit使用一个与帖子不同的系统对其评论进行排名。考虑到评论不应该受到时间的影响,而应该按照有用性进行排名,这是有道理的。我在此不做详述,因为它不适用于这篇文章,但我认为这很有趣。你可以在这里读到它。

1、bear的约束
那么,对于比Reddit或Hacker News流量小得多的Bear来说,什么才是理想的算法,但又需要考虑到来自这些平台的巨大的、不经常涌入的加注?

2、第一次尝试
第一次尝试是对Hacker News算法的纯SQL实现,并做了一些轻微的修改。它在一年多的时间里运行得相当好。你可以在 here看到它与以下算法的运行。

Score = (Upvotes - 1) / (Time in hours + 4) ^ Gravity

Where Gravity = 1.2


你会马上注意到它的问题。在前三页有几个帖子比其他帖子有几个数量级的支持率,并且在那里停留了一年之久。增加引力解决了这个问题,但代价是降低了帖子的整体质量,因为像样的帖子(属于10-20票的范围)也会更快地被废弃。这使得权衡变得有点困难,因为我们希望那些老的帖子被删除,同时在页面上保持较低票数(但高于平均值)的新鲜帖子。

3、第二次尝试
第二次尝试非常直接,利用Reddit的 "热门 "算法来获得灵感,我在最高支持率的数量上加了一个对数,得到如下结果。

Score = log(Upvotes) / (Time in hours + 4) ^ Gravity

Where Gravity = 1.1

这里的问题是,现在有2种形式的帖子得分衰减,即重力和对数的上升引力。这导致所有的帖子都很快地从主页上射下来(因此重力减少)。这些值可能会被调整得很好,但我在玩这个的时候遇到了一个问题:查询需要一些时间来完成,有时长达几秒钟。

这更像是一个数据库优化的问题,但在这个项目的 "计算友好性 "约束范围内,因为我对做花哨的数据库东西没有兴趣(我是个ORM婊子)。每次有人浏览发现页面时,数据库查询必须从一个单独的表中整理每个帖子的所有加分项,确定一个分数,并返回查询集。这在计算上是很昂贵的,而且我在一个便宜的服务器上运行。

4、第三次尝试(我对它相当满意)
第三次尝试从Reddit的算法中得到了很大的启发。每当一个帖子被加注,它的分数就会被重新计算(而不是在查看发现信息时重新计算所有的分数)。这意味着我无法获得发现频道提交后的时间,而是使用发布时间和过去某个任意日期之间的差值。该算法如下。

Score = log(Upvotes) + (Seconds / Days modifier * 8600)

Where,
Seconds = Seconds since Jan 1st, 2020
Days modifier =  14

这里我们可以看到,对数主要是防止卡塔玛里球效应。我还选择了加入自2020年1月1日(我开始养熊的那一年)以来的双周数作为确定新鲜度的方法,因为较新的帖子会有较多的双周数。由于这个分数是在每次上调票数时计算和存储的,所以计算的开销可以忽略不计,而且这个算法的效果也很好。基本上,每一个两周前的帖子需要有10倍于现在发布的帖子的支持率才能超越它。随着该平台变得更加流行,我可以将Days修改器减少到越来越短的时间间隔,以适应 "好 "帖子数量的增加。

更多点击标题

Jdon本站首页的Java排名代码