結合PaddleRec的推薦系統概述

傳統與深度推薦系統重點技術演進圖

1. 什麼是推薦系統? - 傳統推薦系統實例

目標:在海量的信息中確定提供給用戶的具體內容,滿足用戶的個性化需求。

術語:

U2I:基於用戶歷史行為、給用戶直接推薦item

I2I:挖掘item之間的關聯信息。

U2U2I:給相似用戶群體推薦物品,基於用戶的協同過濾。

U2I2I:給用戶推薦相似的物品,基於item的協同過濾。

U2Tag2I:算出用戶tag偏好向量[科幻,恐怖,動作,...],匹配item列表。泛化性好。

1.1 基於內容的推薦系統(Content-Based)

地位:最早使用的推薦算法、年代久遠,但仍被廣泛使用,效果好。

定義:給用戶X推薦 之前喜歡過的物品 推薦 相似的物品。即U2I, 為瞭泛化的目的將中間的I進行聚合,得到Tag標簽,轉變為U2Tag2I問題。

如何實現一個基於內容的推薦系統,整體步驟:

  1. 給物品找特征,使用向量去表達物品。
  2. 根據用戶歷史行為,聚合計算用戶的標簽偏好,得到用戶偏好標簽向量。聚合方法:簡單計數、加權平均等,
  3. 使用餘弦相似度算法,計算用戶標偏好簽向量 與 所有物品的向量 得到最相似的TOPN物品列表

餘弦相似度算法:

優點:

  1. 不需要其他用戶的數據
  2. 針對每個人個性化推薦
  3. 可以推薦最新、冷門的物品
  4. 容易做推薦解釋

缺點:

  1. 物品需要標簽,可能需要人工標簽
  2. 局限於自己的世界,無法挖掘出用戶潛在興趣
  3. 新用戶沒有行為、沒辦法推薦

1.2 基於協同過濾的推薦系統(Collaborative Filtering)

核心:利用集體經驗推薦。

基於用戶的協同過濾U2U2I:給相似用戶群體推薦物品

ebcae072977f40a902e0d0d399081e78

基於物品的協同過濾U2I2I:給用戶推薦相似的物品(通過其他用戶發現)

基於用戶的協同過濾舉例,步驟

  1. 搜索最相似的用戶
  2. 計算用戶和新item的相似度

用戶相似度如下:

相似度問題:

  1. 針對Jaccard相似度,AC在l4和l5上為兩類人
  2. 針對餘弦相似度,實際5分是最高分、1分時最低分,缺失值是0,則表明最不喜歡。
  3. 皮爾遜:缺失值都是為所有物品的平均分,比如A用戶,缺失值為(4+5+1) / 3 = 0.33。計算公式仍為餘弦相似度,但是減去瞭平均分。

已經得到瞭A和BC最相似,再計算用戶和新item的相似度:

  1. 平均值
  2. 權重為相似度值,AB為0.38,AC為0.32

2. 推薦系統環節

技術挑戰:怎樣從海量的內容中,挑選出用戶感興趣的條目,並且能夠滿足系統50ms ~300ms的低延遲要求?

2.1 內容理解

推薦系統通過對用戶興趣和內容進行建模、預測,最終實現用戶與內容的精準匹配。內容理解是建模的基礎,也是推薦系統的基石。

推薦內容平臺,涵蓋瞭圖文、圖集、短視頻、問答、直播、專題等各種內容形態,所有這些內容都可以歸結為文本、圖像和視頻三種數據形式。

內容理解針對文本、圖像和視頻三個大的方面進行內容分析和轉換,即將非結構化的內容(比如圖像、文本等)進行結構化的表示。

在自然語言處理中,使用詞嵌入(Embedding)的方式完成將數據映射為向量的變換,NLP任務中,一般把輸入文本映射成向量表示,以便神經網絡的處理。

在推薦系統領域,可定義為兩個大維度:通過內容本身來理解內容,通過行為反饋來理解內容。

