推薦系統 embedding 技術實踐總結

當前主流的推薦系統中,embedding 無處不在,從一定意義上可以說,把 embedding 做好了,整個推薦系統的一個關鍵難題就攻克了。因此,本文總結了移動騰訊網推薦系統中的 embedding 技術實踐,力圖達到娛人娛己的目的。

什麼是 embedding

embedding 其實就是一種稠密向量的表示形式。在 embedding 大行其道之前 onehot 纔是最靚的仔。如果和我們比較熟悉的 oneHot 對比起來理解,頓時會發現 embedding 這個玄裏玄乎的概念,實際上 so easy。

直觀上看 embedding 相當於是對 oneHot 做了平滑,而 oneHot 相當於是對 embedding 做了 max pooling

比如 RGB(三原色,red,green,blue)任何顏色都可以用一個 RGB 向量來表示,其每一維度都有明確的物理含義(和一個具體的物理量相對應)。當然 RGB 這個例子比較特殊,和我們一般意義的 embedding,還不一樣,因爲 RGB 的特殊性就在,他的每一維度都是事先規定好的,所以解釋性很強。而一般意義的 embedding 則是神經網絡倒數第二層的參數權重,只具有整體意義和相對意義,不具備局部意義和絕對含義,這與 embedding 的產生過程有關,任何 embedding 一開始都是一個隨機數,然後隨着優化算法,不斷迭代更新,最後網絡收斂停止迭代的時候,網絡各個層的參數就相對固化,得到隱層權重表(此時就相當於得到了我們想要的 embedding),然後在通過查表可以單獨查看每個元素的 embedding。

embedding 發展大事記

從 1986 年 Hinton,提出 embedding 的概念。到出現第一個在工業上取得不錯結果的模型---word2vec,先驅們經歷了勇敢的嘗試,探索,在此向大神致敬。

MF 矩陣分解,已經隱約看到了 embedding 的影子,此時 embedding 還是一種經驗感覺的模糊存在,沒有人旗幟鮮明的提出這個概念,屬於是 embedding 誕生的前夜。

毫不誇張的說 word2vec 是 embedding 界開天闢地的大事件,從這之後一切事物都可 embedding 了,在這之後的任何 embedding 都能看到 word2vec 的影子。隨着 item2vec,wide and weep 和 youtube 等各種算法的提出,embedding 也迅速的用到了特徵工程,畫像構建召回排序等方面。而 faiss 作爲專業的向量近鄰檢索工具則解決了向量召回在工程上的最後一公里的問題。

embedding 作爲一種新思想,他的意義包含以下幾個方面:

  • embedding 表示,把自然語言轉化爲一串數字,從此自然語言可以計算;
  • embedding 替代 oneHot 極大的降低了特徵的維度(天下人苦 oneHot 久矣);
  • embedding 替代協同矩陣,極大地降低了計算複雜度。

item embedding

在移動騰訊網的推薦系統中,由於我們的 item 主要是圖文,所以 item 的向量化,實際就是一個文本和圖片向量化的過程。文本 embedding 的核心理論還是 word2vec 相關理論的衍生。

基於詞向量的固定表徵:word2vec、fastText、glove 基於詞向量的動態表徵:elmo、GPT、bert。

動態詞向量相較於靜態詞向量,更加充分利用了上下文信息,所以可以解決一詞多義的問題。在工程實踐上其優越性也得到了證明(BERT 在多個 NLP 任務中也表現優異)。

img embedding

由於我們做的是圖文推薦,因此圖片作爲文章的門面特徵,對推薦也很重要,可以通過 resnet 得到圖片的向量,還可以通過 image caption 得到對一張圖片的中文描述,對於娛樂類的新聞,還可以利用 facenet 識別出組圖中,哪一張包含明星,對於動漫類類的新聞可以利用 OCR 識別出漫畫裏的文字,對於年齡,性別有明顯傾向的場景還可以利用 resnet 改變圖片的風格。

