天天看點

牛頓冷卻定律在得到APP的實踐

作者:閃念基因

背景介紹

「得到錦囊」産品剛上線時,該版塊首頁的最熱排序暴露了兩個問題:分頁時資料重複和最熱榜單被霸屏,本文将圍繞解決這兩個問題來展開,介紹下如何參考牛頓冷卻定律來優化最熱内容的排序。

“牛頓冷卻定律”本質上它描述了高于周圍溫度的物體會向外散熱,并逐漸降溫的過程,同時機關時間内散熱與周圍溫差會成正比關系。通過建立”溫度”與”時間”之間的函數關系,建構一個”指數式衰減”(Exponential decay)的過程。

如果我們把”熱文排名”想象成一個”自然冷卻”的過程,那麼如下的場景是成立的:

  • 任一時刻,網站中所有的文章,都有一個”目前溫度”,溫度最高的文章就排在第一位。
  • 随着時間流逝,所有文章的溫度都逐漸”冷卻”。

一、最熱榜單暴露的問題

2020年1月初,得到App的新産品「得到錦囊」正式上線。産品剛上線時,版塊首頁的最熱排序子產品,暴露出了兩個問題:分頁時資料重複和最熱榜單被霸屏,本文将圍繞解決這兩個問題來展開。

排序規則與樸素的實作方案

産品需求定義的最熱排序規則是:按照問題的總檢視量來倒序排列,且有分頁和查詢條件。服務端對于這種場景,最簡單高效的實作方式,就是利用sql的query語句了,于是我們就直接 [order by {問題的檢視量} desc] 來實作了。

總檢視數 = 獲得檢視權益的使用者數 = 購買數 + 贈一得一領取數

這個簡單樸素的實作方式,再加上緩存政策,使得我們用較小的成本就滿足了産品需求,也應對了較高的流量。

牛頓冷卻定律在得到APP的實踐

按檢視量的最熱排序

得到錦囊(原問答)的産品定位,和知乎、頭條的不太一樣,不僅對于提問的内容進行嚴格稽核,對于老師們的解答内容也是會按照标準來品控,是以我們上新的速度并不會很快。等未來釋出的問題數量大了以後,肯定是會啟用基于大資料的個性推薦算法的,但是擺在眼前的兩個問題,必須要盡快解決。

說明:在2020-03月底的版本中,【得到問答】正式改名為【得到方案】。在2020-04月初的版本中【得到方案】改名為【得到錦囊】,為使用者提供更為全面的知識服務。時間和精力的關系,本文中的一些文字和圖檔不進行全量更新了。

問題一 : 分頁時會出現重複資料

分頁時資料重複,在性質上是個bug,得優先解決。

利用sql的order by 和 limit 對行資料進行排序和分頁時,最正确的姿勢的是基于至少一個固定的字段值。排序值變化頻繁,db加載下一頁資料的時候如果上一頁某條行記錄的排序值發生了變化,就很可能會導緻上一頁中出現過的記錄在下一頁再次出現。我們最熱排序的依據【總檢視數】就是個變化頻繁的值,加上我們對每頁的結果資料都使用了緩存政策,使得資料在不同的頁面出現的幾率加大。

通過一些算法政策的調整,比如緩存的key值和查詢條件增加了時間視窗,我們降低了資料被重複展現的機率,低到使用者幾乎無察覺,低到讓自己也以為徹底解決了問題。

上新的内容接近百條的時候,新的問題暴露了。春節前的某一天,老闆、産品經理、營運都分别吐槽了“最熱榜單被霸屏”的問題,希望能有所優化,每天能呈現不同的熱點内容 。于是,我們調整了排序語句,在其中加入了最近被檢視時間的參數,踩着“知識春晚封版”最後上線的時間點完成了上線。很有效,最熱榜單活了,每個小時都會變化,很多問題都有了更多露臉的機會,包括在多個頁面反複露臉……

資料重複的幾率增高了,高到産品經理和測試都發現了,居然還錄屏為證 (ಥ﹏ಥ)

如下是其中的一個執行個體截屏,我們能看到問題《28歲碼農,不想做管理崗,又擔心以後失去競争力,怎麼辦?》在兩個頁面出現。

牛頓冷卻定律在得到APP的實踐

分頁時資料重複1

牛頓冷卻定律在得到APP的實踐

分頁時資料重複2

問題二 : 最熱榜單被霸屏

我們的新内容是以每天5~10個的頻率來釋出上線的,使用者對于内容的喜好和曝光率會直接影響被檢視的數量和排序。

産品上線沒多久,排名靠前的榜單就被上線較早且又被關注較多的幾條問題占據了,後面新上線的問題,曝光的機會很低。如果按照剛上線時的排序算法,下面幾條問題幾乎會持續霸屏:

