2012-01-13 46 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; 
}