提问人:RichW 提问时间:10/22/2010 最后编辑:skaffmanRichW 更新时间:3/23/2012 访问量:1259
有业力的加权投票系统
Weighted voting system with karma
问:
这个问题目前比编程更合乎逻辑。一旦我了解了我需要使用什么算法,我就会研究如何实现它。
我有一个数据库中的项目列表,需要由用户投票赞成或反对,以确定它们是否正确。目的是为每个项目提供一个百分比,以显示项目信息的可靠性。
有几个标准需要考虑。
- 投票不是绝对的 - 每个用户的投票权重取决于他们的业力。
- 用户业力应该根据他们的投票来计算 - 例如,如果用户提交了一个项目,而其他用户投票确认它是正确的,那么该用户的业力就会增加。如果用户投票支持某个项目,其方向与其他业力高的用户投票的方向相同,也可以给出业力。如果他们的投票方向与其他业力高的用户相反,他们的投票将被认为是不正确的,虽然这会降低项目的分数,但也会降低他们的业力水平,使他们在未来的投票中影响力降低。
- 用户可以投反对票,也可以投赞成票。
- 计算出的项目分数应考虑项目的年龄(随着时间的推移,分数会降低,因为项目可能会变得不那么可靠)。
有没有人对执行此操作的最佳算法有任何建议,或者关于如何在编程语言(例如 PHP)中实现这一点的任何提示?
答:
我假设在你的计算中,你只考虑项目的业力,你只考虑早期选民在投票时所拥有的业力,而不是他们当前的业力(可能自他们以来发生了变化),因为这将导致一个递归函数,它可能涉及所有项目和所有用户。
另一个假设是,业力确实是绝对的,但在进行新的投票时会重新计算,因为投票的频率低于观点。
我会存储所有用户的所有投票、他们在投票时所拥有的业力以及每个项目的投票方向。
最后的假设是:你不是在投票后立即向提交者添加业力,而是在一定的时间跨度之后。如果您立即添加它,提交者的业力会经常上升/下降,并导致您的系统出现严重抖动。
如果你得到新的投票,我会首先计算该物品的新业力,然后根据该物品的绝对业力变化向用户添加业力:
一个项目的业力是所有投票用户的业力的总和:例如,你有三票:一票赞成 50 票,一票赞成 150 票,一票反对 30 票。这将导致总业力为 170。所以该物品的业力为 +170。
一旦新用户投票,您就会使用新投票重新计算该项目的业力,同时考虑以下因素:(上一个示例)新用户投票给 10 个业力。该物品的新业力是+180。
物品的新旧业力的区别在于用户获得的业力:(上一个例子)用户的投票使物品的业力改变了 +10,因此用户获得了 +10 的业力(用于未来的投票)。这个想法的缺点是,高业力用户非常非常快地获得新的业力,所以你可能也应该在这里添加一些限制性 faktor (如对数)来正确缩放它。
由于您也想考虑物品的年龄,您可以根据年龄将获得的业力点数乘以系数(例如,如果物品超过 5 天,则用户根本不会得到任何业力:5 天 - 投票的时间跨度乘以更改的业力值)。
当然,这是您想要实现的系统的非常模糊的草稿,我不知道它是否符合您的想法。它可能也可以修改以添加其他因素:您可以通过以下方式确定相关性百分比:
(绝对正业/绝对负业):小于 1 的值比正业多,反之亦然。但是对于可靠的 % 值,您也需要一些值来比较(无论是常数还是其他计算)。
请先阅读: http://www.evanmiller.org/how-not-to-sort-by-average-rating.html
这是对伯努利参数的威尔逊得分置信区间的数学概念的介绍。
这篇文章是一本很好的入门书,介绍了如何使用用户的投票来计算一个真正有用且数学上合理的分数。这样做,你就已经领先 Amazon.com
然后,我认为你可能需要稍微调整一下这个公式。在该公式中,它使用 p 表示赞成票的分数。您可能需要更新 p 的公式,以反映投出该票的用户的业力。
最后,为了将年龄考虑在内,您将公式的结果乘以年龄乘数。例如,如果您希望结果每老化一天就变得不那么相关 1%,请将其乘以 0.99^age_in_days。
简而言之,这就是我要走的道路。希望这会有所帮助。
评论