主要是對實習(xí)期間涉及到的知識進行梳理。
背景:視頻推薦(手機端,TV端等)提揍。
場景:feed 流,瀑布流(猜你喜歡)煮仇,短視頻 Tab 等劳跃。
召回涉及到的方法(以短視頻 Tab 為例):
youtubednn u2i, 插播2i, 頻道熱門召回,up主2i, 熱門內(nèi)容浙垫,F(xiàn)M i2i等刨仑。
排序涉及到的方法 (以猜你喜歡為例):
afm, dcn, deepfm, wide&deep, deep_crossing, xgb等。
數(shù)據(jù)源表(自己日常接觸到的表):
show(展示) click(點擊) vv(播放次數(shù)) vt(播放時長)
都是hive分區(qū)表 通過 dt 和 scene 進行限制夹姥。
關(guān)注的線上指標(biāo):
一般情況下都是通過對不同的字段進行g(shù)roup by聚合來求不同維度下的指標(biāo)杉武。
通常用來聚合的字段有:channel_id(頻道), bucket(實驗分桶), app_version(版本) ,dt(日期)
通過show表求: show_pv , show_uv
通過click表求: click_pv , click_uv
通過vv表求:vv
通過vt表求:vt
ctr = click_pv / show_pv
uctr = click_uv / show_uv
ppui = vt / show_uv
次留
以端指標(biāo)為核心辙售,日常關(guān)注的方面:
- 召回轻抱,排序模型的優(yōu)化。這其中包括 特征豐富旦部,多場景祈搜,多目標(biāo),冷啟動士八,實時性容燕,指標(biāo)加權(quán),長尾分發(fā)婚度,軟保量硬保量蘸秘,debiasing, 新穎性等。每個方面都值得之后再具體展開(更新中)陕见。
- 對1中的方法設(shè)計實驗秘血,進行A/B test, 接下來幾天再進行場景指標(biāo)味抖,端指標(biāo)的觀察和對比评甜,驗證實驗的效果。
- 線上問題的跟蹤與排查仔涩。拿到用戶以及up主的負(fù)面反饋(bad case)忍坷,對于具體的問題分析成因,設(shè)計實驗方法進行改進。改進的方面無非也是1中那些方法佩研。
- 在關(guān)注推薦系統(tǒng)用戶消費指標(biāo)之外柑肴,針對部分推薦場景,基于各產(chǎn)品的業(yè)務(wù)定位把評估體系進一步完善旬薯。
以參與過的TV端 猜你喜歡場景的A/B Test為例晰骑,主要為達成以下三個目標(biāo):
1.長視頻端播放時長,端次留(也就是說這兩個指標(biāo)是核心指標(biāo)绊序,驗證實驗是否成功)
2.對電影/電視劇/綜藝的分發(fā)量進行扶持
3.猜你喜歡場景同樣存在追劇的席位硕舆,降低追劇占比,提升新穎性和探索性骤公。
主要設(shè)計的實驗如下:
規(guī)則層面:
1.追劇內(nèi)容打壓兒童抚官、游戲策略實驗(就是把兒童,游戲頻道的追劇內(nèi)容直接減少)
2.按小時興趣頻道提權(quán)阶捆,分時段重排減少兒童凌节、游戲內(nèi)容占比
3.保留前三卡追劇,后面位置個性化探索(該場景就是電視端的猜你喜歡的十多個欄位洒试,把前三個攔住都設(shè)置為追劇倍奢,即用戶最近在看的劇,后面的欄位自動分發(fā)垒棋。)
召回層面:
4.高消費指數(shù)召回
5.豆瓣高分召回
模型層面:
6.訓(xùn)練樣本影劇綜提權(quán)
之后再統(tǒng)計幾天內(nèi)每個實驗桶下的場景指標(biāo)和端指標(biāo)娱挨,一般來講時間越長說服力越好,單獨拿某一天的指標(biāo)進行實驗的對比并沒有什么意義捕犬。而且這里并沒有使用置信度的概念跷坝。
短視頻場景邏輯梳理:
拿到原始數(shù)據(jù),先進行簡單的過濾碉碉,例如付費內(nèi)容柴钻,色情,政治敏感垢粮,時效性(去除老舊的內(nèi)容)等贴届,寫入Corpus。
從Corpus中取數(shù)據(jù)進行多路召回蜡吧,方法各種各樣有很多毫蚓,除了深度模型大多可以通過sql完成。
每路召回的數(shù)量也不一定(每種召回路徑中的物料id也可作為之后模型學(xué)習(xí)的特征昔善,如果該物料排名較好元潘,可以理解為該路召回效果不錯,可考慮加權(quán)重)
所有召回的內(nèi)容加在一起君仆,之后一起過粗排翩概。
在做粗排前(pre_train),我們拿到了召回得到的物料id. 拿這些id去特征庫中(couchbase)匹配牲距,(特征是全部做好的,我們只需要拿召回結(jié)果去匹配就好了)钥庇。
同時我們還需要拿到label牍鞠,在有的場景下,label可以自定義,比如說觀看時長>15s的.
有的場景不適合這樣定義。這時候就需要pingback了稍浆,我們可以通過pingback看用戶是否點擊了,進而拿來做label 0和1 龄广。
拿到特征和label后(七天的數(shù)據(jù))做特征的組合,生成train_dataset, 再生成tfrecord格式.
opal調(diào)用gitlab代碼進行離線訓(xùn)練蕴侧。訓(xùn)練完成后择同,保存模型。模型在http服務(wù)上進行預(yù)測
(預(yù)測時净宵,也是從根據(jù)id從couchbase中拿到對應(yīng)的特征敲才,以及實時特征,直接送至模型進行預(yù)測)
得到粗排后的結(jié)果择葡,是物料id 設(shè)備id 還有排序紧武。
根據(jù)粗排得到的結(jié)果,再去cb中匹配特征敏储,與粗排同樣的步驟進行精排阻星,模型在http服務(wù)上進行預(yù)測.
之后我們只需給引擎那邊 http地址,他們就可以繼續(xù)做下去已添,得到精排后的結(jié)果妥箕。
再進行重排,(MMR,強插等策略更舞,最終可能只留下top5) 進行推薦畦幢。
特征回放好像就是指 特征到CB,根據(jù)id從CB中取特征的過程。(不確定)
(瞎BB版缆蝉,不改動了宇葱,有很多邏輯梳理錯誤,理解錯誤的地方刊头,回看的時候看能不能找到黍瞧。剛好保留之前自己琢磨時陷入的思維陷阱 )
TV推薦場景
corpus根據(jù)什么來定義:
首先從 videoflow_al_da_snap_hive_episode_album_ppc_meta_latest_view 第一步篩選,
例如 過濾掉 推薦等級為0的原杂,過濾掉 所有的付費內(nèi)容印颤, 過濾掉所有不可試看內(nèi)容等等,這樣生成了第一步基礎(chǔ)的corpus -- tv_basic_short_corpus
在tv_basic_short_corpus中進一步限制掉 政治污尉,色情的內(nèi)容膀哲,并scene=‘short_tab’,生成短視頻tab的高質(zhì)量的corpus數(shù)據(jù).
在tv_basic_short_corpus中進一步限制掉 政治被碗,色情的內(nèi)容某宪,并scene=‘a(chǎn)iplay’,生成隨心看的高質(zhì)量的corpus數(shù)據(jù).
把上面生成的兩個 union all起來 后锐朴,對不同的頻道需要控制 不同的 時效性兴喂。 有的頻道需要限制在一周內(nèi),有的需要控制一個月內(nèi)焚志,有的則需要更久衣迷。
對時效性進行限制后,重寫入 tv_basic_short_corpus
再通過幾個 視頻 質(zhì)量分的特征 進一步篩選 高質(zhì)量的視頻 存入 tv_short_tab_corpus_quality
以上是corpus的生成過程酱酬。
之后進入召回流程:
召回分為 i2i 標(biāo)簽召回 TGI召回 模型召回 trigger 兜底召回 u2i
每個分類下面又有好多的方法壶谒。
(標(biāo)簽召回就很簡單 從不同的維度取出 熱度較高 的視頻或者是 up主 再取出排名前100or前200的
這種方法是統(tǒng)一的 因為沒有利用到 具體用戶和視頻的交互信息 所以做不到 個性化)
通過以上構(gòu)建的tv_short_tab_corpus 進行多種標(biāo)簽召回 和 倒排 (例如 hot_up hot_channel hot_search hot_short)
以hot_up為例,用到這個語句膳沽,以粉絲量做排名 從多到少
row_number() over (partition by domain_name order by fans_following_count desc) as rank
粉絲量這個特征是從videoflow_al.videoflow_al_da_snap_hive_iqiyi_user_meta_view取得(這個源表中還有視頻質(zhì)量分等特征) 因此同時需要 corpus表和這個源表 做join
取出 up rank < 100的 domain, uploader_id 和其對應(yīng)的quality_score 并存入 tv_dwd_dd_recall_invert_qiguan這張表汗菜。
同樣的方法 根據(jù)其他幾路召回的定義 取出 channel rank < 200的 channel-id, qipu_id, 以及其對應(yīng)的hot 并存入tv_dwd_dd_recall_invert_qiguan這張表。 不同召回方式的數(shù)據(jù) 用 reverse_type = '' 做分區(qū)挑社。 (不同的召回的方式 可以見 鋒哥 以前發(fā)的截圖)
還有一種up2up 通過該up進行相同domain其他up的推薦陨界。
以上是標(biāo)簽召回 還有很多方式 具體見 babel - tv推薦 - 基礎(chǔ)數(shù)據(jù) - 標(biāo)簽召回及倒排
通過標(biāo)簽召回的數(shù)據(jù)都存入tv_dwd_dd_recall_invert_qiguan 的不同分區(qū)
以上是 標(biāo)簽召回的過程
(再以i2i 召回為例)
以 fm i2i為例 fm i2i 的路徑分為兩條 tv i2i 和 short tab i2i
tv i2i 用到了表 dwd_base_recall_i2i_fm_prediction_dd dwd_kpp_dump_column_related_rec_hh tv_dwd_dd_view_long_video_corpus 并寫入 tv_dwd_dd_fm_i2i_recall
short tab i2i 用到了表 dwd_base_recall_i2i_fm_prediction_dd tv_short_tab_corpus 并寫入 tv_dwd_dd_recall_i2i_qiguan 的某個分區(qū)
為了跟之前的邏輯對照 還是以短視頻的這個路徑為例
先看dwd_base_recall_i2i_fm_prediction_dd 哪來的 這個表是成都那邊產(chǎn)的 。痛阻。
看一下該表的結(jié)構(gòu):
hive> desc dwd_base_recall_i2i_fm_prediction_dd;
tv_id string
rec_tv_id string
score double
channel_id int
dt string
即已經(jīng)給出了 tv_id 和 根據(jù)其 推薦的 rec_tv_id 還有二者的得分 score
接著看 short_tab i2i 這里就很簡單了 取出 dwd_base_recall_i2i_fm_prediction_dd中的 tv_id rec_tv_id score 并與 tv_short_tab_corpus中的qipu_eposide_id join
得到的 數(shù)據(jù) 寫入到 tv_dwd_dd_recall_i2i_qiguan 的某個分區(qū)
以上是i2i召回的過程
(再以youtubednn召回為例)
從 tv_dwd_dd_user_click 拿到用戶的點擊記錄 再與 tv_dwd_dd_corpus_merged 的前一天的數(shù)據(jù) 通過album_id join 之后再通過 tv_dwd_dd_black_device 限制設(shè)備
最后拿到 device_id ,entity_id , 1 as label, 1 as weight , concat('last_20_click:', concat_ws(',',collect_list(entity_id))) as cf . .存入tv_dwd_dd_train_dataset
根據(jù)entity_id 出現(xiàn)的次數(shù) 對其進行 row_number()排序 得到一列新特征 并連同之前的特征寫入 tv_dwd_dd_train_dataset_merged中菌瘪。
之后進入到 gen_data 模塊 ,子工作流為 tv_common_sub_gen_train_data_without_sample_libsvm
gen_data模塊:
對tv_dwd_dd_train_dataset_merged中的數(shù)據(jù)進行以下操作:
cate_fea > gen_idmapping > feature_field_extract > feature_field_to_mysql
num_fea > numerical_feature_info > update_numerical_columns > numerical_feature_column_to_mysql
之后join 再進行 tfrecord_gen 得到 clean_data 位于 hadoop fs -rm -r /data/bi_uaa/rec/tv-rec/tfrecord/{DT_BEFORE}/
即通過模型召回得到的數(shù)據(jù)以 tfrecord格式 放在 hdfs上
前面的標(biāo)簽召回和i2i召回后 生成tv_dwd_dd_recall_i2i_qiguan 阱当,這張表下一步緊接著干嘛呢 俏扩?
tv_dwd_dd_recall_i2i_qiguan 生成后的步驟 暫沒找到
進入排序模型訓(xùn)練部分
這一部分 包括 feature_extract label_extract train
這部分操作 都是用的 dwd_dd_show click vv等表 并沒有用到corpus表
feature extract 從三個角度 entity_feature device_feature cross_feature 做特征 做的特征 通過feature_type 進行區(qū)分cate num
分別存入不同的表 并通過dt scene 進行分區(qū)
例如 tv_dwd_dd_entity_feature_by_scene
再進入一個子工作流 通過feature_type = num cate把num cate feature分別提取出來 用concat_ws 進行拼接 as categorical_featuers numerical_features
再存入 tv_dwd_dd_entity_feature_by_scene_combined 之后再跟一個 spark 模塊 名為import 暫不清楚這個模塊是不是用來生成 tfrecord 的。弊添。
label_extract 也是通過定義 (t1.item is not null and t1.playtime > 15, 1, 0) as label 來進行l(wèi)abel的定義动猬。
train模塊不只是train 主要包括以下幾個模塊 make_sample gen_data gen_tf_record
make_sample : 規(guī)范的從feature表和label表拿到每天的數(shù)據(jù) 拼接 寫入tv_dwd_dd_train_dataset
gen_data:放在make_sample 之后, 從 tv_dwd_dd_train_dataset 拿到七天內(nèi)的數(shù)據(jù) 表箭,寫入到 tv_dwd_dd_train_dataset_merged
之后再進行 cate_fea > gen_idmapping > feature_field_extract > feature_field_to_mysql
num_fea > numerical_feature_info > update_numerical_columns > numerical_feature_column_to_mysql
再生成 tfrecord.
根據(jù)上面的總結(jié) 還存在幾點問題 Corpus主要是用來干嘛的
應(yīng)該是主要做 非模型的召回等方式的吧 做完生成tv_dwd_dd_recall_i2i_qiguan之后呢赁咙。
在線訓(xùn)練是從哪進行的 是從生成的tdrecord 開始訓(xùn)練的嘛 tfrecord不是存的7天數(shù)據(jù)嗎。 在線訓(xùn)練的任務(wù)流在哪免钻。
之后不是在opal上訓(xùn)練模型嗎 模型的預(yù)測結(jié)果寫入哪里了 是不是保存模型文件后 拿去線上預(yù)測 保存的模型文件不是用當(dāng)天以及以前7天的數(shù)據(jù)訓(xùn)練的嗎
拿到線上的話 不存在時間跨度的問題嗎
還是說opal上的模型只是用來對模型離線訓(xùn)練 用來調(diào)整模型的結(jié)構(gòu)和參數(shù) 等調(diào)好了 再拿到線上用嗎 彼水? 線上還需要訓(xùn)練嗎 還是直接調(diào)用模型進行預(yù)測 線上預(yù)測的代碼在哪 是python實現(xiàn)的嗎?
如果線上預(yù)測的代碼不是python 是java的話 應(yīng)該是把離線的模型 調(diào)用后 在java中預(yù)測給出預(yù)測結(jié)果把 或者不是java呢 這部分的代碼在哪里呢
為啥我覺得做排序的時候 做train_dataset用的表不是 召回后的結(jié)果 而且直接用 dwd_dd_ click show ..detail表 加工而來的
往前看的話 用戶進入app 有展示极舔,點擊凤覆,觀看記錄 經(jīng)過開發(fā)崗的加工 我們才拿到比較干凈的數(shù)據(jù)。拆魏。
此外 在模型上線前 我們經(jīng)常需要找開發(fā) 進行溝通 是為了什么盯桦?
https://zhuanlan.zhihu.com/p/81752025 對于 推薦系統(tǒng)架構(gòu) 文章的一些疑問:
如文章所說慈俯,模型存儲在 在線存儲模塊(用于存儲模型和模型需要的特征信息供實時計算模塊調(diào)用), 預(yù)測的數(shù)據(jù)流接受業(yè)務(wù)的預(yù)測請求拥峦,通過 A/B 測試模塊訪問 實時計算模塊 獲取預(yù)測結(jié)果贴膘。
實時計算模塊:(實時推薦模塊的功能是對來自業(yè)務(wù)的新請求進行預(yù)測。1.獲取用戶特征略号;2.調(diào)用推薦模型刑峡;3.結(jié)果排序。)
那么app的 在線存儲模塊 和 實時計算模塊在哪里(是什么平臺) 代碼又在哪里