前者:主要針對內容抽取靜態屬性標簽。

後者:通過行為積累的後驗數據、統計、或模型預估內容的知識、傾向性、投放目標以及抽象表達。

涉及到的子領域非常多,如下:

文本理解

  1. 文本分類 常見算法:LSTM / TextCNN / BERT
  2. 文本標簽 標簽可以認為是推薦系統的“血液”,存在於推薦系統各個環節。早期簡單的無監督算法過渡到有監督,最後到深度模型。
    1. 無監督訓練方式:TFIDF / 基於doc和tag語義排序 / TextRank
    2. 有監督模型:CRF / 深度模型

視頻理解:即視頻的行為識別,常見算法:雙流網絡 / I3D等。

PaddleRec/models/contentunderstanding at master · PaddlePaddle/PaddleRec (github.com)

Tips:

  1. 粗排 + 精排統稱為排序Rank
  2. 根據輸入數據的大小、召回 / 粗排環節可以根據需求省略的。

2.2 召回 Recall

目標:根據用戶的興趣和歷史行為,從千萬量級的候選物品,降低候選集規模,快速生成候選物品,然後交給排序環節。

特點:考慮到候選物品數量極大,所以要想速度快,就隻能使用簡單模型,使用少量特征,去保證泛化能力,盡量讓用戶感興趣的物品在這個階段能夠初步篩選出來;

推薦系統的召回階段是很關鍵的一個環節, 這個環節偏向策略型導向。目前工業界,標準召回結構一般是多路召回,即每一路召回采取一個不同的策略。

可以看出,上圖分成兩大類召回路:

  1. 個性化因素的召回路:用戶興趣標簽和物品標簽的召回路
  2. 無個性化因素的召回路:比如熱門商品與頭條或者歷史點擊率高的召回路。

上述圖片為單特征召回,如何進行將其多路融合?

多路召回的融合策略

  1. 按順序依次展示各種策略TOPN策略結果
  2. 平均法: ,C為(0.7 + 0.5 + 0.3)/ 3 = 0.5, B為(0.8 + 0.6) / 3 = 0.46。結果C比B優先
  3. 人工加權平均:人工指定不同策略的權重,假設為XYZ為0.4, 0.6, 0.2,B的權重為(0.4*0.8 + 0.6*0.3 + 0*0.2)/ (0.4 + 0.6 + 0.2)
  4. 動態加權法:計算XYZ三種召回策略的CTR,作為每天更新的動態權重。CTR計算方法:
  5. 機器學習權重法:邏輯回歸LR分類模型預先離線算好各種召回的權重,然後做加權召回

以上效果依次變好,按照成本進行選擇

LR缺乏特征交叉例子1:

c53f36bc472b0167b72f593b3e5f9d40

LR是“線性模型+人工特征組合引入非線性”的模式。

  1. 邏輯回歸不具備特征交叉能力,表達能力受限。
  2. 人工特征工程,耗時費力費人力資源。

如何解決表達能力受限的問題與挖掘隱藏特征呢?因此衍生出Ploy, FM, FFM等之類改進方法,用於解決特征交叉問題,以及發掘隱藏特征。

什麼是特征交叉?

如何發掘隱藏特征?矩陣分解MF、引入隱向量。

舉例,使用隱向量給每個用戶與每首音樂打上標簽,將[3, 3]的矩陣 分解為 [3, 4] * [4, 3]的矩陣。

泛化:

註意的是:

  1. 引向量是需要挖掘的,需要模型去學習的,不可解釋的
  2. k的大小決定瞭表達能力的強弱,k越大,表達信息就越強,能夠把用戶的興趣和物品的分類劃分的越具體
  3. 通過用戶矩陣U和物品矩陣V,對用戶偏好進行評分。

