以前 SegmentFault 的熱門內容算法沒有考慮到時間因素,致使熱門內容更新較慢,新的熱門內容排不上位,因此最近對這塊作了一些改動,主要參考了阮一峯老師的關於網站熱門內容排序的一系列博客:html
這幾篇文章對於網站熱門內容的計算研究有很好的指導做用,很是值得拜讀。blog
言歸正傳,來講說 SegmentFault 的熱門算法。排序
對於熱門文章,使用了以下公式:圖片
$$ \frac{lg(views) * 4 + recommendScore + collectScore + ln(articleComments)}{(age/2 + update/2 + 1) ^ i}
$$
其中
views:瀏覽量,對瀏覽量作了一次去對數處理,主要是爲了防止某些瀏覽量較大的文章異軍突起,待在榜單遲遲不動。
recommendScore / collectScore:文章的推薦數和收藏數,直接加和到分子中,做爲文章熱門程度的考慮因素。
articleComments:文章評論數,這個也做爲一個影響文章熱度的因素,不過爲了下降其影響,對其做了一次取對數操做,主要是考慮到評論數量的影響力並無上面兩個的高。
(age/2 + update/2 + 1) ^ i:分母是對時間因子的考慮,宏觀上來看,就是文章熱度和建立時間成反比。細節上,作成了個指數函數,能夠經過對 i 變量的調控來改變時間因子在對熱度的影響。
age:內容發佈時間
update:內容最後更新時間(全部時間值單位均爲 h/3600)
i:重力因子,取值的大小會直接決定熱門排序(後面將介紹這點)
對於熱門問答,使用了以下公式:
$$
\frac{lg(views) * 4 + sum(Qanswers * anwserScores + Qscore) / 5 + ln(commentSocres)}{(age/2 + update/2 + 1) ^ i}
$$
熱門問答的計算參考了 Stack Overflow 對於回答數量和問題得票數的處理。同時,結合咱們的實際,將評論的得票數也作爲一個因素加入計算。
Qanswers / Qscore:分別是問題的答案數量和問題的得票數
anwserScores / commentSocres:分別是該問題下全部答案的總得票數和全部評論的總得票數
update:該問題下答案的最新更新時間
其他的變量含義和文章算法相同。
首先要明確各種不一樣熱門內容的目的。
日熱門的主要目的就是突出最近一天內的熱門內容,更方便於內容被你們看到,文章快速地造成討論、受關注的問題儘快獲得解決;
周熱門的主要目的很明確,就是突出過去一週內的熱門內容,同時,給新產生的優秀內容機會,讓其有機會進入熱門列表;
月熱門同周熱門目的同樣,但更須要給新內容進入列表的機會,以讓內容常常更新。
因此,該怎麼作呢?
對於同一內容,上面的計算公式都可化簡爲
$$ \frac{s}{t^i} (s 是總得分指標,t 爲時間量,i 是變量重力因子) $$
能夠看出,其熱度和建立時間成反比,那麼這個反比的值最終就由重力因子 i 來影響。
日熱門爲了突出新熱內容、過濾時間太久的熱門內容,須要增大重力因子,儘量排除 24 小時以外的熱門內容;周熱門和月熱門則須要按時間要求依次逐漸降小 i 值。
關於指數 i 值的選定,採起了估算:繪製出必定範圍內時間和文章熱度的指數函數的圖,而後根據需求挑選知足本身條件的指數值。以下圖
屢次估值測試,最終分別將日、周、月的 i 值選取爲 1.0、0.五、0.3。
開始修改熱門算法的時候,並無收到計算周熱門、月熱門的需求,因此直接很暴力的將時間因子加入進去,這樣的確可以知足需求,能夠保證熱門的內容隨着時間的推移保持更新,而不會出現以前的某幾篇文章的熱度一直保持恆定,穩居榜首。
後來須要計算區間內的熱門內容時,仍然使用開始的方案,由於時間因子的關係,會致使區間內的熱門內容受時間的影響太大,出現的問題就是周熱門、月熱門榜首的內容依然是最新產生的內容佔比重較多,因此才考慮對分母的時間因子作了動態調節的方案,也就是將分母的指數根據計算不一樣的區間,給出不一樣的值(但未找到更合適的取值方法,只能屢次估值)。
咱們目前的算法仍有須要完善之處,重力因子 i 的取值依舊是難點,你們若是有更好的方法,歡迎討論。