牛頓冷卻定律在得到APP的實踐

霸屏的熱點問題

我們的營運發起了一些專題的促銷活動,才足以打破了上面的局面。但是,我們是不能對每個問題方案都進行營運活動來拉動銷量,更多的還是順其自然,交給使用者去選擇,讓内容靠實力去競争。

“長尾效應”的理論告訴我們,非熱點内容的累計銷售數量,一定是高于幾條熱點内容的累計銷售數量的,是以我們要解決被霸屏的現象,讓更多的内容能夠有機會登上熱榜去“抛頭露面”。

二、問題解決方案分析

1、 分頁時會出現重複資料

問題出現的原因是排序所依據的鍵值變換頻繁,導緻翻頁語句在執行時資料已經發生了變化。我們需要找到一個可以用于排序的值,一個即能根據熱點趨勢及時變化,又相對固定不變的值。

開始時,覺得挺沖突的,解決了一個問題卻加劇了另一個問題,直到發覺這個排序值可以和解決最熱榜單霸屏問題使用一個值,思路就開始打開了。

2、 最熱榜單被霸屏

嘗試了把問題的被檢視時間參與到排序規則中,使得排序可以每個小時重新整理1次。上線後,榜單是真的變了起來,最新被檢視的問題能夠浮上來,但是當熱門問題也被檢視後依然會霸屏。

這個改良版的排序方法,其實就是文末參考資料中描述的Delicious算法的思路,這是最直接、最簡單的算法,按照機關時間内使用者的投票數進行排名,得票最多的項目,自然就排在第一位。

這個算法的優點是簡單、容易部署、内容更新快;缺點是,一方面,排名變化不夠平滑,前一個小時還排名靠前的内容,往往第二個小時就一落千丈,另一方面,缺乏自動淘汰舊内容的機制,某些熱門内容可能會長期占據排行榜前列。

最熱榜單開始變化的幾天中,營運從資料上檢視,問題的整體通路情況要好于調整之前,雖然由于使用姿勢不正确帶來了資料重複的bug,但證明最熱榜單的排序動起來是很有意義的。在咨詢公司大資料的專業人士“溥神”後,給我們推薦了業内解決這種問題的通用算法之一“牛頓冷卻定律”,開始更科學的解決這個問題。

定律的解讀

偉大的實體學家牛頓,早在17世紀就提出了溫度冷卻的數學公式,被後人稱作”牛頓冷卻定律“(Newton’s Law of Cooling)。

牛頓冷卻定律在得到APP的實踐

牛頓冷卻定律

牛頓冷卻定律有廣泛的用途。例如,人死亡以後溫度調節功能随即消失,是以借助于由正常體溫(約為37攝氏度)與環境溫度的比較,利用這個定律,就可以判定死亡的時間。

舉個實際計算的例子。某冬晨,警察局接到報案,在街頭發現一具屍體。在6點30分的時候,測量其體溫為18攝氏度,到 7點30分已下降到16攝氏度。假設室外氣溫維持在約10攝氏度不變,而且設人體正常體溫是37攝氏度,問這個人是什麼時候死的?

牛頓冷卻定律在得到APP的實踐

死亡時間

【來自得到電子書《不可思議的自然對數》】

如果我們把”熱文排名”想象成一個”自然冷卻”的過程,那麼如下的場景是成立的:

  • 目前溫度。任一時刻,網站中所有的文章,都有一個”目前溫度”,溫度最高的文章就排在第一位。
  • 冷卻。随着時間流逝,所有文章的溫度都逐漸”冷卻”。
  • 加溫。如果一個使用者對某篇文章投了贊成票,該文章的溫度就上升一度。

上面的這種場景,概括起來就是新的内容總是會替代老的内容,而它又恰好類似于實體學當中的“牛頓冷卻定律”。本質上它描述了高于周圍溫度的物體會向外散熱,并逐漸降溫的過程,同時機關時間内散熱與周圍溫差會成正比關系。這樣假設的意義,在于我們可以照搬實體學的冷卻定律,使用現成的公式,建立”溫度”與”時間”之間的函數關系,進而建構一個”指數式衰減”(Exponential decay)的過程。

結論

物體的冷卻速度,與其目前溫度與室溫之間的溫差成正比,我們可以參考牛頓冷卻定律建構問答最熱排名的算法。新加一個用于排序的值,俗氣點就叫熱度值(hot value),這個值周期性的更新規則。

三、影響因素與實踐過程

由于問答已經有了”最新上架“的榜單,我們的”最熱“榜單不需要重點關注新上架内容的曝光,是以也就不需要完全采用定義一個初始溫度來逐漸降溫的模式。

牛頓冷卻定律在得到APP的實踐

最新榜單

