威尔逊得分

如何评价知乎的回答排序算法?

知乎今天上线了新的回答排序算法。

你也许不会注意到太大的变化,毕竟旧版排序在大部分情形下效果也不错。因此,这次改进的目标,是更好地做到两点:

  1. 专业、严谨、认真的高质量回答,排序应该更靠前
  2. 新创作的优质回答,能更快地获得更好的排序

为了帮助大家更好的理解新的机制,我们先来看看改进前的排序存在哪些问题。旧版的算法简化后可以表示为:

1
得分 = 加权赞同数 - 加权反对数

注:用户在不同话题下的权重计算方法,可以参考我之前的回答「
知乎如何计算用户在某个领域下的权重?
」。

公式本身很朴素。事实上之所以到今天这个简单的公式仍然能保证大部分优质内容能够排到前面,主要是用户投票权重在发挥作用。虽然针对权重计算的优化仍然在持续进行,我们也很快遇到了一些算法上的瓶颈。

  • 当问题下有多个发布较早的回答获得高票时,新的回答即使质量很高,也很难在问题页上获得足够的曝光,难以积累更多赞同票

  • 一些误导性、煽动性的高票内容,即使同时也有很多反对票,仍然排在认真、严谨但票数相对较少的优质回答前面

  • 一旦回答的反对数超过赞同数,得分为负,就会显示在所有低票回答下面(可能有几百个)。即使内容经过作者修改,也几乎没有机会重见天日。

上述问题在专业领域内对参与讨论的用户造成的伤害尤其明显。这绝不是我们希望看到的。

新的排序机制在很大程度上解决了这些问题。如果想了解算法原理和相关细节,可以移步「如何评价知乎的回答排序算法?」,下文的说明中并不会涉及专业知识。

新排序算法(可以简称为「威尔逊得分」算法)的思想是,如果把一个回答展示给很多人看并让他们投票,内容质量不同的回答会得到不同比例的赞同和反对票数,最终得到一个反映内容质量的得分。当投票的人比较少时,可以根据已经获得的票数估计这个回答的质量得分,投票的人越多则估计结果越接近真实得分。

如果新一个回答获得了 1 票赞同 0 票反对,也就是说参与投票的用户 100% 都选了赞同,但是因为数量太少,所以得分也不会太高。如果一小段时间后这个回答获得了 20 次赞同 1 次反对,那么基于新算法,我们就有较强的信心把它排在另一个有 50 次赞同 20 次反对的回答前面。原因是我们预测当这个回答同样获得 50 次赞同时,它获得的反对数应该会小于 20。威尔逊得分算法最好的特性就是,即使前一步我们错了,现在这个新回答排到了前面,获得了更多展示,在它得到更多投票后,算法便会自我修正,基于更多的投票数据更准确地计算得分,从而让排序最终能够真实地反映内容的质量。

因此未来我们会看到更多新创作的优质内容,快速获得靠前的排序,低质内容则会长期保持在底部。(细心的你可能也想到了,并不是所有的回答最终都会获得很多投票,大体上获得投票总数较多的回答仍然会排在投票较少的回答前面。)

这次算法改进,仍然遵循此前公布的「知乎回答排序原则」。由于权重的计算方法没有公布,反对票也没有显示在页面上,因此出现低票回答在前高票回答在后是很正常的现象

投票权重的计算方法,很多用户非常关心。我们正好再次明确一下最重要的几点原则:

  • 在知乎上创作了专业、严谨、认真的高质量回答的人,应该在他/她擅长的领域里,有更大的判断力。权重则是这个判断力的体现。
  • 用户在一系列相关话题下发布的全部回答所得到赞同、反对、没有帮助票数决定用户在该领域下的权重
  • 问题添加的话题和
    话题父子关系
    决定问题归属的领域

对内容质量的判断,归根结底,是通过知乎社区中用户的集体智慧的选择而完成的,更具体则体现为每一次「赞同」「反对」「没有帮助」按钮的点击。新版排序机制所鼓励的,仍然是知乎从成立第一天就追求的:创作过专业、严谨、认真的高质量内容,并且得到社区认可的用户,在塑造社区未来的内容质量标准和其他社区共识的过程中,他们能发挥的作用也更大。

回想一下,是否有那么一些时候,你面对某个排序并不理想的问题页皱紧眉头,感觉自己的一票对排序结果的影响微乎其微而深感无力。新版排序算法结合话题权重,相比过去能够做到对每一次投票做出更迅速的反应。不试试看又怎么知道呢?

知乎如何对回答进行排序?你的每一次投票都很重要。

查看原文

如何评价知乎的回答排序算法?-精彩回答

这个算法中用来做排序依据的得分的更严谨的名称是「二项分布样本的威尔逊置信区间下界」。计算公式是在 1927 年由数学家 Edwin B. Wilson 发展得到的 [1],用来对二项分布进行参数估计。2009 年芝加哥的软件工程师 Evan Miller 提出 [2],可以用威尔逊置信区间的下界对具有正负双向投票的系统进行排序。在我最初通过煎蛋的介绍 [3] 了解到这个算法时,便立即被它的很多优良特性所吸引:

  • 投票总数增加时,得分趋向于正向反馈占总反馈的比例,对于内容质量有较强的解释性。
  • 在总票数较少(个位数投票)和极端参数(真实比例接近 0 或 100%)的情形下,结果也能具有较高的准确性。
  • 置信区间大小可以通过参数控制。
  • 虽然二项分布是离散模型,但是由于得分表达式关于正负反馈次数的函数是连续的,因此可以引入非整数的投票(加权投票),同时不改变算法性质。
  • 得分的取值范围是 (0,1),与投票总数无关。因此可以间接地用来对不同问题下的回答做归一化的质量比较。

