推模式也有如下的不足:
- 大量的寫操作:每一個粉絲都要寫一次。
- 大量的冗余存儲:每一條內(nèi)容都要存儲N份(受眾數(shù)量)。
- 非實時:一條內(nèi)容產(chǎn)生后,有一定的延遲才會到達(dá)受眾Feed中。
既然兩者各有優(yōu)劣,那么將兩者結(jié)合起來呢?一種簡單的結(jié)合方案是全局的:
- 對于活躍度高的用戶,使用推模式,每次他們刷新時不用等待太久,而且內(nèi)容頁相對多一些。
- 對于活躍度沒有那么高的用戶,使用拉模式,當(dāng)他們登錄時才拉取最新的內(nèi)容。
- 對于熱門的內(nèi)容生產(chǎn)者,緩存其最新的N條內(nèi)容,用于不同場景下拉取。
還有一種結(jié)合方案是分用戶的,這是Etsy的設(shè)計方案:
- 如果受眾用戶與內(nèi)容產(chǎn)生用戶之間的親密度高,則優(yōu)先推送,因為這個內(nèi)容更可能被這個受眾所感興趣。
- 如果受眾用戶與內(nèi)容產(chǎn)生用戶之間的親密度低,則推遲推送或者不推送。
- 也不是完全遵循親密度順序,而是采用與之相關(guān)的概率。
在中小型的社交網(wǎng)絡(luò)上,采用純推模式就夠用了,結(jié)合的方案可以等業(yè)務(wù)發(fā)展到一定規(guī)模后再考慮。
一個推模式的Feed發(fā)布實現(xiàn)很簡單:
- 一個集中存儲所有動態(tài)內(nèi)容的數(shù)據(jù)庫,一般是MySQL。
- 為每個用戶保存各自排序后的Feed,一般是Key-Value數(shù)據(jù)庫,如Redis或者HBase。
- 一個類似Pinlater的分布式異步任務(wù)隊列,Celery是一個不錯的選擇。
按興趣排序
興趣Feed的排序,要避免陷入兩個誤區(qū):
- 沒有目標(biāo)的排序。設(shè)計排序算法之前,一定要先弄清楚:為什么要對時間序重排?希望達(dá)到什么目標(biāo)?目標(biāo)用哪些指標(biāo)量化?只有先確定目標(biāo),才能檢驗和優(yōu)化算法。
- 人工量化排序因素。我們經(jīng)常見到的產(chǎn)品或者運營的同學(xué)要求對某個因素加權(quán)、降權(quán)。這樣做很不明智,因為人的知識利于做啟發(fā),不利于做量化。人可以告訴算法很多可能有用的排序因素,縮短效果提升的路徑,但是人直接指定參數(shù)的權(quán)重,對效果提升來說基本上有百害而無一利。
我們從機器學(xué)習(xí)的思路來簡單設(shè)計一個提升互動率的興趣Feed。首先,定義好互動行為包括哪些,比如點贊、轉(zhuǎn)發(fā)、評論和查看詳情等。其次,區(qū)分好正向互動和負(fù)向互動,比如隱藏某條內(nèi)容、點擊不感興趣等是負(fù)向的互動。
這是一個典型的二分類監(jiān)督學(xué)習(xí)問題,將正向的互動視為同一類。一條動態(tài)產(chǎn)生之后,展示給用戶之前,用機器學(xué)習(xí)來預(yù)測用戶對產(chǎn)生正向互動的概率,預(yù)測的概率就可以作為興趣排序分?jǐn)?shù)輸出。
能產(chǎn)生概率輸出的二分類算法都可以用在這里,包括貝葉斯、最大熵和邏輯回歸等?;ヂ?lián)網(wǎng)常用的是邏輯回歸,它有很多好處:
- 線性模型,足夠簡單。
- 產(chǎn)生0-1之間的輸出,互相可以比較。
- 開源實現(xiàn)多,初始技術(shù)成本小。
- 工業(yè)界已經(jīng)反復(fù)驗證過。
用機器學(xué)習(xí)來為興趣Feed排序,最重要的是將<動態(tài),受眾>這個數(shù)據(jù)對表示成特征向量。特征向量就是排序因素的向量化表述。在算法選定后,人工可以花很多力氣在尋找影響排序的因素上,這就是傳說中的“特征工程”。特征工程還包括對已有的特征進(jìn)行選擇,選擇的目的是:機器學(xué)習(xí)模型完成后,以RPC的方式提供服務(wù),供Feed系統(tǒng)中新動態(tài)內(nèi)容發(fā)布時調(diào)用。
關(guān)于RPC框架,選用Apache Thrift即可。機器學(xué)習(xí)模型訓(xùn)練框架有很多,我們可以選Vowpal Wabbit,它是一個分布式機器學(xué)習(xí)框架,可以和Hadoop輕松結(jié)合。
數(shù)據(jù)和效果追蹤
我們既要通過歷史數(shù)據(jù)來尋找算法的最優(yōu)參數(shù),又要通過新的數(shù)據(jù)驗證排序效果,所以我們要關(guān)注數(shù)據(jù)的存儲和使用。
與興趣Feed相關(guān)的數(shù)據(jù)有:
- 目標(biāo)有關(guān)的互動行為數(shù)據(jù)(記錄每一個用戶在Feed上的操作行為)。
- 曝光給用戶的內(nèi)容(一條曝光要有唯一的ID,曝光的內(nèi)容僅記錄ID即可)。
- 互動行為與曝光的映射關(guān)系(每條互動數(shù)據(jù)要對應(yīng)到一條曝光數(shù)據(jù))。
- 用戶profile(提供用戶特征,來自離線挖掘和數(shù)據(jù)同步)。
- Feed內(nèi)容分析數(shù)據(jù)(提供內(nèi)容特征)。
日志的收集和存儲,一般選用Kafka和Hadoop即可,用Hive處理數(shù)據(jù),生成訓(xùn)練樣本,監(jiān)控產(chǎn)品指標(biāo)。其中比較重要的是模型的參數(shù)更新,即訓(xùn)練模型。