對於 CNN 結構來說,不同層級的神經元學習到了不同類型的圖像特徵,由底向上特徵形成層級結構,對人臉識別任務,訓練好網絡後,把每層神經元學習到的特徵可視化,肉眼看一看每層學到了啥特徵,你會看到最底層的神經元學到的是線段等特徵,圖示的第二個隱層學到的是人臉五官的輪廓,第三層學到的是人臉的輪廓,通過三步形成了特徵的層級結構,越是底層的特徵越是所有不論什麼領域的圖像都會具備的比如邊角線弧線等底層基礎特徵,越往上抽取出的特徵越與手頭任務相關。正因爲此,所以預訓練好的網絡參數,尤其是底層的網絡參數抽取出特徵跟具體任務越無關,越具備任務的通用性,所以這是爲何一般用底層預訓練好的參數初始化新任務網絡參數的原因。而高層特徵跟任務關聯較大,實際可以不用使用,或者採用 Fine-tuning 用新數據集清洗掉高層無關的特徵抽取器。

user embeding

爲了使新聞和用戶可以在相同的向量空間下做運算,我們對對用戶也做了 embedding,前期主要是從用戶畫像中篩選出一些在排序模型中重要性較大的特徵來做向量化(比如通過特徵重要度分析,發現標籤(tag),媒體號(mid),一級分類(cat1),二級分類(cat2),主題(topic)等特徵對於用戶是否點擊某篇文章的影響是最大的)。中期使用了更多特徵,模型採用了 DSSM(確保 user 和 item 在同一向量空間),目前則是利用 bert+lstm 對用戶的行爲序列進行了建模。

基於 embedding 的召回

得到 item,user 向量後,就可以做各種基於向量的召回了,從 embedding 本身的使用方式上看,大致可以分成以下幾種召回方式。我們的召回實踐多數用的單 embedding,少量用到了多 embedding。

embedding 的基礎用法——i2i 召回算法

單純使用 fasttext+faiss 就可以實現好幾路召回算法,比如 iten2vec,media2vec,tag2vec,loc2vec,title2vec。

tag2vec 就是利用詞向量去做召回,比如可以用文章的標籤向量表示文章的向量,如果一個文章有 4 個 tag(keywords: "蔣凡;離婚;張大奕;網紅張大奕")我們的經驗是取前 3 個 tag,做等權重向量相加,效果最好。當然了這不是唯一的做法。關於 embedding 向量的用法有很多種比如,等權重相加,加權相加,取平均,取最大等。

得到文章向量之後就是典型的 item2item 的計算過程了,利用 faiss 計算每篇文章的相似文章,比如爲每一篇文章查詢詢出 1000 篇候選文章後,按相似度作一個截斷,比如 cosin sim<0.6 捨去,對餘下的文章,再利用文章的其他特徵比如熱度,CTR,新鮮度作一個加權,一路最簡單的 tag2vec 召回就誕生了。

其他召回和這個套路類似,就是訓練 embedding 向量的時候,略有差異。tag2vec 是訓練中文詞語的向量,而 item2vec 是訓練文章 ID(aid)所對應的向量,media2vec 訓練的是文章的作者 ID(mid)所對應的向量,loc2vec 是訓練地域名稱所對應的向量,title2vec 是用 LSTM 訓練得到的文章標題向量,doc2vec 是用 bert 計算出的文章正文(或者摘要)的向量。entity2vec 是利用我們自己構建的知識圖譜通過 transE 得到的

u2i 召回算法初步

u2i 召回算法實現了,uese2vec,word2vec 個性化,crosstag,DSSM 個性化等召回算法;user2vec 是拿用戶的 tag 向量和文章的 tag 向量求相似度,做的召回;DSSM 個性化是拿用戶的 DSSM 向量和文章的 DSSM 向量求相似度,做的召回;crosstag 相當於多個 user2vec,需要把用戶的 tag 按類別進行統計,每個類取 K 個 tag,共獲取 m 組 tag,然後各組分別做 user2vec,最後彙總得到用戶的推薦列表。