下面这两张图可以比较直观地显示威尔逊得分算法的几个重要特性。

20190905204359.png

为方便讨论,依次称左图中 up-vote, down-vote, score 对应的轴为 x,y,z 轴。右图为左图的等高线图。

左图的整体曲面形状,与通常理解中赞同票、反对票和回答质量的对应关系是相符的。固定反对票,赞同票越多得分越高;固定赞同票,反对越多得分越低;固定赞同与反对的比例,总票数越高得分越高。

总投票数较少时,回答如果获得投票,得分会快速增加,总票数越大增加速度越慢。体现为垂直 y 轴的平面截得的曲线斜率对 x 恒正且单调下降。同时,赞同数较高的回答,开始获得反对票时,得分会快速下降,总反对数越大下降速度越慢。垂直 x 轴的平面截得的曲线斜率对 y 恒负且单调上升。

对老版算法,对应函数 z = x - y,也不难画出上面两个图(这么简单的表达式,相信很多人闭上眼睛就已经把图画出来了)。老版算法的得分曲面实际为平面,因此各种截线都是平行直线(斜率为固定常数),右图等高线也是平行直线。

相对而言,新版算法对应的等高线图,等高线比老版更密集 [4],因此跨越等高线更容易。这也是新排序机制的上线说明中,我们说新算法能够做到对单次投票更加敏感的根本原因。

另一方面,函数曲面连续光滑,使得这个算法可以很好的处理浮点数投票,支持知乎已有的用户话题权重机制。二者有机结合,让回答排序更符合真实的内容质量。

当然,使用威尔逊得分来决定排序也远非完善。不同的回答获得投票的能力不同,这一点受很多因素影响,包括作者的文风、内容是否属于专业领域等。这些差异目前还没有在算法中得到体现。

另一个问题是,算法在 x = 0 时函数取值收敛为 0,无法对赞同为 0 但有不同反对票数的回答进行排序。我们的处理方式是默认所有回答者对自己的回答投了一票赞同。这样不仅解决了这个问题,还能让回答者的权重参与到排序的计算中。

威尔逊得分是一个简单强大,但是价值还没有被充分发掘的算法。至今,世界范围内应用了这个算法的著名网站仍然寥寥无几 [5]。近几年开始见到一些应用较广的开源库支持威尔逊得分,关于它的讨论似乎也在逐渐增加 [6],还是很让人开心的。我也希望借此次知乎排序算法升级,把这个算法介绍给更多国内的团队,希望能对大家有所助益。

下面是利用威尔逊得分是一个扩展:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<?php

define('STRATEGY_BASIC', 1);
define('STRATEGY_WILSON_SCORE', 2);
define('STRATEGY_SCORE_WEIGHT', 1000000);
define('DEFAULT_ZA', 21);

/**
* ${STATIC} calc_reply_or_comment_score
* @desc:
* @param $intU
* @param $intV
* @param $intID
* @param $intTime
* @param int $intSwc
* @param int $intZa
* @return int
*/
function calc_reply_or_comment_score($intU, $intV, $intID, $intTime, $intSwc = STRATEGY_BASIC, $intZa = DEFAULT_ZA) {
if (empty($intTime)) {
$intTime = time();
}

$intScore = 0;
switch($intSwc) {
case STRATEGY_BASIC: {
/// 公式一
/// 赞同率
$intN = $intU + $intV;
$fScore = ($intN > 0) ? ($intU / doubleval($intN)) : 0;
$intScore = intval(STRATEGY_SCORE_WEIGHT * $fScore);
break;
}
case STRATEGY_WILSON_SCORE: {
/// 公式一
/// 威尔逊得分
$intN = $intU + $intV;
if ($intN > 0) {
$fP = $intU / doubleval($intN);
$intZa2 = $intZa * $intZa;
$fScore = ($fP + $intZa2 / (2 * $intN) - $intZa / (2 * $intN) * sqrt(4 * $intN * (1 - $fP) * $fP + $intZa2)) / (1 + $intZa2 / $intN);
$intScore = intval(STRATEGY_SCORE_WEIGHT * $fScore);
}
break;
}

}

$bitTime = $intTime & 0x1FFFFFF;
$bitThumb = $intScore & 0xEFFFFF;
$bitReplyId = $intID & 0xFF;
$score = $bitReplyId | ($bitTime << 8) | ($bitThumb << 33);

return $score;
}


// demo
$intID = 0;
for ($intU = 0; $intU < 10; $intU++) {
for ($intV = 0; $intV < 10; $intV++) {
$intID++;
$score = calc_reply_or_comment_score($intU, $intV, $intID, time(), STRATEGY_WILSON_SCORE);
echo "U={$intU},V={$intV},score={$score}\n";

}
}

Binomial proportion confidence interval
How Not To Sort By Average Rating
Reddit的评论排序新算法
威尔逊得分 Wilson Score 排序算法-简书
如何评价知乎的回答排序算法?


来源:http://leunggeorge.github.io/

0%