快速開始
一、Contextual Bandit 算法的適用范圍
Contextual Bandit 算法雖然可以用來解決冷啟動問題,但如果在一些基礎(chǔ)條件不滿足時,算法可能不能很好地收斂。
注意:
探索流量是否足夠。如果一個場景新品數(shù)量很大,每時每刻都有新品源源不斷地加進來,并且能夠用來做探索的流量并不是很多時(比如每次請求返回結(jié)果列表里只有一個位置可以展現(xiàn)新品,且總流量也不是很多),算法的效果可能不會很好。平均每個新品應該能夠獲得幾十次曝光的機會,如果無法滿足此要求,可以考慮建模時不要使用Item作為Arm。
建模時的考慮。一般情況下可以使用Item本身作為Contextual Bandit算法的Arm,但如果面臨流量不夠時,可以考慮使用主題、類目等粗粒度Item屬性作為Arm,算法計算出每次應該展現(xiàn)的Arm(主題、類目等),然后再使用某種策略展現(xiàn)該Arm下面的Item(比如展現(xiàn)最新的)。
考慮是否一定要使用冷啟動排序。當條件不成熟時,僅僅使用基于模型的冷啟動召回(如DropoutNet模型)也能取得不錯的效果。我們可以在冷啟動召回模型的基礎(chǔ)上加上一定探索機制,比如當我們需要展現(xiàn)N個新品時,使用向量K近鄰算法匹配出 M(M>N)個新品,保留相似度最高(距離最近)的個新品作為候選,然后再根據(jù)相似度的Softmax概率采樣N-K個新品添加到候選集。
按相似度分數(shù)的概率采樣候選物品既能夠保證一定的相關(guān)性,也加入了Exploration機制。
二、創(chuàng)建Hologres表
1. 創(chuàng)建特征表
BEGIN;
CREATE TABLE rec.contextual_bandit_features (
request_id text NOT NULL,
user_id bigint NOT NULL,
arm_id bigint NOT NULL,
recom_time timestamp with time zone NOT NULL,
feature text NOT NULL
,PRIMARY KEY (user_id, arm_id)
);
CALL set_table_property('rec.contextual_bandit_features', 'orientation', 'row');
CALL set_table_property('rec.contextual_bandit_features', 'clustering_key', 'user_id:asc,arm_id:asc');
CALL set_table_property('rec.contextual_bandit_features', 'time_to_live_in_seconds', '259200');
CALL set_table_property('rec.contextual_bandit_features', 'distribution_key', 'user_id,arm_id');
CALL set_table_property('rec.contextual_bandit_features', 'storage_format', 'sst');
COMMENT ON TABLE rec.contextual_bandit_features IS '冷啟動算法特征表';
COMMENT ON COLUMN rec.contextual_bandit_features.request_id IS '每次請求唯一的ID';
COMMENT ON COLUMN rec.contextual_bandit_features.user_id IS '用戶ID';
COMMENT ON COLUMN rec.contextual_bandit_features.arm_id IS '在大多數(shù)場景下指item_id';
COMMENT ON COLUMN rec.contextual_bandit_features.recom_time IS '請求時間';
COMMENT ON COLUMN rec.contextual_bandit_features.feature IS '序列化的特征向量';
END;
2. 創(chuàng)建模型表
BEGIN;
CREATE TABLE rec.contextual_bandit_models (
arm_id bigint NOT NULL,
version bigint NOT NULL,
invert_matrix_a integer[] NOT NULL,
vector_b integer[] NOT NULL,
matrix_b integer[]
,PRIMARY KEY (arm_id)
);
CALL set_table_property('rec.contextual_bandit_models', 'orientation', 'column');
CALL set_table_property('rec.contextual_bandit_models', 'clustering_key', 'arm_id:asc');
CALL set_table_property('rec.contextual_bandit_models', 'bitmap_columns', 'arm_id');
CALL set_table_property('rec.contextual_bandit_models', 'time_to_live_in_seconds', '259200');
CALL set_table_property('rec.contextual_bandit_models', 'storage_format', 'orc');
CALL set_table_property('rec.contextual_bandit_models', 'distribution_key', 'arm_id');
CALL set_table_property('rec.contextual_bandit_models', 'segment_key', 'version');
COMMENT ON TABLE rec.contextual_bandit_models IS '冷啟動模型參數(shù)表';
COMMENT ON COLUMN rec.contextual_bandit_models.arm_id IS 'arm id';
COMMENT ON COLUMN rec.contextual_bandit_models.version IS '算法版本號:時間戳';
COMMENT ON COLUMN rec.contextual_bandit_models.invert_matrix_a IS 'linucb算法參數(shù):矩陣A的逆矩陣';
COMMENT ON COLUMN rec.contextual_bandit_models.vector_b IS 'linucb算法參數(shù):向量b';
COMMENT ON COLUMN rec.contextual_bandit_models.matrix_b IS 'linucb算法參數(shù):矩陣B';
END;
三、部署模型訓練任務
下載Flink訓練任務的Jar包ContextualBanditFlink-1.0-SNAPSHOT-jar-with-dependencies.jar 。
進入阿里云實時計算控制臺——資源上傳頁面,上傳剛剛下載的Jar包
進入阿里云實時計算控制臺——作業(yè)開發(fā)頁面,創(chuàng)建作業(yè)——流作業(yè)/Jar
配置作業(yè)信息,
Jar URI
選擇剛上傳的Jar;Entry Point Class
文本框輸入com.alibaba.pairec.linucb.Driver
;Entry Point Main Arguments
文本框輸入--datasource datahub
(如果數(shù)據(jù)來源為datahub)或者--datasource kafka
(如果數(shù)據(jù)來源為kafka)
配置訓練任務信息,在作業(yè)頁面右側(cè)高級配置浮窗的
更多Flink配置
文本框中輸入算法訓練相關(guān)的配置?
配置完畢后,點擊左上方"保存"按鈕,右上方"上線"按鈕,發(fā)布任務。
進入"作業(yè)運維"頁面,啟動任務; 并查看任務運行情況
四、部署模型打分服務
創(chuàng)建好模型打分服務需要的配置文檔,并上傳到OSS,獲取對應的OSS公開可訪問的路徑。
準備好EAS服務的配置文件,假設(shè)文件名為eas_config.json
, 示例如下:
{
"name": "cold_start",
"containers": [
{
"image": "mybigpai-registry.cn-beijing.cr.aliyuncs.com/mybigpai/eas-contextual-bandit:0.0.1-efa1d85",
"env": [
{
"name": "GIN_MODE",
"value": "release"
},
{
"name": "ALGO_CONFIG",
"value": "https://${bucket}.oss-cn-beijing-internal.aliyuncs.com/cold_start.json?OSSAccessKeyId=xxxxx&Expires=1001639368243&Signature=XXXX"
}
],
"port": 8000,
"command": "/linucb-server -l /log"
}
],
"metadata": {
"cpu": 15,
"instance": 2,
"memory": 22000
}
}
其中,containers
參數(shù)的說明如下:
"image": "mybigpai-registry.cn-beijing.cr.aliyuncs.com/mybigpai/eas-contextual-bandit:0.0.1-efa1d85",是模型打分服務的鏡像倉庫地址,固定不變。
ALGO_CONFIG: value表示模型打分服務的配置文件,需要為公開可訪問的地址。
通過eascmd
命令行工具創(chuàng)建或更新EAS服務:
# 創(chuàng)建服務
#eval "${eascmd} create ../conf/eas_config.json"
# 更新服務
eval "${eascmd} modify cold_start -s ../conf/eas_config.json"
# 查看服務
eval "${eascmd} desc cold_start"
五、在推薦服務中配置冷啟動Pipeline
參考推薦引擎PaiRec的配置文檔自定義 Pipeline 流程 ,配置單獨冷啟動推薦鏈路。
配置如下:
{
"PipelineConfs": {
"video_feed": [ // 場景名稱,場景,可以配置多個 pipeline
{
"Name": "coldstart", // 自定義 pipeline 名稱,全局唯一,不同場景也要唯一
"RecallNames": [], // 召回列表, RecallConfs 里定義
"FilterNames": [], // 過濾列表, FilterConfs 里定義
"GeneralRankConf": { // 粗排定義, 可以參考粗排的配置
"FeatureLoadConfs":[],
"RankConf":{},
"ActionConfs": [
{
"ActionType": "filter",
"ActionName": ""
}
]
},
"FeatureLoadConfs":[],
"RankConf":{
"RankAlgoList":[],
"RankScore":"",
"Processor":"",
"BatchCount": 100
},
"ColdStartRankConf": {
"AlgoName":"",
"OnlyEmbeddingFeature": true
},
"SortNames":[] // 排序處理,SortConfs 里定義
}
]
}
}
冷啟動Pipeline的結(jié)果會與常規(guī)主流程的推薦結(jié)果融合在一起。
六、新品冷啟動效果評估
新品冷啟動是作用在物品側(cè)的算法,因此,不能再使用流量劃分的A/B測試方法來評估效果。
在做算法效果度量時,需要以物品集的劃分為實驗對比的對象,比如:
基準桶:針對item id(或hash值)為奇數(shù)的新物品集合,不使用冷啟動算法。比如,常規(guī)推薦,或隨機展現(xiàn)新品。
實驗桶:針對item id(或hash值)為偶數(shù)的新物品集合,使用冷啟動算法,如LinUcb算法。
統(tǒng)計指標需根據(jù)業(yè)務特點確定,比如曝光量、點擊率、留存率、播放時長等。