好處在於:

  1. 可以使用隱向量去擬合缺失值,即預測用戶對物品的評分
  2. 協同過濾隻利用瞭[用戶]和[物品],但矩陣分解MF挖掘瞭潛在信息,可以看作是對用戶和物品打標簽的過程。
  3. 便於各種特征的組合拼接,便於與深度學習直接結合
  4. 空間復雜度[m, m] [n, n] => [m, k] [n, k]

常見的召回策略分類

  1. 統計類(閱讀、點贊、評論、分享、熱度)
  2. 協同過濾類,UserCF、ItemCF;
  3. U2Tag2I,如基於user tag召回;
  4. I2I - 模型類,如Embedding(Word2Vec、FastText),GraphEmbedding(Node2Vec、DeepWalk、EGES),模型類的模式是將用戶和item分別映射到一個向量空間,然後用向量召回
  5. U2I - 矩陣分解MF,如DSSM、YouTube DNN、Sentence Bert;

總體而言

召回階段的技術趨勢總體而言:一切Embedding化以及有監督模型化,這是兩個相輔相成的總體發展趨勢。

embedding核心思想:將用戶特征和物品特征分離,各自通過某個具體的模型,分別打出用戶Embedding以及物品Embedding。embedding的具體方法有各種選擇,為不同的給用戶和物品打embedding的不同方法而已。

PaddleRec Recall Models

2.3 排序 Rank

目標:排序環節融入更多特征,使用復雜模型,來精準地做根據用戶特征/物品特征/上下文特征對物品進行精準排名。

粗排:當每個用戶召回環節返回的物品數量還是太多,怕排序環節速度跟不上,所以可以在召回和精排之間加入一個粗排環節,通過少量用戶和物品特征,簡單模型,來對召回的結果進行個粗略的排序,粗排往往是可選的,可用可不同,跟場景有關。

精排:使用你能想到的任何特征,可以上你能承受速度極限的復雜模型,盡量精準地對物品進行個性化排序。

特點:

  1. 排序階段核心目標是要精準,因為它處理的物品數據量小,所以可以采用盡可能多的特征與更復雜的模型,一切以精準為目標。

深度學習的排序模型目前看大的范式還是embedding + MLP,還沒有主流的精排模型能超越這一范式。

具體來說,特征主要有統計特征,id特征,用戶行為序列特征。對於這些特征不同的建模方式可以演化出deepFM, xDeepFM,DIN,autointent等等。

現狀:圖像領域裡有Resnet時刻,NLP裡面有Bert時刻,推薦領域暫時還停留在embedding + MLP階段。

PaddleRec Rank Models

(12 封私信 / 26 條消息) 目前工業界常用的推薦系統模型有哪些? - 知乎 (icpchaxun.com)

d71aae8dfa7d004eb5d9422bb6c18c39

2.4 重排 ReRank

目標:利用各種技術及業務策略,比如去已讀、去重、打散、多樣性保證、固定類型物品插入等等,以技術產品策略主導或者改進推薦體驗的。

註意:精排推薦結果出來瞭,一般並不會直接展示給用戶,可能還要上一些業務策略,比如去已讀,推薦多樣化,加入廣告等各種業務策略。之後形成最終推薦結果,將結果展示給用戶。

3. PaddleRec項目介紹

以排序模型(rank)文件夾下的dnn模型為例:

├── data #樣例數據 ├── sample_data #樣例數據 ├── train ├── sample_train.txt #訓練數據樣例├── __init__.py├── README.md #文檔├── config.yaml # sample數據配置├── config_bigdata.yaml # 全量數據配置├── net.py # 模型核心組網(動靜統一)├── criteo_reader.py #數據讀取程序# 為模型使用靜態圖的方式運行時的執行過程。其中定義瞭模型的具體運行方式:數據輸入方式,配置優化器、學習率、模型訓練和預測時的前向計算,損失的計算方式等。├── static_model.py # 構建靜態圖# 為模型使用動態圖的方式運行時的執行過程。定義內容同上├── dygraph_model.py # 構建動態圖

