2012-01-13 62 views
0

我正在构建一个网站,让用户可以通过拖放来排列项目列表以对其“个人视图”进行排名。他们可以选择删除一个项目以将其隐藏起来,使其“隐私”。为多用户可排序列表建议排名算法

我的问题是我如何公平地实现一个排名算法,以确定一个共享视图的项目的排序不惩罚新项目。

这也可以帮助,如果这也可以用来排名的新项目将显示在用户的个人名单。

因此,如果有新项目出现,并且其他用户的排名很高,我们可以将其显示在我们预测用户将其排名与其他排名相关的位置。

我最初的想法是按用户排列的每个项目给用户排名列表中的位置。 (例如,如果有10个项目,给予等级1 10分,2 9等等,对用户隐藏的项目给予负分)。共享视图将根据总分进行排序。但对于那些基本上没有排名的新项目来说,这并不适用,并且不会轻易上移。

因此,对公平算法可以预测新项目的任何想法?

+0

Ravloony的评论让我更好地思考了这个问题,这里是我认为可行的算法。 当用户对列表进行排序时,给每个项目一个分数=项目数+ 1 - 项目列表/项数中的排名。 (3中的1 = 1,2中的3 = 0.667,2中的2 = 8)。 项目分数是所有用户分数的平均值。 因此,随着更多项目的添加,排名较高的较新项目将浮动到顶部。 这应该在一般情况下工作,但会使新条目很容易排名很高,评分很少。有关如何添加排名数量的权重的任何想法? – mtelligent 2012-01-13 18:58:23

回答

1

所以我想我有一个工作解决方案。通过结合我在问题评论中提到的方法和Wilson's score confidence interval for a Bernoulli parameter的下限,得分似乎与我的预期一致。

所以要重新评论我的评论方法:用户物品评分=物品数量+ 1 - 物品列表/物品数量中的等级。 (3中的1 = 1,2中的3 = 0.667,2中的2 = 8)。

给出整体项目评分I插入Wilson公式: (phat + z * z /(2 * n)-z * Math.sqrt((phat *(1-phat)+ z * z/(4 * n))/ n))/(1 + z * z/n)

其中phat =分数的平均值,n是排名数,z = 1.96(对于95%的置信度排名)。

我在Excel中嘲笑了一些数据,并在不同场景中玩过并喜欢上了结果。将转向实施。感谢您的帮助

+0

你能否详细说明当你通过Z?时你的意思是什么? – AhmadAssaf 2012-03-01 12:44:31

0

如何实现类似于9gag排名系统的东西。您可以拥有一个显示最高排名项目的共享页面和一个投票页面,用户可以在其中查看新项目并对其进行排名。

+0

不要认为这种方法适合。该网站将有多个主题,并且每个主题都可以包含可添加到的项目列表。这个页面将使用jQuery排序来允许用户以任何他们喜欢的方式为他们的“个人”视图排序列表,但他们可以切换到共享视图或新视图。即使对于个人观点,我也想预测将新项目放在哪里,因为它将成为先前对项目进行分类的用户的默认视图。 – mtelligent 2012-01-13 16:48:33

0

我认为这里的重要一点是要看看其他用户的排名与其他项目的关系。

“这个项目是经常排名第三”是没有用的,我想,而“下的审议项目(我们称之为A)是排名优于项目B大部分时间”,因为它可以让你创建一个(可能是模糊的)你正在考虑的项目清单的排序。

实质上,对于用户列表中的新项目,您可以实施一种插入排序,其中两个元素的比较由其他人列表中的平均顺序决定。事实上,只要它依赖于两个给定元素之间的顺序,任何排序算法都可以工作。

+0

所以这意味着我可以计算一个项目的分数,通过平均等级(6的10个百分比中的3个对比2个中的2个),并且使用它来计算它如何与其他物品堆叠有更多的排名? – mtelligent 2012-01-13 16:56:18

+0

那么我的意思是,当你比较每对物品时,你计算出其他用户的排名是否高于其他用户。但事实上,这可能会过于昂贵。然而,考虑到系统是动态的,计算每个元素的分数也很困难,所以您很多时候都必须重新计算很多分数。 – 2012-01-13 17:09:51

0

这里是我对Wilson节点中Bernoulli参数的置信区间。js

wilson.normaldist = function(qn) { 
    var b = [1.570796288, 0.03706987906, -0.0008364353589, -0.0002250947176, 0.000006841218299, 0.000005824238515, -0.00000104527497, 0.00000008360937017, -0.000000003231081277, 0.00000000003657763036, 0.0000000000006936233982]; 
    if (qn < 0.0 || 1.0 < qn) return 0; 
    if (qn == 0.5) return 0; 
    var w1 = qn; 
    if (qn > 0.5) w1 = 1.0 - w1; 
    var w3 = -Math.log(4.0 * w1 * (1.0 - w1)); 
    w1 = b[0]; 

    function loop(i) { 
     w1 += b[i] * Math.pow(w3, i); 
     if (i < b.length - 1) loop(++i); 
    }; 
    loop(1); 
    if (qn > 0.5) return Math.sqrt(w1 * w3); 
    else return -Math.sqrt(w1 * w3); 
} 

wilson.rank = function(up_votes, down_votes) { 
    var confidence = 0.95; 
    var pos = up_votes; 
    var n = up_votes + down_votes; 
    if (n == 0) return 0; 
    var z = this.normaldist(1 - (1 - confidence)/2); 
    var phat = 1.0 * pos/n; 
    return ((phat + z * z/(2 * n) - z * Math.sqrt((phat * (1 - phat) + z * z/(4 * n))/n))/(1 + z * z/n)) * 10000; 
}