u2i 召回算法進階

uese2vec 是在做召回的初級階段,做的一些樸素的嘗試,簡單暴力見效快,存儲壓力大。每個 user 都存儲一個推薦列表,在產品初期 DAU 不多時,矛盾還不明顯,隨着 DAU 不斷提升,存儲問題日益嚴重,這迫使我們想辦法改變現狀,可行的策略有兩條,一個是把離線提前計算再存儲轉爲線上即時計算不存儲,另一個是把按人推薦轉化爲分羣推薦。兩種方法我們都做了實踐。

分羣召回流程大體如下:

分羣推薦我們嘗試了簇召回,羣畫像召回,LSTM 分羣,DSSM 分羣,bnb 分羣,增量聚類,動態規則聚類。

簇召回就是先把所有用戶的 tag 向量用聚類算法(如 minibatch-kmeans)聚成若干個簇(比如 500 個,根據肘點法確定),然後保存下簇標籤,簇中心,每個用戶所屬的簇(一個用戶可以隸屬於一個簇或者多個簇)。得到用戶所在的簇後,有兩種做法,一種是根據實時點擊日誌,在簇內做實時 CF,也就是在簇內把點擊過的新聞相互推。另一種做法是離線定時計算各個簇中心和候選新聞的相似度,然後和到每個簇的候選集。從實驗效果來看簇內做實時 CF 效果要好一些。

羣畫像召回是先把用戶分羣,然後把同一個羣裏的用戶畫像全部抽取出來,然後融合爲一個羣畫像,相當於把這一羣人合成了一個人,然後對於羣畫像,再使用和單個用戶畫像類似的個性化召回。

LSTM 分羣和簇召回類似,不過用戶的向量是通過用戶最近點擊文章的 m 篇文章的 bert 向量(tag2vec 向量亦可)送入 LSTM 得到用戶的向量,剩下的步驟和簇召回類似,該算法有一定提升但是計算速度慢,很難鋪量。

DSSM 分羣,是把用戶畫像送入 DSSM,得到一個用戶 64 維的向量,把文章畫像送入 DSSM,得到一個文章的 64 維的向量,剩下的步驟和簇召回類似。該算法有提升顯著,已經鋪量使用。

bnb 分羣是借鑑 airbn(愛彼迎)公佈的房源推薦算法,把文章的多個特徵的 embedding(tag,topic,cat)拼接成一個向量,類似得到文章的向量。剩下的步驟和簇召回類似,該算法有一定提升,不十分顯著。

增量聚類

增量聚類就是對文章或用戶聚完類後,很長一段時間聚類中心,保持不變,用戶和類中心的關係可以是變化的,比如一個用戶可能今天屬於這個簇,明天屬於另一個簇。這樣的好處是,同一個簇標籤的含義長期保持不變,便於排序層更好的學習到這個特徵。該算法亦有顯著提升,已鋪量使用。

主要步驟如下

  1. 利用聚類算法預聚類,以 Kmeans 爲例
  2. 保存預聚類的聚類中心 C 和類標籤 L
  3. 對於新增數據點 Xnew,計算其到各個聚類中心 Ci 的距離
  4. 把新增數據點 Xnew 分到距離其最近的聚類中心 Ci,所屬的類別 Li
  5. 在業務低峯期全量更新每個類的聚類中心,以消除增量聚類可能引入的局部偏差,以提高系統的準確性

動態規則聚類

根據用戶的畫像,將用戶聚成若個類,然後再根據類大小,將類大小小於一定閾值的類合併到與其最相似的類,經過多次迭代後聚類過程完成。該算法效率高,CTR 提升約 3%。

