基於深度學習的推薦模型已廣泛應用於各種電商平臺中,為使用者提供推薦。目前常用的方法通常會將使用者和商品 embedding 向量 連線起來輸入 多層感知器 ( multilayer perceptron )以生成最終的預測。但是,這些方法無法捕獲實時使用者行為訊號,並且沒有考慮到重要的 情景特徵 (例如時間和位置等)的影響,以致最終的推薦不能準確地反映使用者的實時偏好,這個問題在快餐推薦的應用場景中更為重要,因為:
- 如果當使用者的購物車中已經新增了飲料時,使用者不太可能再購買其他飲料。
- 使用者的購買偏好會在給定的地點、時間和當前的天氣條件下發生很大變化。例如,人們幾乎從不在半夜給孩子們買食物,也不太可能在寒冷的雨天購買冰鎮飲料。
在此文章中,我們介紹了 Transformer Cross Transformer ( T x T )模型,該模型可以利用到實時使用者點餐行為以及情景特徵來推斷使用者的當前偏好。該模型的主要優點是,我們應用了多個 Transformer 編碼器來提取使用者點單行為和複雜的 情景特徵 ,並透過點積的方法將 Transformer 輸出 組合在一起以生成推薦。
此外,我們利用 Analytics Zoo 提供 的 RayOnSpark 功能, 使用 Ray , Apache Spark 和 Apache MXNet 構建了一個完整的端到端的推薦系統。它將資料處理(使用 Spark )和分散式訓練(使用 MXNet 和 Ray )整合到一個統一的資料分析和 AI 流水線中,並直接執行在儲存資料的同一個大資料叢集上。我們已經在 Burger King 成功部署了這套推薦系統,並且已經在生產環境中取得了卓越的成果。
T x T 推薦模型
我們提出了 Transformer Cross Transformer ( T x T )模型,該模型使用 Sequence Transformer 對客戶訂單行為進行編碼,使用 Context Transformer 對 情景特徵 (例如天氣,時間和位置等)進行編碼,然後使用 點積的方式 將它們組合(“ cross ”部分)以產生最終輸出,如圖 1 所示。我們利用 MXNet API 實現了我們的模型程式碼。
Sequence Transformer 我們基於 Transformer 架構建立了一個 Sequence Transformer ,用於學習客戶購物車中包含每件產品加入順序資訊的 embedding 向量 ,如圖 1 的左下部分所示。為了確保商品位置資訊可以在其原始的 購物行為 中得到考慮,除了商品特徵 embedding 之外,我們還對商品進行基於位置的 embedding 。兩個 embedding 的輸出加在一起,輸入到一個 multi-head self-attention 神經網路 中。
為了從每個商品的隱藏向量中提取客戶整個購物車資訊的向量表示,我們將 mean-pooling 和 max-pooling 分別與最終 Sequence Transformer 的輸出連線起來。透過這種方式, pooling 層的輸出既考慮到了在 購物車 中包含的所有產品,同時又專注提取了少數關鍵產品的顯著特徵。
Sequence Transformer 可以使用 Analytics Zoo 中的 API 直接構建,如下:
from zoo.models.recommendation import SequenceTransformer sequence_transformer = SequenceTransformer( num_items=num_items, item_embed= 200 , item_hidden_size= 200 , item_max_length= 10 , item_num_heads= 4 , item_num_layers= 2 , item_transformer_dropout= 0.1 , item_pooling_dropout= 0.1 , cross_size= 100 ) item_outs = sequence_transformer(input_items, padding_mask)
Context Transformer 合併情景特徵的一種常見方法是將它們與帶時間序列 的輸入特徵 直接連線起來。但是簡單地將 非時間序列的 特徵與 時間序列的 特徵連線起來的意義不大。以前的一些解決方案使用相加來處理多個 情景特徵 ,然而 簡單的相加 只能綜合多個情景特徵對輸出做出的貢獻,但大多數情況下,這些 情景特徵 對使用者最終決策的貢獻並不相等。
因此,我們使用 Context Transformer 對情景特徵進行編碼,如圖 1 右下方所示。使用 Transformer 的 multi-head self-attention ,我們不僅可以捕獲每一個 情景特徵 的影響,還可以捕獲不同 情景特徵 之間的內部關係和複雜的互動作用。
Context Transformer 可以使用 Analytics Zoo 中的 API 直接構建,如下:
context_transformer = ContextTransformer( context_dims=context_dims, context_embed= 100 , context_hidden_size= 200 , context_num_heads= 2 , context_transformer_dropout= 0.1 , context_pooling_dropout= 0.1 , cross_size= 100 ) context_outs = context_transformer(input_context_features)
Transformer Cross Transformer 為了聯合訓練 Sequence Transformer 和 Context Transformer ,我們在這兩個 transformer 輸出之間做 點積 進行聯合訓練,同時最佳化商品的 embedding , 情景特徵 的 embedding 及其互動的所有引數。最後我們使用 LeakyRelu 作為啟用函式,使用 softmax 層來預測每個候選商品的機率。
T x T 由 Sequence Transformer 和 Context Transformer 組成,可以使用 Analytics Zoo 中的 API 直接構建,如下:
from zoo.models.recommendation import TxT net = TxT(num_items, context_dims, item_embed= 100, context_embed= 100, item_hidden_size= 256, item_max_length= 8, item_num_heads= 4, item_num_layers= 2, item_transformer_dropout= 0.0, item_pooling_dropout= 0.1, context_hidden_size= 256, context_max_length= 4, context_num_heads= 2, context_num_layers= 1, context_transformer_dropout= 0.0, context_pooling_dropout= 0.0, activation= "leakyRelu", cross_size= 100) net .hybridize(static_alloc=True, static_shape=True) output = net(sequence, valid_length, context)
端到端的系統架構 通常情況下,構建一個完整的推薦系統會建立兩個單獨的叢集,一個叢集用於大資料處理,另一個叢集用於深度學習(例如,使用 GPU 叢集)。但這不僅會帶來跨叢集資料傳輸的巨大開銷,而且還需要在生產環境中去管理獨立的系統和工作流。為了應對這些挑戰,我們在 Analytics Zoo 的 RayOnSpark 之上構建了我們的推薦系統,將 Spark 資料處理和使用 Ray 的 分散式 MXNet 訓練整合到一個統一的流水線中,直接執行在資料儲存的叢集上。
圖 2 展示了我們系統的總體架構。Spark 的程式中,在 Driver 節點上會建立一個 SparkContext 物件去負責啟動多個 Spark Executor 來執行 Spark 任務。 RayOnSpark 會在 Spark Driver 上 另外建立一個 RayContext 物件,去自動把 Ray 進 程和 Spark Executor 一起啟動,並在每個 Spark Executor 裡創 建一個 RayManager 來管理 Ray 程式(例如, 在 Ray 程式退 出時自動關閉程式)。
在我們的推薦系統中,我們首先啟動 Spark 任務去讀取儲存在分散式檔案系統上的餐廳交易資料,然後使用 Spark 對這些資料 進行資料清理, ETL 和預處理。 Spark 任務完成後,我們將處理後在記憶體中的 Spark RDD 透過 Plasma 直接輸入給 Ray 進行分散式訓練。
參考 RaySGD 的設計,我們實現了 MXNet Estimator ,它提供了一個輕量級的 wrapper ,可以在 Ray 上自動地部署分散式 MXNet 訓練。 MXNet worker 和 parameter server 都是用 Ray actor 實現和 執行的,它們之間透過 MXNet 提供的分 布式 key-value store 來相互通訊,每個 MXNet worker 從 Plasma 中拿取本地節點上的部分資料來訓練模型。透過這種方式,使用者就可以使用下面簡單的 scikit-learn 風格的 API, 透過 Ray 無縫地將 MXNet 的模型 訓練程式碼從單個節點擴充套件到生產叢集:
from zoo.orca.learn.mxnet import Estimator mxnet_estimator = Estimator(train_config, model, loss, <br>metrics, num_workers, num_servers) mxnet_estimator.fit(train_rdd, validation_rdd, epochs, batch_size)
這種統一的設計架構將基於 Spark 的 資料處理和基於 Ray 的分散式 MXNet 訓練整合到一個端到端的、基於記憶體的流水線中,能夠在儲存大資料的同一叢集上直接執行。因此,構建整個 推薦系統的 流水線我們只需要維護一個叢集,避免了不同叢集之間額外的資料傳輸,也不需要額外的叢集維護成本。這樣充分地利用了現有的叢集資源,並且顯著地提升了整個系統的端到端效能。
模型評估 我們使用了過去 12 個月中 漢堡王 客戶的交易記錄進行了離線的實驗,其中前 11 個月的歷史資料用於訓練,最後一個月的資料用於驗證。我們用這些資料對模型進行訓練,讓模型能夠預測客戶下一個最有可能購買的產品。從圖表 1 中,我們可以看到我們的 T x T 優 於其他用於推薦的基準模 型(包括 Association Rule Learning 和 GRU4Rec )。相比 GRU4Rec ,我們可以看到, T x T 能 利用各種 情景特徵 大大提高了 預測的 準確性 (Top1 和 Top3 準確 率分別提升了約 5.65 %和 7.32 %)。
選用的模型 | Top1 準確率 | Top3 準確率 | |
---|---|---|---|
1 | Association Rule Learning | 20.14% | 35.04% |
2 | GRU4Rec | 30.65% | 45.72% |
3 | Transformer Cross Transformer (T x T) | 35.03% | 53.04% |
圖表 1: 不同推薦模型的離線訓練結果
為了評估我們的模型在實際生產環境中的有效性,我們在 Burger King 的手機客戶端上同時對比了 T x T 模型和 Google Recommendation AI* 提供的推薦模型 。我們從推薦轉化率和附加銷售額的提升這兩個方面評估了不同模型的線上效果,在生產環境做了 4 周的 A/B 測試。我們隨機選擇了 20 %的使用者作為對照組,為他們提供之前在生產環境使用的基於規則( Rule Based )的推薦系統。如圖表 2 ,與對照組相比, T x T 將下單頁面上的推薦轉化率提高了 264 %,附加銷售額提高了 137 %。與執行 Google Recommendation AI 的測試組相比, T x T 進一步提高了 100 %的轉換收益和 73 %的附加銷售收益。
推薦系統 | 轉化率提升 | 附加銷售額提升 |
---|---|---|
Rule Based Recommendation (Control) | 0% | 0% |
Google Recommendation AI | +164% | +64% |
Transformer Cross Transformer (T x T) | +264% | +137% |
圖表 2: 不同推薦解決方案的線上結果
結論
這篇文章描述了我們如何在 Burger King 的生產環境 中構建一個端到端的推薦系統。我們透過 Transformer Cross Transformer ( T x T )模型成功地捕獲了使用者訂單行為和複雜的 情景特徵為使用者做合適的推薦 ,並且使用 RayOnSpark 實現了統一的資料處理(使用 Spark )和 深度學習模型 訓練(使用 Ray )的流水線。 T x T 模型和 RayOnSpark 均已在 Analytics Zoo 專案中開源。
- 其他名稱和品牌可能是其他所有者的財產