問答的最熱榜單,希望能根據使用者最近的實際檢視量(例如前一天的檢視量),同時結合上架時間的因素,來決定今天的熱度排序。于是我們重點關注決定降溫趨勢的時間因子,使用者行為的加溫值,由此來計算熱度值,公式入下:

熱度值 = 加溫值 * 時間因子

1、時間因子

無論對于使用者還是平台,顯然是不希望一直是同樣的内容霸占了排行榜或者清單的最前面位置的,而是希望不斷被更新的内容所替代。站在使用者的角度上,一方面當然是希望對于一些比較熱門的問題能夠及時看到,但另外一方面還是希望能不斷看到新的東西。

對于任一内容,在某一定時間段之後,排列順序能夠發生周期性的變化,内容的熱度需要随時時間的推移而慢慢衰減,這個周期就是降溫周期,在周期内最好能呈現出下面這樣的一種趨勢:

牛頓冷卻定律在得到APP的實踐

降溫趨勢

降溫周期,可以了解為重新整理文章熱度的時間間隔。具體的間隔多少則需要根據平台的内容量來确定,如果内容較多,希望盡快呈現新的内容給使用者,便可以把時間間隔設定的比較短;如果内容較少,則可以把間隔時間設定的比較長。截至到這篇文檔初次編寫的時候(2020-02-12 18:43),我們問答的數量是298,是以應該把間隔時間設定的長些,例如30天。

實踐:經過觀察和資料調試,把問答熱點問題的降溫趨勢定義在了30天,即我們新上線的問題從100°降到0°的時間為30天左右,在這期間所有上架的問題都有機會被加溫升上來。當天上架的問題,隻要被浏覽,那麼就可以優先級最高的機會被排到前面。

2、使用者行為的加溫值

如果隻是有上面提到的熱度因素,那麼可能會導緻的問題是,有很多相近或者同一時間段上架的問題,熱度值随着時間的推移降低的速度幾乎是一緻的,這就還會導緻内容的排名也基本上是一緻的。為了解決這樣的問題,還可以在除了初始熱度以外,引入問題被釋出後使用者對其産生的一些行為,常見的行為可以包括浏覽、評價、收藏、分享、點贊等。

目前我們在問題清單裡隻展示了檢視量,為了更容易被了解,我們先隻把檢視量當做加溫值。

實踐:在問題資訊的擴充表中增加一列來記錄昨日被檢視量(yesterday_count ),每天更新這個值,這樣根據準實時總檢視量和昨日總檢視量的內插補點,就能計算出當日的檢視量,作為計算熱度值的重要參數。

3、熱度值的計算

關鍵點:熱度因子和昨日被檢視量,直接決定了一個問題的熱度值,影響“最熱”排序。

熱度值的更新:目前定在了每天淩晨的2點鐘,直接用sql來計算更新。

版本1 、參考牛頓冷卻定律

熱度因子取一個和時間反比例縮小的值。這個版本,采用了如下的計算方式,問題會在35天左右衰減。

熱度因子factor = (1+ROUND(1 / (DATEDIFF(目前時間,首次被浏覽的時間) + 1),2) * 100)

加溫值 = 昨日浏覽量 = 總浏覽量 - 昨日浏覽量

熱度值 HotValue = 加溫值 * factor

牛頓冷卻定律在得到APP的實踐

降溫趨勢1

實際效果: 如下是初次寫稿時(2020-02-12 19:33)的一個線上問題top 10,從結果可以看到,前面的那幾個霸屏問題已經被排到了下面,新上架的問題按規則排到了前面。

牛頓冷卻定律在得到APP的實踐

霸屏問題得以解決

這個版本解決的問題

1、解決了分頁排序資料重複的問題。由于HotValue隻在固定的時間段更新,我們按照HotValue排序相當于按照了一個固定的值,是以出現重複資料的幾率大大降低,在2020-02-10日下午上線後,再沒有發現。

2、問題的熱度排序更加科學,增加了老問題的曝光幾率,看到了熱度降溫的效果,對于學習牛頓冷卻定律更有興趣了。

這個版本存在的問題

1、前期降溫過快

問題上架的第一天是100°,第二天就直接降到了50°,如果問題在第一天的加溫情況并不好(檢視量較低),那麼就會被排到後面。

2、冷卻期較長

35天左右才會降到0°,而産品經理希望以後能調整到15天左右試試,而這個版本的算法比較費勁,調整多次都達不到期望的效果。

版本1的實驗過程:

  • 2月8日 确定方案,添加基礎支撐的字段
  • 2月9日 記錄昨日檢視量,上線計算熱度值算法
  • 2月10日 更新了線上的排序政策

版本2、使用牛頓冷卻定律的公式改進

1、改進熱度因子

經過版本1的資料和經驗積累,最終求出了幾個适合問答現狀的值,即降到冰點天數和冷卻系數的定義。

