天天看點

Hacker News 排名算法工作原理

這篇文章我要向大家介紹 Hacker News 網站的文章排名算法工作原理,以及如何在自己的應用裡使用這種算法。這個算法非常的簡單,但卻在突出熱門文章和遴選新文章上表現的異常優秀。

Hacker News 排名算法工作原理

深入 news.arc 程式代碼

Hacker News是用Arc語言開發的,這是一種Lisp方言,由Y Combinator投資公司創始人

Paul Graham

創造。Hacker News的開源的,你可以在

arclanguage.org

找到它的源代碼。深入發掘 news.arc 程式,你會找到這段排名算法代碼,就是下面這段:

; Votes divided by the age in hours to the gravityth power.

    ; Would be interesting to scale gravity in a slider.

    (= gravity* 1.8 timebase* 120 front-threshold* 1

       nourl-factor* .4 lightweight-factor* .3 )

    (def frontpage-rank (s (o scorefn realscore) (o gravity gravity*))

      (* (/ (let base (- (scorefn s) 1)

              (if (> base 0) (expt base .8) base))

            (expt (/ (+ (item-age s) timebase*) 60) gravity))

         (if (no (in s!type 'story 'poll))  1

             (blank s!url)                  nourl-factor*

             (lightweight s)                (min lightweight-factor* 

                                                 (contro-factor s))

                                               (contro-factor s))))

本質上,這段 Hacker News采用的排名算法的工作原理看起來大概是這個樣子:

Score = (P-1) / (T+2)^G

其中,

  • P = 文章獲得的票數( -1 是去掉文章送出人的票)
  • T = 從文章送出至今的時間(小時)
  • G = 比重,news.arc裡預設值是1.8

正如你看到的,這個算法很容易實作。在下面的内容裡,我們将會看到這個算法是如何工作的。

比重(G)和時間(T)對排名的影響

比重和時間在文章的排名得分上有重大的影響。正常情況下如下面所述:

  • 當T增加時文章得分會下降,這就是說越老的文章分數會越底。
  • 當比重加大時,老的文章的得分會減的更快

為了能視覺呈現這個算法,我們可以把它繪制到

Wolfram Alpha

得分随着時間是如何變化的

Hacker News 排名算法工作原理

你可以看到,随着時間的流逝,得分驟然下降,例如,24小時前的文章的分數變的非常低——不管它獲得了如何多的票數。

Plot語句

:

    plot(

        (30 - 1) / (t + 2)^1.8, 

        (60 - 1) / (t + 2)^1.8,

        (200 - 1) / (t + 2)^1.8

    ) where t=0..24

比重參數是如何影響排名的

Hacker News 排名算法工作原理

圖中你可以看到,比重越大,得分下降的越快。

        (p - 1) / (t + 2)^1.8, 

        (p - 1) / (t + 2)^0.5,

        (p - 1) / (t + 2)^2.0

    ) where t=0..24, p=10

Python語言實作

之前已經說了,這個評分算法很容易實作:

def calculate_score(votes, item_hour_age, gravity=1.8):

    return (votes - 1) / pow((item_hour_age+2), gravity)

關鍵是要了解算法中的各個因素對評分的影響,這樣你可以在你的應用中進行定制。我希望這篇文章已經向你說明了這些

更新: Paul Graham 分享了修正後的

HN 排名算法

(= gravity* 1.8 timebase* 120 front-threshold* 1

 nourl-factor* .4 lightweight-factor* .17 gag-factor* .1)

(def frontpage-rank (s (o scorefn realscore) (o gravity gravity*))

(* (/ (let base (- (scorefn s) 1)

        (if (> base 0) (expt base .8) base))

      (expt (/ (+ (item-age s) timebase*) 60) gravity))

   (if (no (in s!type 'story 'poll))  .8

       (blank s!url)                  nourl-factor*

       (mem 'bury s!keys)             .001

                                      (* (contro-factor s)

                                         (if (mem 'gag s!keys)

                                              gag-factor*

                                             (lightweight s)

                                              lightweight-factor*

                                             1)))))