大家應(yīng)該知道廣告有一種計(jì)算收益的方式叫CPM旺坠,簡單講就是通過不斷擴(kuò)大曝光量來提升廣告收益的計(jì)算方式玫恳;同樣這種方式也適用于推薦系統(tǒng);業(yè)務(wù)在不斷提升薄嫡,而商品的展示位相對(duì)又是比較固定的饥努,為了收益最大化捡鱼,必須要充分利用商品展示欄位,最大化優(yōu)質(zhì)商品的曝光酷愧。
數(shù)據(jù)分析
易企秀PC商城90%以上的流量來自搜索推薦驾诈,每天PC端H5商品總曝光次數(shù)800w次,去重后的商品有16.8w個(gè)溶浴,占總商品的84%乍迄,咋一看這個(gè)數(shù)字挺可喜的,可進(jìn)一步分析發(fā)現(xiàn)問題所在士败;首先將商品曝光人數(shù)分別限制在2人或5人以上時(shí)闯两,那么有效的商品曝光數(shù)是9.4w和6w,分別占比47%和30%谅将,曝光占比一下子下滑了50%生蚁;我們繼續(xù)調(diào)大人數(shù)到100,此時(shí)曝光占比跌至2%戏自;一天中PC端活躍人數(shù)6w,很明顯絕大部分商品只有極小部分人可以看到伤锚,長尾問題可見一斑擅笔;有很多優(yōu)質(zhì)商品得不到展示的機(jī)會(huì),沒有曝光就不可能有后續(xù)的點(diǎn)擊和購買動(dòng)作屯援,那么定義一個(gè)好的曝光控制策略將是多么的重要猛们。
架構(gòu)
-
商品索引庫
結(jié)合商品屬性數(shù)據(jù)及用戶行為特征數(shù)據(jù),通過hadoop離線計(jì)算平臺(tái)算出用戶商品特征關(guān)系存入ES狞洋,該數(shù)據(jù)為商品候選結(jié)果集弯淘,為推薦系統(tǒng)召回模塊提供商品檢索、篩選及底層排序支持吉懊。
-
策略庫
通過管理后臺(tái)庐橙,產(chǎn)品可輕松添加推薦策略;策略庫存放推薦系統(tǒng)使用的策略信息借嗽,如召回策略态鳖、排序策略、打散策略恶导、分流策略浆竭、分群策略、配比策略等。
-
標(biāo)簽庫
基于業(yè)務(wù)數(shù)據(jù)及用戶行為數(shù)據(jù)邦泄,通過制定運(yùn)營規(guī)則及算法模型離線計(jì)算得到删窒;標(biāo)簽庫主要存放商品、作品及用戶的標(biāo)簽顺囊,如用戶屬性標(biāo)簽肌索、用戶興趣標(biāo)簽,作品用途標(biāo)簽包蓝、商品風(fēng)格標(biāo)簽及商品行業(yè)標(biāo)簽等驶社。
-
CTR模型庫
定期通過spark任務(wù)提取業(yè)務(wù)日志與用戶行為日志構(gòu)建商品點(diǎn)擊預(yù)估模型,CTR模型用來對(duì)商品進(jìn)行二次排序测萎,將用戶可能點(diǎn)擊的商品優(yōu)先返回亡电。
-
實(shí)時(shí)特征庫
實(shí)時(shí)特征庫的構(gòu)建主要為了彌補(bǔ)離線特征在時(shí)效性方面的不足;特征庫記錄用戶與商品實(shí)時(shí)產(chǎn)生的互動(dòng)數(shù)據(jù)硅瞧,如曝光份乒、點(diǎn)擊、購買腕唧,依據(jù)用戶未來對(duì)商品興趣程度判斷:已點(diǎn)擊 > 已曝光 > 已購買 或辖,參照興趣程度及數(shù)據(jù)量分別設(shè)置小時(shí)、日枣接、周的曝光限制颂暇,如用戶已購買的商品本周內(nèi)將不會(huì)重復(fù)推薦。
用戶上下文特征庫
重點(diǎn)來了但惶,實(shí)時(shí)特征庫我們選擇ES進(jìn)行存儲(chǔ)耳鸯,理由是便于特征檢索及排序;用戶動(dòng)作的上下文環(huán)境數(shù)據(jù)結(jié)構(gòu)如下:
- 創(chuàng)建索引庫自動(dòng)生成模板
PUT _template/uplog_temp
{
"template" : "uplog_*",
"order":1,
"mappings" : {
"dynamic" : "false",
"dynamic_templates" : [
{
"strings" : {
"match_mapping_type" : "string",
"mapping" : {
"doc_values" : false,
"norms" : false,
"type" : "keyword"
}
}
}
],
"date_detection" : false,
"properties" : {
"pid" : { ##動(dòng)作對(duì)象
"type" : "keyword"
},
"platform" : {
"type" : "keyword"
},
"position" : { ## 位置信息
"type" : "text",
"index_options" : "docs",
"analyzer" : "ik_max_word",
"search_analyzer" : "ik_smart"
},
"mark" : { ## 備注
"type" : "text",
"index_options" : "docs",
"analyzer" : "ik_max_word",
"search_analyzer" : "ik_smart"
},
"product" : {
"type" : "keyword"
},
"time" : {
"type" : "date",
"format" : "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"feature_type" : {
"type" : "integer" ##用戶動(dòng)作 1:點(diǎn)擊膀曾;2:曝光县爬;3:購買 ;4:升級(jí)會(huì)員...
},
"u_i" : { ## 不能為空
"type" : "keyword"
},
"s_i" : {
"type" : "keyword" ## 標(biāo)記上下文環(huán)境
}
}
},
"settings" : {
"index" : {
"codec" : "best_compression",
"search" : {
"slowlog" : {
"level" : "info",
"threshold" : {
"fetch" : {
"info" : "500ms"
},
"query" : {
"info" : "1s"
}
}
}
},
"refresh_interval" : "60s",
"number_of_shards" : "1",
"translog" : {
"flush_threshold_size" : "2024mb",
"sync_interval" : "1200s",
"durability" : "async"
},
"merge" : {
"scheduler" : {
"max_thread_count" : "2"
}
},
"store" : {
"type" : "niofs"
},
"number_of_replicas" : "0"
}
}
}
因?yàn)槠毓馊罩据^多(千萬日志量)添谊,所以分庫存儲(chǔ)只保留1天财喳,其它上下文日志保留7天(每天一個(gè)索引庫),超過對(duì)應(yīng)天數(shù)的日志會(huì)執(zhí)行delete操作斩狱,執(zhí)行刪除索引庫的動(dòng)作比delete_by_query性能要高很多
- 通過spark腳本同步離線日志到ES進(jìn)行測試(上線后切streaming日志)
#!/bin/bash
export SPARK_HOME=/data/work/spark-2.4.4
export PATH=$SPARK_HOME/bin:$PATH
source /etc/profile
exec spark-shell --master yarn --name log2es --num-executors 5 --packages org.elasticsearch:elasticsearch-spark-20_2.11:7.3.0 <<!EOF
import org.elasticsearch.spark.sql._
val df=spark.read.parquet("/data/merge/tracker/202003/31")
df.registerTempTable("log")
#曝光日志
sql("select u_i,s_i,e_d.product_id pid, 'h5' product,os_2 platform,tk_id position,'2' as feature_type, from_unixtime(cast(s_t/1000 as long),'yyyy-MM-dd HH:mm:ss') time from log where e_t='element_view' and length(u_i)>4 and length(e_d.product_id)>4 and e_d.type=2").saveToEs("uplog_view_20200331",Map("es.nodes"->""))
#其它行為上下文日志
sql("select u_i,s_i,e_d.product_id pid, 'h5' product,os_2 platform,tk_id position,'1' as feature_type, from_unixtime(cast(s_t/1000 as long),'yyyy-MM-dd HH:mm:ss') time from log where e_t='element_click' and length(u_i)>4 and length(e_d.product_id)>4 and e_d.type=2").saveToEs("uplog_ctx_20200331",Map("es.nodes"->""))
spark.stop
!EOF
- 數(shù)據(jù)預(yù)覽
"_source" : {
"u_i" : "ff80808159905690015991716a1d007e",
"s_i" : "f69604159905001585499443PGXGRB",
"pid" : "1237715",
"product" : "h5",
"platform" : "PC",
"position" : "search-69604-96046-1585499443PGXGRB-687-11",
"feature_type" : "1",
"time" : "2020-03-30 00:52:11"
}
- 例如獲取某用戶當(dāng)天推薦曝光次數(shù)高的200個(gè)商品進(jìn)行屏蔽
GET uplog_view_20200330/_search
{
"size": 0,
"query": {
"bool": {
"filter": {
"term": {
"u_i": {
"value": "ff80808159905690015991716a1d007e"
}
}
},
"must": [
{
"match": {
"position": "re"
}
}
]
}
},
"aggregations": {
"field1": {
"terms": {
"field": "pid",
"size": 200
}
}
}
}
通過實(shí)時(shí)的用戶上下文日志也可快速區(qū)分用戶當(dāng)前興趣變化及身份變化情況耳高,配合運(yùn)營規(guī)則及時(shí)合理調(diào)配資源以提升用戶活躍及留存
商品曝光控制
商品曝光控制主要分為兩種:節(jié)假日&興趣預(yù)判
-
節(jié)假日
已過節(jié)假日及熱點(diǎn)商品,理論上熱度已經(jīng)減少喊废,需要在推薦系統(tǒng)召回模塊進(jìn)行降權(quán)甚至過濾處理祝高;
通過離線任務(wù)每天對(duì)昨日新增商品進(jìn)行標(biāo)簽化處理,標(biāo)記出有節(jié)假日性質(zhì)的商品污筷,整個(gè)過程程序通過算法規(guī)則自動(dòng)完成的無需人工干預(yù)工闺。
推薦系統(tǒng)會(huì)在數(shù)據(jù)召回時(shí)先獲取全年中不在最近一個(gè)月的節(jié)日類清單乍赫,基于此清單在獲取ES候選結(jié)果集時(shí)對(duì)商品進(jìn)行排除或降權(quán)處理。
image.png 興趣預(yù)判
基于實(shí)時(shí)特征庫的行為日志陆蟆,結(jié)合一定的分析策略來預(yù)判用戶未來一段時(shí)間內(nèi)對(duì)該商品的興趣程度雷厂;首先設(shè)計(jì)類電商平臺(tái)有區(qū)別于傳統(tǒng)電商平臺(tái),例如某用戶今天購買了一個(gè)模板商品叠殷,那么很大程度上近期該用戶是不會(huì)再重復(fù)購買類似商品的改鲫,所以推薦系統(tǒng)需要在各推薦位自動(dòng)屏蔽該商品繼續(xù)曝光給該用戶,通過選擇其它商品曝光不僅能充分利用推薦位展示更多信息林束,同時(shí)更能拓展用戶興趣需求像棘;
在商品召回模塊,程序會(huì)根據(jù)用戶id從實(shí)時(shí)特征庫抽取出當(dāng)前用戶最近觸達(dá)到的Top商品壶冒,基于此清單在獲取ES候選結(jié)果集時(shí)對(duì)商品進(jìn)行排除缕题。
注:
根據(jù)不同用戶的活躍程度,每個(gè)用戶日志量有大有小胖腾,在獲取用戶日志信息時(shí)需要進(jìn)行Top限制烟零,防止因數(shù)據(jù)量太大影響服務(wù)性能(建表時(shí)已根據(jù)type和time進(jìn)行排序)
該屏蔽策略并不會(huì)永久屏蔽商品,根據(jù)用戶興趣預(yù)判咸作,最長屏蔽1周锨阿,最短屏蔽1天
兜底策略
當(dāng)召回模塊沒有提取到足夠的數(shù)據(jù)時(shí)需要觸發(fā)兜底策略:
- 熱點(diǎn)
基于業(yè)務(wù)日志及用戶行為日志,匯總求出商品近7日銷量作為熱點(diǎn)候選商品记罚,每天通過hadoop離線數(shù)據(jù)平臺(tái)進(jìn)行計(jì)算墅诡,將熱點(diǎn)score已標(biāo)簽方式更新到商品標(biāo)簽庫,更新之前需要先將所有熱點(diǎn)商品score致為0桐智。 - 運(yùn)營干預(yù)
運(yùn)營可根據(jù)時(shí)下熱點(diǎn)及促銷模式指定一部分商品书斜,并以標(biāo)簽的形式更新到商品標(biāo)簽庫。