搜索排序實時個性化中的Embedding調研與實踐

萬物皆Embedding

最近在搜索場景中嘗試做個性化召回部分的工作,經歷了一番調研和實踐之後,希望通過這篇博文來做個階段性的總結和下一步工作的思考。

自從Tomas Mikolov的word2vec出來之後,相信只要做過文本處理的同學們都知道Embedding的概念,後來的Transformer和BERT無不在Embedding和Attention上做文章。近些年來,Embedding不止是在NLP屆活躍,現在甚至有人提出“萬物皆Embedding的概念”。具體說來就是借鑑NLP的文本上下文概念,構造出真實場景中的上下文,每個現實中的實體當作是文檔中的單詞,使用word2vec的方式,訓練出實體的向量表達。

Embedding在非NLP場景的應用

Real-time Personalization using Embeddings for Search Ranking at Airbnb 是2018年KDD的最佳論文,該論文沒有花哨的模型結構,而是使用了傳統的word2vec的模型,通過對細節的調整處理來適應真實的應用場景。可以這麼說,該論文的價值不在於模型的創新,而是工程化實踐應用的細節處理。

接下來,讓我們先簡單過一下論文的一些要點:

  1. 樣本處理

    在airbnb場景中,同一個登錄用戶點擊的房屋可以構造出點擊序列。每個點擊序列就相當於NLP中的文檔,而其中的每個房源就是單詞。在這些點擊序中,文中做了兩個小處理。

    • 過濾停留時間較短的房源
    • 兩次點擊間隔超過30min即歸爲不同點擊Session

  2. 使用skip-gram訓練Embedding

    在多數的場景下,我們更經常能看到skip-gram模型,而不是cbow。在論文中,我們看到兩者的差別,skip-gram相較於cbow更能學習到語義上的信息。在我們非文本的場景裏,語義對我們來說更爲重要。

  3. 下單商品作爲全局上下文(Global Context)

    下單的商品在電商場景中是比較特殊的,但skip-gram是按照窗口大小來進行構造樣本集,如果下單商品是最後點擊的商品,那麼該下單商品無法和前面的點擊商品形成上下文,所以airbnb團隊對原生的word2vec進行了修改,針對有下單的點擊序,構造一個global context,使得點擊商品的Embedding空間往最終下單商品靠近。

  4. Embedding驗證

    由於Embedding是從文本中通過無監督的方式(其實算是自動生成樣本然後用有監督的方式做的)生成的,沒有一套樣本來對結果進行驗證。在原始的word2vec論文裏,作者是自己構建了文本單詞對的數據集,然後進行驗證的。而對於電商場景來說,這個驗證就顯得更爲困難。

    該論文中,作者使用兩種方式來對Embedding進行驗證。

    1. 利用了房源的地理位置做直觀的判斷。首先對同一區域內(加州)的房源Embedding進行聚類,不同類別塗上不同顏色,然後在地圖上展示。
    2. 構建小工具,通過單個房源獲取餘弦距離Top N小的其他房源,判斷Embedding是否學到房屋風格等信息。
    3. 利用房屋的類型、價格等信息,對房源進行了分類,然後計算不同類別之間的Embedding的餘弦距離。

這裏我們過了一下listing Embedding部分的內容,實際上該論文還有做關於User Type Embedding和Listing Type Embedding的內容,這塊後續嘗試之後再跟大家分享。

Embedding在CF的一些嘗試

  1. 樣本構建

    • 停留時間過濾這塊沒有做,一開始我以爲沒有包含用戶在頁面停留的時間。不過後來發現user_trace表內包含停留時間dur字段,後續可以基於該字段進行過濾;
    • 我這裏也是用30min間隔作爲click session的打斷。這個參數的意義其實就是我們認爲多久時間間隔的兩次點擊分屬不同搜索(不同場景不同意圖)
  2. global context的實現

    作爲該論文的亮點,global context的概念還是挺新鮮的。不過要實現這塊功能,我們需要對源碼進行修改。但是word2vec的源碼是C++,如果想要修改的話不太容易,至少要先把代碼review一遍。考慮到時間投入成本,對此,我這邊做了一個小trick(建議有時間的同學們最好還是能過一遍源碼並進行改造word2vec),通過自己構造包含global contex的上下文的新樣本來實現。具體就是保持原樣本不動的情況下,拼接下單商品Lb和其他點擊商品L1-Ln.

    當然這種構造雖然不用改動代碼,但是爲引入兩個問題:

    1. 新增樣本數據,導致在統計詞頻時改變了詞頻的分佈。
    2. 由於訓練過程中會進行負採樣,單獨構造的新樣本,有可能負採樣到同一窗口的其他商品(如下圖,在訓練L1 Lb時,有可能負採樣到L1 L2)

  3. 訓練

    一開始我使用Spark的word2vec進行訓練,一個月的數據量沒有問題,但是數據量加大之後spark的運行時間變得很久,後來我這邊就該用原生的word2vec進行訓練。(Spark這塊訓練時間久的原因暫時未找到)

    雖然原生的word2vec使用單機訓練,但是我這邊4個月9千多萬的click session訓練10個epoch也只要一個多小時就搞掂了。

  4. Embedding驗證

    • 不同類目下Embedding的餘弦相似度。相對於論文的cosine similarity,我們的結果偏低,但是類目之間的差異相對來說還是比較明顯的。

    • 聚類後,同cluster下的類目信息熵。由於我們沒有地理位置的信息,無法像論文那樣給出直觀的聚類結果評價。在這裏我們聚類後,對同類別的商品類目進行分析,通過類目分佈的信息熵來判斷聚類效果。可以看到我們的類目信息熵普遍在1.5以下, 而原來所有商品的類目分佈熵爲2.6

雖然我們通過以上的流程訓練得到了商品Embedding,但如何使用把Embedding用在搜索場景還需要繼續探討。初步想法是用faiss來做搜索的多路召回。

參考資料:

  1. Efficient Estimation of Word Representations in Vector Space
  2. Real-time Personalization using Embeddings for Search Ranking at Airbnb
  3. Listing Embeddings in Search Ranking
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章