迄今為止,這個系列都在討論,如何給出"某個時段"的排名,比如"過去24小時最熱門的文章"。
但是,很多場合需要的是"所有時段"的排名,比如"最受使用者好評的產品"。
這時,時間因素就不需要考慮了。這個系列的最後兩篇,就研究不考慮時間因素的情況下,如何給出排名。
一種常見的錯誤演算法是:
得分 = 贊成票 - 反對票
假定有兩個專案,專案A是60張贊成票,40張反對票,專案B是550張贊成票,450張反對票。請問,誰應該排在前面?按照上面的公式,B會排在前面,因為它的得分(550 - 450 = 100)高於A(60 - 40 = 20)。但是實際上,B的好評率只有55%(550 / 1000),而A為60%(60 / 100),所以正確的結果應該是A排在前面。
Urban Dictionary就是這種錯誤演算法的例項。
另一種常見的錯誤演算法是
得分 = 贊成票 / 總票數
如果"總票數"很大,這種演算法其實是對的。問題出在如果"總票數"很少,這時就會出錯。假定A有2張贊成票、0張反對票,B有100張贊成票、1張反對票。這種演算法會使得A排在B前面。這顯然錯誤。
Amazon就是這種錯誤演算法的例項。
那麼,正確的演算法是什麼呢?
我們先做如下設定:
(1)每個使用者的投票都是獨立事件。
(2)使用者只有兩個選擇,要麼投贊成票,要麼投反對票。
(3)如果投票總人數為n,其中贊成票為k,那麼贊成票的比例p就等於k/n。
如果你熟悉統計學,可能已經看出來了,這是一種統計分佈,叫做"二項分佈"(binomial distribution)。這很重要,下面馬上要用到。
我們的思路是,p越大,就代表這個專案的好評比例越高,越應該排在前面。但是,p的可信性,取決於有多少人投票,如果樣本太小,p就不可信。好在我們已經知道,p是"二項分佈"中某個事件的發生機率,因此我們可以計算出p的置信區間。所謂"置信區間",就是說,以某個機率而言,p會落在的那個區間。比如,某個產品的好評率是80%,但是這個值不一定可信。根據統計學,我們只能說,有95%的把握可以斷定,好評率在75%到85%之間,即置信區間是[75%, 85%]。
這樣一來,排名演算法就比較清晰了:
第一步,計算每個專案的"好評率"(即贊成票的比例)。
第二步,計算每個"好評率"的置信區間(以95%的機率)。
第三步,根據置信區間的下限值,進行排名。這個值越大,排名就越高。
這樣做的原理是,置信區間的寬窄與樣本的數量有關。比如,A有8張贊成票,2張反對票;B有80張贊成票,20張反對票。這兩個專案的贊成票比例都是80%,但是B的置信區間(假定[75%, 85%])會比A的置信區間(假定[70%, 90%])窄得多,因此B的置信區間的下限值(75%)會比A(70%)大,所以B應該排在A前面。
置信區間的實質,就是進行可信度的修正,彌補樣本量過小的影響。如果樣本多,就說明比較可信,不需要很大的修正,所以置信區間會比較窄,下限值會比較大;如果樣本少,就說明不一定可信,必須進行較大的修正,所以置信區間會比較寬,下限值會比較小。
二項分佈的置信區間有多種計算公式,最常見的是"正態區間"(Normal approximation interval),教科書裡幾乎都是這種方法。但是,它只適用於樣本較多的情況(np > 5 且 n(1 − p) > 5),對於小樣本,它的準確性很差。
1927年,美國數學家 Edwin Bidwell Wilson提出了一個修正公式,被稱為"威爾遜區間",很好地解決了小樣本的準確性問題。
在上面的公式中,表示樣本的"贊成票比例",n表示樣本的大小,表示對應某個置信水平的z統計量,這是一個常數,可以透過查表或統計軟體包得到。一般情況下,在95%的置信水平下,z統計量的值為1.96。
威爾遜置信區間的均值為
它的下限值為
可以看到,當n的值足夠大時,這個下限值會趨向。如果n非常小(投票人很少),這個下限值會大大小於。實際上,起到了降低"贊成票比例"的作用,使得該專案的得分變小、排名下降。
Reddit的評論排名,目前就使用這個演算法。
[參考文獻]
* How Not To Sort By Average Rating
(完)