基于Wide Deep Learning的推荐系统
我們先來看下Google Inc的paper:Wide & Deep Learning for Recommender Systems。
一、介紹
推薦系統可以看成是一個搜索排序系統,其中輸入的query是一個用戶和上下文的集合,輸出是一個item列表。給定一個query,推薦任務就是在數據庫中找到相關的items,接著基于目標(比如:點擊or購買)去對items進行排序。
推薦系統與常見的搜索排序問題相同的一個挑戰是,同時滿足Memorization和Generalization。Memorization可以寬泛地定義成學到items或features的共現率,并利用(exploiting)這種在歷史數據中的相關關系(correlation)。Generalization則基于相關關系的轉移,并探索(explores)在過往很少或從不出現的新的特征組合。基于Memorization的推薦系統通常更局部化(topical),將items與執行相應動作的users直接相關。而基于Generalization的推薦則更趨向于推薦多樣化的items。在本papers中,我們主要關注Google Play Stores的推薦問題,方法本身可用于其它場景。
對于工業界大規模的在線推薦和排序系統,常用的線性模型(比如:logistic regression)被廣泛使用,因為它的簡單性、可擴展性以及可解釋性。模型通常在使用one-hot編碼的二值化的稀疏特征上。例如,二值化特征”user_installed_app=netflix”,如果用戶過去安裝(installed)了Netflix,則具有特征值1.?通過在稀疏特征上使用cross-product transformation可以有效地達到Memorization,比如AND(user_installed_app=netflix, impression_app=pandora),如果用戶過去安裝了Netflix,接著被曝光了Pandora,那么它的值是1.?這可以解釋一個特征對(feature pair)的共現率與目標label間的相關關系。通過使用更少(粗)粒度的特征可以添加Generalization,例如:AND(user_installed_category=video, impression_category=music),(注:上面Memorization使用的是具體的app,而此處Generalization使用的僅僅是app的category),但人工的特征工程通常是必需的。(cross-product transformation)的一個限制是,不能泛化到那些在訓練數據上沒有出現過的query-item特征對。
而Embedding-based的模型,比如因子分解機(FM)或深度神經網絡,只需要很少的特征工程,通過為每個query和item特征對(pair)學到一個低維的dense embedding vector,可以泛化到之前未見過的query-item特征對,。然而,當底層的query-item矩陣很稀疏和高秩(high-rank)時(比如,用戶具有特殊偏好或很少出現的items),很難為query-item pair學到有效的低維表示。在這種情況下,大多數query-item pairs之間是沒有交叉的,但dense embeddings會為所有的query-item pairs生成非零的預測,這樣會過泛化(over-generalize),并生成不相關的推薦。另一方面,使用交叉特征轉換(cross-product features transformations)的線性模型可以使用更少的參數就能記住(memorize)這些“異常規則(exception rules)”。(embedding 優點:泛化,缺點:稀疏時)
在本文中,我們提出了Wide&Deep learning框架來在同一個模型中達到Memorization 和 Generalization,通過聯合訓練一個如圖一所示的線性模型組件和一個神經網絡組件。
本文的主要貢獻:
- Wide & Deep 學習框架,可以用于聯合訓練帶embeddings的feed-forward神經網絡以及帶特征轉換的線性模型,用于帶稀疏輸入的常見推薦系統中。
- Wide & Deep推薦系統的實現和評估在Google Play上已經產品化,這個app store具有數十億的活躍用戶、以及上百萬的app。
- 開源,在Tensorflow上提供了一個高級API。
思想很簡單,我們展示了Wide & Deep框架,它極大地提升了App的獲得率(acquisition rate)并且同時滿足training和serving的速度要求。
推薦系統總覽
app推薦系統如圖二所示。一個query,它包含著許多用戶和上下文特征,當一個用戶訪問app store時生成。推薦系統會返回一個app列表(曝光:impressions),用戶在此之上會執行特定的動作(點擊:click或購買:purchase)。這些用戶動作,伴隨著queries和impressions,會以日志的形式記錄下來。
由于在數據庫中有超過百萬的app,對于在serving延遲條件之內(通常為O(10)ms)的每一個query,盡可能得對每一個app進行評分是相當困難。因此,上述第一步收到一個query的過程是檢索(retrieval)。檢索系統會返回一個最匹配query的item的短列表,通常使用機器學習模型和人工定義規則來達到。在數量減至候選池后,排序系統(ranking system)會通過它們的得分對所有items進行排序。得分通常是P(y|x)P(y|x),對于給定的特征x,一個用戶的動作標簽y,包括用戶特征(比如:國家,語言,人口屬性信息),上下文特征(比如:設備,天的小時,周的天),曝光特征(比如:app age, app的歷史統計信息)。在本文中,我們只關注在排序系統中使用Wide & Deep 學習框架。
3. Wide & Deep Learning
3.1 Wide組件
wide組件是一個泛化的線性模型,形式為:y=wTx+by=wTx+b,如圖1(左)所示。y是預測,x=[x1,x2,…,xd]x=[x1,x2,…,xd]是d維的特征向量,?w=[w1,w2,…,wd]w=[w1,w2,…,wd]是模型參數,其中b為bias。特征集包括原始的輸入特征和轉換后的特征,一個最重要的轉換是,cross-product transformation。它可以定義成:
?k(x)=∏i=1dxckii,cki∈{0,1}?k(x)=∏i=1dxicki,cki∈{0,1}
…(1)
其中ckicki為一個boolean變量,如果第i個特征是第k個變換?k?k的一部分,那么為1; 否則為0.對于二值特征,一個cross-product transformation(比如:”AND(gender=female, language=en)”)只能當組成特征(“gender=female” 和 “language=en”)都為1時才會為1, 否則為0. 這會捕獲二值特征間的交叉,為通用的線性模型添加非線性。
3.2 Deep組件
Deep組件是一個前饋神經網絡(feed-forward NN),如圖1(右)所示。對于類別型特征,原始的輸入是特征字符串(比如:”language=en”)。這些稀疏的,高維的類別型特征會首先被轉換成一個低維的、dense的、real-valued的向量,通常叫做“embedding vector”。embedding的維度通常是O(10)到O(100)的階。該embedding vectors被隨機初始化,接著最小化最終的loss的方式訓練得到該值。這些低維的dense embedding vectors接著通過前向傳遞被feed給神經網絡的隱層。特別地,每個隱層都會執行以下的計算:
al+1=f(W(l)a(l)+b(l))al+1=f(W(l)a(l)+b(l))
…(2)
其中,l是層數,f是激活函數(通常為ReLUs),a(l),b(l)和W(l)a(l),b(l)和W(l)分別是第l層的activations, bias,以及weights。
3.3 Wide & Deep模型的聯合訓練
Wide組件和Deep組件組合在一起,對它們的輸入日志進行一個加權求和來做為預測,它會被feed給一個常見的logistic loss function來進行聯合訓練。注意,聯合訓練(joint training)和集成訓練(ensemble)有明顯的區別。在ensemble中,每個獨立的模型會單獨訓練,相互并不知道,只有在預測時會組合在一起。相反地,聯合訓練(joint training)會同時優化所有參數,通過將wide組件和deep組件在訓練時進行加權求和的方式進行。這也暗示了模型的size:對于一個ensemble,由于訓練是不聯合的(disjoint),每個單獨的模型size通常需要更大些(例如:更多的特征和轉換)來達到合理的精度。相比之下,對于聯合訓練(joint training)來說,wide組件只需要補充deep組件的缺點,使用一小部分的cross-product特征轉換即可,而非使用一個full-size的wide模型。
一個Wide&Deep模型的聯合訓練,通過對梯度進行后向傳播算法、SGD優化來完成。在試驗中,我們使用FTRL算法,使用L1正則做為Wide組件的優化器,對Deep組件使用AdaGrad。
組合模型如圖一(中)所示。對于一個logistic regression問題,模型的預測為:
P(Y=1|x)=σ(wTwide[x,?(x)]+wTdeepa(lf)+b)P(Y=1|x)=σ(wwideT[x,?(x)]+wdeepTa(lf)+b)
…(3)
其中Y是二分類的label,σ(?)σ(·)是sigmoid function,??(x)?(x)是對原始特征x做cross product transformations,b是bias項。wwidewwide是所有wide模型權重向量,wdeepwdeep是應用在最終激活函數a(lf)a(lf)上的權重。
4.系統實現
app推薦的pipeline實現包含了三個stage:數據生成,模型訓練,模型serving。如圖3所示。
4.1 數據生成
在這一階段,用戶和app的曝光數據在一定時間內被用于生成訓練數據。每個樣本對應于一個曝光。label為app的獲得率(acquisition):如果曝光的app被下載則為1, 否則為0.
詞匯表(Vocabularies),它是一個關于將類別特征字符串映射到integer ID上的表,也在該階段生成。該系統會為至少出現過某個最小次數的所有的string特征計算ID空間。連續的real-valued特征被歸一化到[0, 1],通過將一個特征值x映射到它的累積分布函數P(X<=x)P(X<=x),將它分成nqnq份 (quantiles)。對于第i個份(quantiles),對應的歸一化值為:i?1nq?1i?1nq?1。分位數(quantiles)邊界在數據生成階段計算。
4.2 模型訓練
我們在試驗中使用的模型結構如圖4所示。在訓練期間,我們的輸入層接受訓練數據和詞匯表的輸入,一起為一個label生成sparse和dense特征。wide組件包含了用戶安裝app和曝光app的cross-product transformation。對于模型的deep組件,會為每個類別型特征學到一個32維的embedding向量。我們將所有embeddings聯接起來形成dense features,產生一個接近1200維的dense vector。聯接向量接著輸入到3個ReLU層,以及最終的logistic輸出單元。
此處做個注解(美食推薦場景FoodIO):wide模型的目的是,記住(memorize)哪些items能更好地對應每個query。因此,你訓練帶交叉特征轉換的線性模型,是為了捕獲一個query-item feature pair與相應的目標label(一個item是否被消費、購買)間的共現關系。該模型會預測每個item的消費概率?P(consumption∥query,item)P(consumption‖query,item),接著FoodIO會返回最高預測購買率的top item。例如,模型學到了特征:AND(query=”炸雞(fried chicken)”, item=”雞肉和華夫餅(chicken and waffles)”)的效果很好,而AND(query=”炸雞(fried chicken)”, item=”雞肉炒飯(chicken fried rice)”)這個并不受喜歡,盡管字符上更匹配。換句話說,它可以記住哪些用戶喜歡,從而獲得更多的交易額。
同理:上述wide中提到的installed app和impressed app可以理解成是上面的item和query。
Wide & Deep模型在超過5000億的樣本上進行訓練。每一時刻有新的訓練數據集到達時,模型需要重新訓練。然而,每次從頭到尾重新訓練的計算開銷很大,數據到達和模型更新后serving間的延遲較大。為了解決該問題,我們實現了一個warm-starting系統,它會使用前一個模型的embeddings和線性模型權重來初始化一個新的模型。
在將模型加載到模型服務器上之前,需要做模型的演習,以便確保它不會在serving的真實環境上出現問題。我們在經驗上會驗證模型質量,對比前一模型做心智檢查(sanity check)。
4.3 模型Serving
一旦模型被訓練和驗證后,我們會將它加載到模型服務器上。對于每個請求,服務器會從app檢索系統上接收到一個app候選集,以及用戶特征來從高到低排序,接著將app按順序展示給用戶。得分的計算通過在Wide&Deep模型上運行一個前向推斷傳遞(forward inference pass)來計算。
為了在10ms的級別服務每個請求,我們使用多線程并行來優化性能,運行運行更小的batches,而不是在單個batch inference step中為所有的候選app進行scoring。
5.試驗結果
為了在真實的推薦系統上評估Wide & Deep learning的效果,我們運行了在線試驗,并在兩部分進行系統評測:app獲得率(app acquisitions)和serving性能。
5.1 App Acquisitions
我們在一個A/B testing框架上做了3周的試驗。對于控制組,1%的用戶被隨機選中,推薦由之前版本的排序系統生成,它是一個高度優化的wide-only logistic regression模型,具有豐富的cross-product特征轉換。對于試驗組,隨機選中1%的用戶,使用相同的特征進行訓練。如表1所示,Wide & Deep模型在app store的主頁上提升了app acquisition rate,對比控制組,有+3.9%的提升。另一個分組只使用deep組件,使用相同的神經網絡模型,具有+1%的增益。
除了在線試驗,我們也展示了在held-out離線數據上的AUC。其中Wide & Deep具有更高的離線AUC,在線也更好。一個可能的原因是,曝光和點擊在離線數據集上是確定的,而在線系統通過混合generalization和memorization,從新的用戶響應學到,生成新的探索推薦。
5.2 Serving Performance
Serving時具有高的吞吐率(throughout)和低延時是很有挑戰性的。在高峰期,我們的推薦服務每秒處理1000w個app得分。單個線程上,在單個batch上為所有的候選得進行scoring會花費31ms。我們實現了多線程,并會將每個batch分割到更小的size上,它會將客戶端的延遲的延遲減小到14ms上,所圖2所示。
6.相關工作
將使用特征交叉轉換的wide linear model與使用dense embeddings的deep neural networks,受之前工作的啟發,比如FM:它會向線性模型中添加generalization,它會將兩個變量的交互分解成兩個低維向量的點積。在該paper中,我們擴展了模型的能力,通過神經網絡而非點積,來學習在embeddings間的高度非線性交叉(highly nonlinear interactions)。
在語言模型中,提出了RNN和n-gram的最大熵模型的joint training,通過學習從input到output之間的直接權重,可以極大減小RNN的復雜度(hidden layer)。在計算機視覺中,deep residual learning被用于減小訓練更深模型的難度,使用簡短連接(跳過一或多層)來提升accuracy。神經網絡與圖模型的joint training被用于人體姿式識別。在本文中,我們會探索前饋神經網絡和線性模型的joint training,將稀疏特征和output unit進行直接連接,使用稀疏input數據來進行通用的推薦和ranking問題。
7.Tensorflow
只需要3步,即可以使用tf.estimator API來配置一個wide,deep或者Wide&Deep:
- 1.選中wide組件的特征:選中你想用的稀疏的base特征列和交叉列特征列
- 2.選擇deep組件的特征:選擇連續型的列,對于每個類別型列的embedding維,以及隱層的size。
- 將它們放置到一個Wide&Deep模型中(DNNLinearCombinedClassifier)
關于更詳細的操作,示例代碼在:/tensorflow/tensorflow/examples/learn/wide_n_deep_tutorial.py,具體詳見tensorflow tutorial。
參考
- 0.Wide & Deep Learning for Recommender Systems
- 1.TensorFlow Wide & Deep Learning Tutorial
- https://ai.googleblog.com/2016/06/wide-deep-learning-better-together-with.html
總結
以上是生活随笔為你收集整理的基于Wide Deep Learning的推荐系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 构建并用 TensorFlow Serv
- 下一篇: 知乎容器化构建系统设计和实践