熱度因子fac = ROUND(exp(-冷卻系數* DATEDIFF(目前時間,首次被浏覽的時間) * 24 ),2) * 100

30天的降溫趨勢圖如下,降溫趨勢将更加平滑了。

牛頓冷卻定律在得到APP的實踐

采用牛頓冷卻定律的30天降溫趨勢

提前計算了幾個适用的冷卻參數,當問題達到一定數量的時候,可以加快降溫的速度,這點是版本1所不具備的。

冷卻天數 冷卻系數
30天 0.0072
15天 0.014
10天 0.022

2、改進加溫因子

可以把留言數、收藏數等值加進來,實作類似如下的加溫值:

加溫值 = 浏覽量50% + 留言量20%+收藏量*30% ……

版本2的實施:

  • 2月21日,修改熱度因子的計算規則為版本2
  • 等正式釋出的問題數量接近1000時,可以考慮把冷卻天數縮短為15天

最後,我們看一張圖,2020-03-08女神節問題最熱榜單的排序情況。在第20條以後,我們看到上線超過30天熱度因子為0的幾個問題,由于昨日通路量增加到一定程度,也有機會上浮到前面了。

牛頓冷卻定律在得到APP的實踐

最熱榜單的效果

思考與結語

1、定律使用要結合實際的場景

牛頓冷卻定律是偉大的,但使用時要結合實際的場景,不能生搬硬套。

在算法剛上線時,我還是按照Delicious算法的慣性思路,覺得榜單要動起來就該讓榜單在一天中重新整理多次,結果由于新上線内容的熱度因子值較大,導緻最新和最熱榜單的排序在第1頁幾乎完全一樣,這樣的話最熱榜單意義就被打了折扣。

資料中的對牛頓冷卻定律的使用,都是定義一個初始熱度值再去逐漸降溫,而我們的産品中由于有了最新的榜單,也采用這種方式的話,也會導緻榜單資料重合。

2、最熱排序未來的優化方向

在内容的總量達到一定程度之前,可以由服務端對所有使用者統一規則排序展示,當到達一定規模後,毫無疑問,個性化的推薦算法就一定是更好的了。

在内容的數量接近1000個時,會把降溫的速度加快,15天後就降低到冰點。

牛頓冷卻定律在得到APP的實踐

15天降溫

3、牛頓冷卻定律适用的場景

通過閱讀資料和實踐,單就排序而言,個人覺得牛頓冷卻定律适用于投票政策以正方向為主的場景,例如浏覽、留言、收藏這些都是加溫行為,即使各個行為的權重不同,對于排序的影響都是正向的,唯一的負方向值就是時間。

如果打分排序的場景還需要同時考慮正方向和負方向的投票行為,牛頓冷卻定律就不太适用了。比如同一個内容,有的讀者覺得有幫助會頂一頂增加正值,有的讀者覺得沒意義會踩一踩增加負值,平台希望内容清單的排序規則,即考慮時間因素又結合使用者投票還要客觀公正,算法可就沒有那麼簡單了!

最後列舉列舉了一些相關的文章和參考資料,感興趣的讀者們可以繼續延伸閱讀。

  • https://baike.baidu.com/item/長尾效應/6352848?fr=aladdin 長尾效應
  • http://www.ruanyifeng.com/blog/2012/03/ranking_algorithm_newton_s_law_of_cooling.html 基于使用者投票的排名算法(四):牛頓冷卻定律
  • http://www.woshipm.com/pd/2970177.html 資訊流優化:牛頓冷卻定律的應用
  • https://www.ruanyifeng.com/blog/2012/02/ranking_algorithm_hacker_news.html 基于使用者投票的排名算法(一):Delicious和Hacker News
  • https://www.ruanyifeng.com/blog/2012/03/ranking_algorithm_reddit.html 基于使用者投票的排名算法(二):Reddit
  • https://www.ruanyifeng.com/blog/2012/03/ranking_algorithm_stack_overflow.html 基于使用者投票的排名算法(三):Stack Overflow
  • https://www.ruanyifeng.com/blog/2012/03/ranking_algorithm_newton_s_law_of_cooling.html 基于使用者投票的排名算法(四):牛頓冷卻定律
  • https://www.ruanyifeng.com/blog/2012/03/ranking_algorithm_wilson_score_interval.html 基于使用者投票的排名算法(五):威爾遜區間
  • https://www.ruanyifeng.com/blog/2012/03/ranking_algorithm_bayesian_average.html 基于使用者投票的排名算法(六):貝葉斯平均
  • 得到電子書《不可思議的自然對數》

#後端資料排序,最熱内容排序,牛頓冷卻定律的運用,自然冷卻算法

作者:韓宇斌

出處:https://blog.luojilab.com/2020/03/08/backend/sort-with-law-of-cooling/