深度學習在推薦領域的應用
CSDN 同步發表 深度學習在推薦領域的應用 - 極客頭條 - CSDN.NET
以下正文:
當2012年Facebook在廣告領域開始應用定製化受眾(Facebook Custom Audiences)功能後,「受眾發現」這個概念真正得到大規模應用,什麼叫「受眾發現」?如果你的企業已經積累了一定的客戶,無論這些客戶是否關注你或者是否跟你在Facebook上有互動,都能通過Facebook的廣告系統觸達到。「受眾發現」實現了什麼功能?在沒有這個系統之前,廣告投放一般情況都是用標籤去區分用戶,再去給這部分用戶發送廣告,「受眾發現」讓你不用選擇這些標籤,包括用戶基本信息、興趣等。你需要做的只是上傳一批你目前已有的用戶或者你感興趣的一批用戶,剩下的工作就等著Custom Audiences幫你完成了。
Facebook這種通過一群已有的用戶發現並擴展出其他用戶的推薦演算法就叫Lookalike,當然Facebook的演算法細節筆者並不清楚,各個公司實現Lookalike也各有不同。這裡也包括騰訊在微信端的廣告推薦上的應用、Google在YouTube上推薦感興趣視頻等。下面讓我們結合前人的工作,實現自己的Lookalike演算法,並嘗試著在新浪微博上應用這一演算法。
調研
首先要確定微博領域的數據,關於微博的數據可以這樣分類:
- 用戶基礎數據:年齡、性別、公司、郵箱、地點、公司等。
- 關係圖:根據人?人,人?微博的關注、評論、轉發信息建立關係圖。
- 內容數據:用戶的微博內容,包含文字、圖片、視頻。
有了這些數據後,怎麼做數據的整合分析?來看看現在應用最廣的方式——協同過濾、或者叫關聯推薦。協同過濾主要是利用某興趣相投、擁有共同經驗群體的喜好來推薦用戶可能感興趣的信息,協同過濾的發展有以下三個階段:
第一階段,基於用戶喜好做推薦,用戶A和用戶B相似,用戶B購買了物品a、b、c,用戶A只購買了物品a,那就將物品b、c推薦給用戶A。這就是基於用戶的協同過濾,其重點是如何找到相似的用戶。因為只有準確的找到相似的用戶才能給出正確的推薦。而找到相似用戶的方法,一般是根據用戶的基本屬性貼標籤分類,再高級點可以用上用戶的行為數據。
第二階段,某些商品光從用戶的屬性標籤找不到聯繫,而根據商品本身的內容聯繫倒是能發現很多有趣的推薦目標,它在某些場景中比基於相似用戶的推薦原則更加有效。比如在購書或者電影類網站上,當你看一本書或電影時,推薦引擎會根據內容給你推薦相關的書籍或電影。
第三階段,如果只把內容推薦單獨應用在社交網路上,準確率會比較低,因為社交網路的關鍵特性還是社交關係。如何將社交關係與用戶屬性一起融入整個推薦系統就是關鍵。在神經網路和深度學習演算法出現後,提取特徵任務就變得可以依靠機器完成,人們只要把相應的數據準備好就可以了,其他數據都可以提取成向量形式,而社交關係作為一種圖結構,如何表示為深度學習可以接受的向量形式,而且這種結構還需要有效還原原結構中位置信息?這就需要一種可靠的向量化社交關係的表示方法。基於這一思路,在2016年的論文中出現了一個演算法node2vec,使社交關係也可以很好地適應神經網路。這意味著深度學習在推薦領域應用的關鍵技術點已被解決。
在實現演算法前我們主要參考了如下三篇論文:
Audience Expansion for Online Social Network Advertising 2016node2vec: Scalable Feature Learning for Networks Aditya Grover 2016Deep Neural Networks for YouTube Recommendations 2016第一篇論文是LinkedIn給出的,主要談了針對在線社交網路廣告平台,如何根據已有的受眾特徵做受眾群擴展。這涉及到如何定位目標受眾和原始受眾的相似屬性。論文給出了兩種方法來擴展受眾:
- 與營銷活動無關的受眾擴展;
- 與營銷活動有關的受眾擴展。
在圖1中,LinkedIn給出了如何利用營銷活動數據、目標受眾基礎數據去預測目標用戶行為進而發現新的用戶。今天的推薦系統或廣告系統越來越多地利用了多維度信息。如何將這些信息有效加以利用,這篇論文給出了一條路徑,而且在工程上這篇論文也論證得比較紮實,值得參考。
第二篇論文,主要講的是node2vec,這也是本文用到的主要演算法之一。node2vec主要用於處理網路結構中的多分類和鏈路預測任務,具體來說是對網路中的節點和邊的特徵向量表示方法。
簡單來說就是將原有社交網路中的圖結構,表達成特徵向量矩陣,每一個node(可以是人、物品、內容等)表示成一個特徵向量,用向量與向量之間的矩陣運算來得到相互的關係。
下面來看看node2vec中的關鍵技術——隨機遊走演算法,它定義了一種新的遍歷網路中某個節點的鄰域的方法,具體策略如圖2所示。
圖2 隨機遊走策略假設我們剛剛從節點t走到節點v,當前處於節點v,現在要選擇下一步該怎麼走,方案如下:
其中dtx表示節點t到節點x之間的最短路徑,dtx=0表示會回到節點t本身,dtx=1表示節點t和節點x直接相連,但是在上一步卻選擇了節點v,dtx=2表示節點t不與x直接相連,但節點v與x直接相連。其中p和q為模型中的參數,形成一個不均勻的概率分布,最終得到隨機遊走的路徑。與傳統的圖結構搜索方法(如BFS和DFS)相比,這裡提出的隨機遊走演算法具有更高的效率,因為本質上相當於對當前節點的鄰域節點的採樣,同時保留了該節點在網路中的位置信息。
node2vec由斯坦福大學提出,並有開源代碼,這裡順手列出,這一部分大家不用自己動手實現了。aditya-grover/node2vec
註:本文的方法需要在源碼的基礎上改動圖結構。第三篇論文講的是Google如何做YouTube視頻推薦,論文是在我做完結構設計和流程設計後看到的,其中模型架構的思想和我們不謀而合,還解釋了為什麼要引入DNN(後面提到所有的feature將會合併經歷幾層全連接層):引入DNN的好處在於大多數類型的連續特徵和離散特徵可以直接添加到模型當中。此外我們還參考了這篇論文對於隱含層(FC)單元個數選擇。圖3是這篇論文提到的演算法結構。
實現
(a)數據準備
- 獲得用戶的屬性(User Profile),如性別、年齡、學歷、職業、地域、能力標籤等;
- 根據項目內容和活動內容制定一套受眾標籤(Audience Label);
- 提取用戶之間的關注關係,微博之間的轉發關係;
- 獲取微博message中的文本內容;
- 獲得微博message中的圖片內容。
(b)用戶標籤特徵處理
- 根據步驟a中用戶屬性信息和已有的部分受眾標籤系統。利用GBDT演算法(可以直接用xgboost)將沒有標籤的受眾全部打上標籤。這個分類問題中請注意處理連續值變數以及歸一化。
- 將標籤進行向量化處理,這個問題轉化成對中文單詞進行向量化,這裡用word2vec處理後得到用戶標籤的向量化信息Label2vec。這一步也可以使用word2vec在中文的大數據樣本下進行預訓練,再用該模型對標籤加以提取,對特徵的提取有一定的提高,大約在0.5%左右。
(c)文本特徵處理
將步驟a中提取到的所有微博message文本內容清洗整理,訓練Doc2Vec模型,得到單 個文本的向量化表示,對所得的文本作聚類(KMeans,在30w的微博用戶的message上測試,K取128對文本的區分度較強),最後提取每個cluster的中心向量,並根據每個用戶所佔有的cluster獲得用戶所發微博的文本信息的向量表示Content2vec。(d)圖像特徵(可選)
將步驟a中提取到的所有的message圖片信息整理分類,使用預訓練卷積網路模型(這裡為了平衡效率選取VGG16作為卷積網路)提取圖像信息,對每個用戶message中的圖片做向量化處理,形成Image2vec,如果有多張圖片將多張圖片分別提取特徵值再接一層MaxPooling提取重要信息後輸出。(e)社交關係建立(node2vec向量化)
將步驟a中獲得到的用戶之間的關係和微博之間的轉發評論關係轉化成圖結構,並提取用戶關係sub-graph,最後使用node2Vec演算法得到每個用戶的社交網路圖向量化表示。
圖4為簡歷社交關係後的部分圖示。
圖4 用戶社交關係
(f)將bcde步驟得到的向量做拼接,經過兩層FC,得到表示每個用戶的多特徵向量集(User Vector Set, UVS)。這裡取的輸出單元個數時可以根據性能和準確度做平衡,目前我們實現的是輸出512個單元,最後的特徵輸出表達了用戶的社交關係、用戶屬性、發出的內容、感興趣的內容等的混合特徵向量,這些特徵向量將作為下一步比對相似性的輸入值。
(g)分別計算種子用戶和潛在目標用戶的向量集,並比對相似性,我們使用的是餘弦相似度計算相似性,將步驟f得到的用戶特徵向量集作為輸入x,y,代入下面公式計算相似性:
使用餘弦相似度要注意:餘弦相似度更多的是從方向上區分差異,而對絕對的數值不敏感。因此沒法衡量每個維度值的差異,這裡我們要在每個維度上減去一個均值或者乘以一個係數,或者在之前做好歸一化。(h)受眾擴展
- 獲取種子受眾名單,以及目標受眾的數量N;
- 檢查種子用戶是否存在於UVS中,將存在的用戶向量化;
- 計算受眾名單中用戶和UVS中用戶的相似度,提取最相似的前N個用戶作為目標受眾。
最後我們將以上步驟串聯起來,形成如圖5所示。
在以上步驟中特徵提取完成後,我們使用一個2層的神經網路做最後的特徵提取,演算法結構示意圖如圖6所示。
圖6 Lookalike演算法結構圖其中FC1層也可以替換成MaxPooling,MaxPooling層具有強解釋性,也就是在用戶特徵群上提取最重要的特徵點作為下一層的輸入,讀者可以自行嘗試,這裡限於篇幅問題就不做展開了。
講到這裡,演算法部分就已基本完結,其中還有些工程問題,並不屬於本次主題探討範圍,這裡也不做討論了。
結果
我司演算法團隊根據Lookalike思想完整實現其演算法,並在實際產品中投入試用。針對某客戶(乳品領域世界排名前三的品牌主)計算出結果(部分):
表1 部分計算結果可以觀察到以上微博ID的主題基本都是西點企業或西點培訓企業,和品牌主售賣的乳品有很高的關聯性:乳品是非常重要的西點原料,除終端用戶外,西點相關企業就是乳品企業主需要尋找的最重要的受眾之一。
探討
特徵表達
除了以上提到的特徵外,我們也對其他的重要特徵表達做了處理和變換:根據我們的需求,需要抽取出人的興趣特徵,如何表達一個人的興趣?除了他自己生成的有關內容外,還有比較關鍵的一點是比如「我」看了一些微博,但並沒有轉發,大多數情況下都不會轉發,但有些「我」轉發了,有些「我」評論了;「我」轉發了哪些?評論了哪些?這次距上次的瀏覽該人的列表時間間隔多久?都代表「我」對微博的興趣,而間接的反應「我」的興趣特徵。這些數據看來非常重要,又無法直接取得,怎麼辦?
下面來定義一個場景,試圖描述出我們對看過的內容中哪些是感興趣的,哪些不是感興趣的:
- (a)用戶A,以及用戶A關注的用戶B;
- (b)用戶A的每天動作時間(比如他轉發、評論、收藏、點贊)起始時間,我們定義為蘇醒時間A_wake(t);
- (c)用戶B每天發帖(轉發、評論)時間:B_action(t);
- (d)簡單假設一下A_wake(t)> B_action(t),也就是B_action(t)的評論都能看到。這就能得到用戶A對應了哪些帖子;
- (e)同理,也可知用戶A 在A_wake(t)時間內轉發了、評論了哪些帖子;
- (f)結合上次瀏覽間隔時間,可以描述用戶A對哪些微博感興趣(post ive),哪些不感興趣(negative)。
全連接層的激活單元比對提升
在Google那篇論文中比對隱含層(也就是我們結構圖中的FC層)各種單元組合產生的結果,Google選擇的是最後一種組合,如圖7所示。
圖7 YouTube推薦模型隱含層單元選擇對比我們初期選用了512 tanh→256 tanh 這種兩層組合,後認為輸入特徵維度過大,512個單元無法完整的表達特徵,故又對比了 1024→512組合,發現效果確實有微小提升大概在0.7%。另外我們的FC層輸入在(-1,1)區間,考慮到relu函數的特點沒有使用它,而是使用elu激活函數。測試效果要比tanh函數提升0.3%-0.5%。
附node2vec偽碼:
感謝我司演算法組周維在擬寫這篇文章時提供的幫助。
推薦閱讀:
※機器學習系列-Logistic回歸:我看你像誰 (下篇)
※Python語言下的機器學習庫
※機器學習-異常檢測演算法(一):Isolation Forest
※這樣能解決知乎質量越來越低,老用戶離開的情況么?
※生成式對抗網路 NIPS 2016 課程 第 3 節
TAG:深度学习DeepLearning | 机器学习 | Facebook |