4. PaddleRec Demo實例 - 電影推薦

4.1 數據準備與格式處理

目標:1. 將數據集劃分為訓練集和測試集。2. 然後進行數據處理,生成可以直接輸入模型的數據。3. 並讀入模型。

1. 數據準備

  1. MovieLens數據集是一個關於電影評分的數據集,包含用戶對電影的評分信息,用戶的人口統計學特征以及電影的描述特征。
  2. MovieLens數據集包含多個子數據集,選取瞭其中一個較小的子數據集ml-1m,大小在1M左右。該數據集共包含瞭6000多位用戶對近3900個電影的100多萬條評分數據,評分為1~5的整數,其中每個電影的評分數據至少有20條。

該數據集包含三個數據文件,分別是:

  • users.dat:存儲用戶屬性信息的txt格式文件,格式為“UserID::Gender::Age::Occupation”,其中原始數據中對用戶年齡和職業做瞭離散化處理,如下
      • movies.dat:存儲電影屬性信息的txt格式文件,格式:“MovieID::Title::Genres”。
          • ratings.dat:存儲電影評分信息的txt格式文件,格式:“UserID::MovieID::Rating::time”。

              根據ratings.dat中的評分時間(time),選取每個用戶最新的一條數據作為測試集,剩餘數據作為訓練集。

              2. 格式處理

              對於ratings.dat文件中每一條數據,我們根據userid和movieid去users.dat和movies.dat裡找到相應的用戶特征和電影特征,經過hash處理後拼接成一條可真實用於訓練或預估的數據。

              拼接後數據格式如下所示,第一個數字是logid即數據的ID,各個數據間的分隔符為空格。

              logid:10000004 time:971979246 userid:313460 gender:113660 age:144970 occupation:209266 movieid:466203 title:504 title:66476 title:0 title:0 genres:249254 genres:332172 genres:0 label:3

              在每條數據中,電影的電影名title和電影風格genres可能需要拆分處理成多個詞,形成多組slot:feasign樣式的數據。

              Slot:Feasign 是什麼? 推薦工程中,是指某一個寬泛的特征類別,比如用戶ID、性別、年齡就是Slot,Feasign則是具體值,比如:12345,男,20歲。 實踐過程中,很多特征槽位不是單一屬性,或無法量化並且離散稀疏的,比如某用戶興趣愛好有三個:遊戲/足球/數碼,且每個具體興趣又有多個特征維度,則在興趣愛好這個Slot興趣槽位中,就會有多個Feasign值。

              PaddleRec在讀取數據時,每個Slot ID對應的特征,支持稀疏,且支持變長,可以非常靈活的支持各種場景的推薦模型訓練。

              3. 數據Reader

              PaddleRec支持您使用自定義的格式進行輸入,根據需要自己定義數據讀取的邏輯,對以行為單位的數據進行截取,轉換等預處理,返回一個可以迭代的reader方法。

              數據的輸出順序與我們在網絡中創建的inputs必須是嚴格一一對應的,並以np.array的形式輸入網絡中。

              # 自定義的Reader中,您需要引入IterableDataset基類,創建一個名為RecDataset子類,繼承IterableDataset的基類。繼承並實現基類中的__iter__(self)函數,逐行讀取數據。from __future__ import print_functionimport numpy as np#引入IterableDataset基類from http://paddle.io import IterableDataset #創建一個子類,繼承IterableDataset的基類class RecDataset(IterableDataset): def __init__(self, file_list, config): super(RecDataset, self).__init__() self.file_list = file_list def __iter__(self): full_lines = [] self.data = [] for file in self.file_list: with open(file, "r") as rf: # 以行為單位,逐行讀取數據 for l in rf: output_list = [] line = l.strip().split(" ") sparse_slots = ["logid", "time", "userid", "gender", "age", "occupation", "movieid", "title", "genres", "label"] #logid和time這兩個特征,訓練模型時並不需要用到,故不必加入output_list logid = line[0].strip().split(":")[1] time = line[1].strip().split(":")[1] #向output_list中加入用戶特征:userid:1個數,gender:1個數,age:1個數,occupation:1個數 userid = line[2].strip().split(":")[1] output_list.append(np.array([float(userid)])) gender = line[3].strip().split(":")[1] output_list.append(np.array([float(gender)])) age = line[4].strip().split(":")[1] output_list.append(np.array([float(age)])) occupation = line[5].strip().split(":")[1] output_list.append(np.array([float(occupation)])) #向output_list中加入電影特征:movieid:1個數,title:4個數,genres:3個數 movieid = line[6].strip().split(":")[1] output_list.append(np.array([float(movieid)])) title = [] genres = [] for i in line: if i.strip().split(":")[0] == "title": title.append(float(i.strip().split(":")[1])) if i.strip().split(":")[0] == "genres": genres.append(float(i.strip().split(":")[1])) output_list.append(np.array(title)) output_list.append(np.array(genres)) #向output_list中加入標簽:label:1個數 label = line[-1].strip().split(":")[1] output_list.append(np.array([float(label)])) #返回一個可以迭代的reader方法 yield output_list

              至此,我們已經將用戶和電影的特征用數字表示。

              4.2 召回模型解析

              召回的目的是從大量電影庫中降低候選集規模,選出部分候選,輸入給排序模塊。召回通常采用簡單的模型,如ItemCF、UserCF、DSSM等。

              本例采用DSSM模型的簡化版,即普通的雙塔模型。

              雙塔模型介紹

              所謂“雙塔”模型,是經典的DNN模型,從特征OneHot到特征Embedding,再經過幾層MLP隱層,兩個塔分別輸出用戶Embedding和Item Embedding編碼。訓練過程中,User Embedding和Item Embedding做Cosine相似度計算,使得用戶和正例Item在Embedding空間更接近,和負例Item在Embedding空間距離拉遠。損失函數則可用標準交叉熵損失,將問題當作一個分類問題。

              現狀:對於絕大多數應用來說,雙塔模型的速度是足夠快瞭,但模型精度還有待提升。因此衍生出瞭,微軟雙塔DSSM,YouTube雙塔,Facebook雙塔, SENet雙塔模型。

              Paddle Rec召回網絡結構:

              1. 第一層結構:將原始的輸入特征,通過Embedding變換為原始的特征集合。如圖:左側對用戶特征建模,得到用戶表示,右側對電影特征建模,得到電影表示。
              2. 第二層結構:將原始特征集合變換為用戶和電影兩個特征向量。如圖:
              3. 第三層結構:計算用戶和電影的相似度。對於用戶評分較高的電影,電影的特征向量和用戶的特征向量應該高度相似,反之則相異。
              4. 第四層結構:最後與訓練樣本(已知的用戶對電影的評分)做損失計算,計算縮放後的相似度與用戶對電影的真實評分的“均方誤差”。

              class DNNLayer(nn.Layer): # 在使用動態圖時,針對一些比較復雜的網絡結構,可以使用Layer子類定義的方式來進行模型代碼編寫,即在__init__構造函數中進行組網Layer的聲明, # 在forward中使用聲明的Layer變量進行前向計算。子類組網方式也可以實現sublayer的復用,針對相同的layer可以在構造函數中一次性定義,在forward中多次調用。 def __init__(self, sparse_feature_number, sparse_feature_dim, fc_sizes): super(DNNLayer, self).__init__() self.sparse_feature_number = sparse_feature_number self.sparse_feature_dim = sparse_feature_dim self.fc_sizes = fc_sizes #聲明embedding層,建立emb表將數據映射為向量 self.embedding = paddle.nn.Embedding( self.sparse_feature_number, self.sparse_feature_dim, padding_idx=0, sparse=True, weight_attr=paddle.ParamAttr( name="SparseFeatFactors", initializer=paddle.nn.initializer.Uniform())) #使用循環的方式創建全連接層,可以在超參數中通過一個數組確定使用幾個全連接層以及每個全連接層的神經元數量。 #本例中使用瞭4個全連接層,並在每個全連接層後增加瞭relu激活層。 user_sizes = [36] + self.fc_sizes acts = ["relu" for _ in range(len(self.fc_sizes))] self._user_layers = [] for i in range(len(self.fc_sizes)): linear = paddle.nn.Linear( in_features=user_sizes[i], out_features=user_sizes[i + 1], weight_attr=paddle.ParamAttr( initializer=paddle.nn.initializer.Normal( std=1.0 / math.sqrt(user_sizes[i])))) self.add_sublayer('linear_user_%d' % i, linear) self._user_layers.append(linear) if acts[i] == 'relu': act = paddle.nn.ReLU() self.add_sublayer('user_act_%d' % i, act) self._user_layers.append(act) # 電影特征和用戶特征使用瞭不同的全連接層,不共享參數 movie_sizes = [27] + self.fc_sizes acts = ["relu" for _ in range(len(self.fc_sizes))] self._movie_layers = [] for i in range(len(self.fc_sizes)): linear = paddle.nn.Linear( in_features=movie_sizes[i], out_features=movie_sizes[i + 1], weight_attr=paddle.ParamAttr( initializer=paddle.nn.initializer.Normal( std=1.0 / math.sqrt(movie_sizes[i])))) self.add_sublayer('linear_movie_%d' % i, linear) self. _movie_layers.append(linear) if acts[i] == 'relu': act = paddle.nn.ReLU() self.add_sublayer('movie_act_%d' % i, act) self._movie_layers.append(act) def forward(self, batch_size, user_sparse_inputs, mov_sparse_inputs, label_input): # 對用戶特征建模, 所有用戶sparse特征查對應的emb表,獲得特征權重 user_sparse_embed_seq = [] for s_input in user_sparse_inputs: emb = self.embedding(s_input) emb = paddle.reshape(emb, shape=[-1, self.sparse_feature_dim]) user_sparse_embed_seq.append(emb) # 對電影特征建模, 所有電影sparse特征查對應的emb表,獲得特征權重 mov_sparse_embed_seq = [] for s_input in mov_sparse_inputs: s_input = paddle.reshape(s_input, shape=[batch_size, -1]) emb = self.embedding(s_input) emb = paddle.sum(emb, axis=1) emb = paddle.reshape(emb, shape=[-1, self.sparse_feature_dim]) mov_sparse_embed_seq.append(emb) # 查表結果拼接在一起,構成用戶特征權重向量 user_features = paddle.concat(user_sparse_embed_seq, axis=1) # 查表結果拼接在一起,構成電影特征權重向量 mov_features = paddle.concat(mov_sparse_embed_seq, axis=1) # 通過4層全鏈接層,獲得用於計算相似度的用戶特征和電影特征 for n_layer in self._user_layers: user_features = n_layer(user_features) for n_layer in self._movie_layers: mov_features = n_layer(mov_features) # 使用餘弦相似度算子,計算用戶和電影的相似程度 sim = F.cosine_similarity( user_features, mov_features, axis=1).reshape([-1, 1]) # 對輸入Tensor進行縮放和偏置,獲得合適的輸出指標 predict = paddle.scale(sim, scale=5) return predict

              4.3 排序模型解析

              排序的目的是引入更多特征,進行更加精細化的預估。一般特點是模型較復雜,候選輸入集比較少。

              此處采用DNN模型,模型組網如下圖所示。

              相較於上述召回模型的雙塔結構,排序模型更早地完成瞭特征交叉,然後進一步利用DNN網絡進行訓練,旨在對候選集合進行更加精確的打分。

              class DNNLayer(nn.Layer): def __init__(self, sparse_feature_number, sparse_feature_dim, fc_sizes): super(DNNLayer, self).__init__() self.sparse_feature_number = sparse_feature_number self.sparse_feature_dim = sparse_feature_dim self.fc_sizes = fc_sizes # 聲明embedding層,建立emb表將數據映射為向量 self.embedding = paddle.nn.Embedding( self.sparse_feature_number, self.sparse_feature_dim, padding_idx=0, sparse=True, weight_attr=paddle.ParamAttr( name="SparseFeatFactors", initializer=paddle.nn.initializer.Uniform())) # 使用循環的方式創建全連接層,可以在超參數中通過一個數組確定使用幾個全連接層以及每個全連接層的神經元數量。 # 本例中使用瞭4個全連接層,並在每個全連接層後增加瞭relu激活層。 sizes = [63] + self.fc_sizes + [1] acts = ["relu" for _ in range(len(self.fc_sizes))] + ["sigmoid"] self._layers = [] for i in range(len(self.fc_sizes) + 1): linear = paddle.nn.Linear( in_features=sizes[i], out_features=sizes[i + 1], weight_attr=paddle.ParamAttr( initializer=paddle.nn.initializer.Normal( std=1.0 / math.sqrt(sizes[i])))) self.add_sublayer('linear_%d' % i, linear) self._layers.append(linear) if acts[i] == 'relu': act = paddle.nn.ReLU() self.add_sublayer('act_%d' % i, act) self._layers.append(act) if acts[i] == 'sigmoid': act = paddle.nn.layer.Sigmoid() self.add_sublayer('act_%d' % i, act) self._layers.append(act) def forward(self, batch_size, user_sparse_inputs, mov_sparse_inputs, label_input): # 對用戶特征建模, 所有用戶sparse特征查對應的emb表,獲得特征權重 user_sparse_embed_seq = [] for s_input in user_sparse_inputs: emb = self.embedding(s_input) emb = paddle.reshape(emb, shape=[-1, self.sparse_feature_dim]) user_sparse_embed_seq.append(emb) # 對電影特征建模, 所有電影sparse特征查對應的emb表,獲得特征權重 mov_sparse_embed_seq = [] for s_input in mov_sparse_inputs: s_input = paddle.reshape(s_input, shape=[batch_size, -1]) emb = self.embedding(s_input) emb = paddle.sum(emb, axis=1) emb = paddle.reshape(emb, shape=[-1, self.sparse_feature_dim]) mov_sparse_embed_seq.append(emb) # 查表結果拼接在一起,混合用戶特征和電影特征,相比召回模型,排序模型更早地完成瞭特征交叉 features = paddle.concat( user_sparse_embed_seq + mov_sparse_embed_seq, axis=1) # 利用DNN網絡進行訓練,使用sigmoid激活的全鏈接層,旨在對候選集合進行更加精確的打分 for n_layer in self._layers: features = n_layer(features) # 對輸入Tensor進行縮放和偏置,獲得合適的輸出指標 predict = paddle.scale(features, scale=5) return predict

              4.4 模型應用

              PaddleRec在線應用

              本PaddleRec demo系統一共啟動瞭5個在線服務,分別是用戶模型服務,內容模型服務,召回服務,排序服務,還有應用服務

              用戶模型和內容模型分別是數據集當中的users.dat和movies.dat經過解析之後保存在redis當中,用戶模型以user_id作為key,內容模型以movie_id作為key。

              1. 用戶模型服務和內容模型服務的邏輯分別是從redis當中按照用戶傳入的key來尋找對應的value並封裝成protobuf結果返回。支持用原有的用戶內容訓練的模型擬合新增用戶,直接在召回服務中產生用戶向量。

              召回服務目前分為兩個階段:

              1. 第一個階段是通過用戶模型得到用戶向量;
              2. 第二個階段是把用戶向量和milvus中的電影向量做近期搜索。

              排序服務是用PaddleRec訓練好的CTR模型,用Paddle Serving啟動來提供預測服務能力,傳入一個用戶信息和一組內容信息,接下來就能經過特征抽取和排序計算,求得最終的打分,按從高到低排序返回給用戶。

              整體應用服務流程

              設計的流程是用戶傳入自己的用戶信息(性別,年齡,工作),從召回服務中得到用戶向量,近似查詢movie列表,接下來查詢到所有的內容模型信息,最終電影信息和用戶信息兩個結合在排序服務中得到所有候選電影的從高到低的打分,最終還原成原始的電影信息返回給用戶。

              經過召回、正排(查電影)、排序rank之後,根據分數降序,從大到小,把最適合該用戶的電影信息返回回來,結果中是由大到小排序的電影信息,每個電影信息包含瞭電影的id,電影名和影片類型。

              error { code: 200}item_infos { movie_id: "2670" title: "Run Silent, Run Deep (1958)" genre: "War"}item_infos { movie_id: "3441" title: "Red Dawn (1984)" genre: "Action, War"}item_infos { movie_id: "71" title: "Fair Game (1995)" genre: "Action"}item_infos { movie_id: "3066" title: "Tora! Tora! Tora! (1970)" genre: "War"}item_infos { movie_id: "3449" title: "Good Mother, The (1988)" genre: "Drama"}

              總結

              Future Reading (priority order)

              1. 傳統推薦算法
                  1. FM / Wide & Deep / Deep & Cross / 引入attention機制DIN 等各類深度推薦算法
                  2. 雙塔模型各有個特點:微軟雙塔DSSM,YouTube雙塔,Facebook雙塔, Facebook雙塔,SENet雙塔模型
                  3. 推薦系統架構:離線層、近線層、在線層、Netflix架構

                  參考資料

                  1. 推薦系統召回四模型之:全能的FM模型 - 知乎 (icpchaxun.com)
                  2. 萬字長文讀懂微信“看一看”內容理解與推薦 | 人人都是產品經理 (woshipm.com)
                  3. 騰訊基於預訓練模型的文本內容理解實踐 - 知乎 (http://icpchaxun.com)](http://zhuanlan.icpchaxun.com/p/409867119)
                  4. 告別電影荒,手把手教你訓練符合自己口味的私人電影推薦助手 - 飛槳AI Studio (baidu.com)
                  5. 推薦系統從入門到實戰嗶哩嗶哩bilibili
                  6. SENet雙塔模型:在推薦領域召回粗排的應用及其它 - 知乎 (icpchaxun.com)

                  发表回复

                  相关推荐

                  香港公司必备知识 | 3分钟了解商业登记证

                  根据香港《商业登记条例》(第310章)的规定,任何在香港经营业务的人士,都需要在公司开业之后的一个月内,以书面通知向税局 ...

                  · 4分钟前

                  被聯合抵制!四川大學走到今天這一步,純屬自找的

                  “落實立德樹人根本任務有差距,思想政治工作不夠到位,師德師風建設不夠紮實,加強學科建設不夠有力。”“落實全面從嚴治黨兩個...

                  · 12分钟前

                  小户型福利,7款迷你衣帽间设计方案,超实用!

                  其实在心底, 每个女生都希望有一间属于自己的衣帽间(包括丽酱在内)。 我们在很多影视剧里都看过这样梦幻敞亮的衣帽间,简 ...

                  · 13分钟前

                  直流電機和交流電機有什麼不同

                  1、首要兩者的外部供電不同,直流電機運用直流電做為電源;而交流電機則是運用交流電做為電源。2、從結構上說,前者的原理相...

                  · 15分钟前

                  转帖 欲加之罪,何患无辞–袁崇焕十二宗罪辨析

                  这是《袁崇焕之孤城》第二部《孤忠》后记之二(已在起点首发),看到凤凰网“袁崇焕是怎样走上神坛的?”等几组专稿以及起点中 ...

                  · 15分钟前