主要步驟如下:

  1. 處理用戶畫像數據,得到每個用戶最感興趣的 K 個興趣點
  2. 把這 K 個興趣點按照權重大小,組合成一個興趣標籤
  3. 如果存在相應的聚類標籤則直接加入該類,否則創建一個新的聚類標籤
  4. 全部數據遍歷完成後,統計各個聚類標籤下的用戶數
  5. 如果該類別下的用戶數大於閾值,則該聚類標籤可以保留,否則該聚類標籤需要和其他聚類標籤合併
  6. 對於需要合併的聚類標籤,首先把屬於該類別的用戶標籤回退一步,即得到該聚類標籤下用戶的 k-1 個興趣點組成的興趣標籤,然後重複 3-5 的過程,最好得到一個類大小相對均衡的聚類結果

embedding 召回算法--其他

這個過程主要是用 DNN 類的算法做一些召回,比如 CNN,attention,YouTube 等;CNN 召回主要是用於圖文相關召回,希望把文章的 title,tag,abstract 合成爲一個向量做召回;attention 主要是把文章信息和圖片信息做了融合。

YouTube 是利用 embedding 特徵做推薦的開山之作,由於名聲比較大,我們還是複用了他的網絡結構,只不過在使用的特徵上稍有差別。從一個 embedding 主義者的角度看,他的典型特點是把所有的特徵(無論離散連續,單值多值)全部轉化爲 embedding,然後把各種 embedding 拼接在一起,構成一個一字長蛇陣的向量,然後送入 DNN,最後得到文章的向量。在我們的實踐中主要用了 cat1,cat2,mid,topic,kg 等特徵的 embedding,來訓練。從實踐的效果來看,第一版效果不佳,並未達到預期效果,主要是視頻推薦和新聞推薦有時效性的差異(一個視頻時效性可以很長,因此這個 VID 的 embedding 就可以反覆不斷地訓練,越來越好,而新聞的生命週期則很短,往往是還沒來得及曝光就過期了),後續又做了各種優化,效果也不斷提升。

airbnb 主要貢獻是在稀疏樣本的構造上有所創新,個人感覺 Airbnb 這個操作部分彌補了 YouTube 在新聞推薦領域水土不服的問題。從一個 embedding 主義者的角度看,他的創新點主要有一下兩點,一個是分羣 embedding,另一個是用戶和 item 混合訓練。在移動騰訊網的動態規則聚類召回算法中就借鑑了 Airbnb 分羣訓練 embedding 的思想。

在特徵工程中,對於離散值,連續值,多值大致有以下幾種 embedding 的方法。預先訓練的 embedding 特徵向量,訓練樣本大,參數學習更充分。end2end 是通過 embedding 層完成從高維稀疏向量到低維稠密特徵向量的轉換,優點是端到端,梯度統一,缺點是參數多,收斂速度慢,如果數據量少,參數很難充分訓練。

不同的深度學習模型中,除了對網絡結構的各種優化外,在 embedding 的運算上也進行了各種優化的嘗試,個人覺得對網絡結構的各種優化本質上也是對 embedding 的運算的優化。

embedding 作爲一種技術,雖然很流行,但是他也存在一些缺陷,比如增量更新的語義不變性,很難同時包含多個特徵,長尾數據難以訓練等。

針對 embedding 的空間分佈影響模型的泛化誤差的問題阿里和谷歌先後在 embedding 的表示和結構上進行了各種嘗試,其中阿里提出了 residual embedding 的概念,希望把一個向量用中心向量和殘差向量的形式去表示,以達到同一類別向量簇內高度聚集的目的。谷歌則希望對 embedding 的編碼空間進行優化,簡單來說就是爲更高頻更有效的特徵分配更多的編碼位置,反之則分配更少的編碼位置。

embedding 總體來說還是一種很有效的技術,在實踐過程中大致經歷了以下演進路線:

 

作者:minwxwang,騰訊 PCG 應用研究員

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章