機器學習在餓了麼競價廣告中的實踐

本文介紹的內容,有真亦是假假亦真的部分,請讀者自行斟酌。具體數據比較敏感,都使用模糊的描述方式代替。

概述
競價廣告,這個在大百度的時代就家喻戶曉的詞彙,相比大家也很熟悉了。顧名思義,競價、競價,廣告位置有限,滿足條件的競爭商家有很多,那麼如何選擇商家對商家排序。價高者應該是在沒有任何數據積累的情況下,最原始的策略。這類廣告的收費模型往往是按照點擊次數付費(CPC),如果價高者得廣告位,但是因爲自身原因或者用戶喜好原因,而沒有發生點擊,那麼既浪費的流量,也降低了用戶體驗。所以除了出價(Bid)因素外,競價廣告還要解決的一個非常重要的問題就是點擊率預估(CTR)。並用 BID * CTR 作爲決定排序結果的主要因子,它直接衡量了該廣告可以給平臺帶來的營收的期望值。
如果你留心觀察(一定要留心,因爲廣告標小到很難看到),會發現淘寶,京東都有大量對競價廣告。下圖展示了餓了麼首頁、分類頁,搜索結果頁面的競價廣告。

整體架構
在深入介紹之前,首先拋出系統的整體架構,大致可以分爲基礎數據層,策略層和應用層。
基礎數據層主要是大數據平臺提供用戶日誌(UBT)行爲,和各種業務數據,包括用戶資料,訂單數據,歷史評價等。
有了這些基礎數據,數據挖掘工程師可以真對業務場景,挖掘出大量的符合廣告場景的用戶商戶基礎畫像,用戶商戶交叉畫像,針對時間和領域的細分特徵,以及抽象用戶當下喜好或者行爲的實時特徵。有了畫像、特徵數據和用戶行爲歷史,就可以用這些打標的歷史數據來做點擊率預估模型和轉化率預估模型,產出通常是模型文件提供給線上使用。
用戶瀏覽請求的第一步會經過Lucene搜索引擎召回粗排結果,例如命中配送範圍內商戶,過濾掉關閉商戶等,如果是搜索頁廣告,商戶要命中搜索詞。獲得粗排商戶列表後,載入用戶畫像、商戶畫像等特徵數據以及業務數據,按照規則做特徵變換得到模型可用數據,然後用模型計算預估點擊率或者轉化率,最後按照規則(可能是比 BID * CTR 更復雜的規則)排序商戶。
應用層是不同業務形態廣告的接入方,可以餓了麼APP首頁分類頁的競價廣告,搜索頁面的關鍵詞廣告,也可能是新零售業務的競價廣告。
下面分別從特徵、樣本生成、模型、在線引擎等方面分別深入介紹一下系統。

特徵維度
在機器學習領域,有一個很著名的說法:數據和特徵決定了機器學習的上限,而模型和算法只是逼近這個上限而已。出去演講,大家基本也是秉承着模型隨便聊,特徵卻閉口不提的潛規則,可見特徵的核心重要度。對於計算廣告這種傳統而特徵容易提取的領域,前期投入到特徵挖掘帶來的質量提升是更明顯的。當然特徵的挖掘也是循序漸進,不斷迭代的,至今我們的特徵工程體系下,主要包括如下種類的特徵:用戶畫像、商戶畫像、用戶商戶交叉畫像、實時特徵、細分特徵等。
1. 商戶畫像。主要刻畫了商戶的屬性,可以使用各種統計數據來做挖掘,不同的業務需求,挖掘的特徵也有所不同。下圖展示了用戶畫像和商戶畫像的分類舉例。
2. 用戶畫像
3. 用戶商戶交叉畫像,這類畫像主要刻畫了商戶和用戶之間的關係,該類特徵可以很好的刻畫反購傾向,有如下若干分類。
4. 細分特徵,細分特徵嚴格 意義來說,並不算是一類單獨的特徵,它是對基本特徵做細粒度拆分的手段。通常有幾種做特徵細分的方式。
a. 按照某個條件細粒的值域擴展,例如gmv是衡量用戶給平臺的總營收的屬性,這個屬性可以按照性別 user_sex (取值1、2) 做拆分,此時一個 gmv 屬性,可以拆成 gmv_user_sex_1 和 gmv_user_sex_2兩個屬性。
b. 按照特徵+值域範圍組合,值域範圍例如時間,例如基礎屬性同樣是gmv,可以按照用戶在不同時間段貢獻的gmv拆分成,gmv_at_morning,gmv_at_noon,gmv_at_afternoon, gmv_night 等。通過這樣的拆分可以更精細的描述用戶,例如上面的例子,對於白天很少點外賣正餐,晚上經常外賣吃宵夜的用戶,區分度就很高。
根據業務敏感度不同,還有更多的細分手段。
5. 實時特徵,用來刻畫用戶的實時行爲,例如當下用戶口味偏好,當下對某個店鋪的喜好程度等。

樣本生成
1. 離線樣本生成
各類畫像數據準備好以後,我們要生成打標的訓練樣本,以訓練模型。打標數據根據在我們的業務下主要是,曝光點擊表(用於CTR模型),點擊轉化表等(用於CVR模型)。我們這裏以訓練CTR模型爲例,主要拆分成如下步驟:首先將各類畫像表數據和點擊日誌做Join操作,操作等 key 值就是用戶畫像或者商戶畫像;得到寬表後(merged wide log),對數據做預處理,例如對於值缺失的,加上默認值等;然後做特徵變換,包括歸一化、分桶、one-hot編碼等,最後得到純數字的,可以被模型訓練使用的樣本表。流程圖如下:
對於專家讀者,這個操作是天經地義的,不過也準備了一個小例子闡述一下特徵工程的做法,假設有用戶畫像如下:
{ "userId": 1000, "sex": "男", "age": 20, "phone": "iphoneX" }
商戶畫像如下:
{ "shopId": 2000, "cateLevel1":"川菜", "cateLevel2":"火鍋", "shop_gmv":300000, "falor":"辣" }
以及曝光點擊日誌如下:
[{ "exp":1, "click":0, "shopId":2000, "userId":1000, "time":"2017-12-12 12:34:00" }, { "exp":1, "click":1, "shopId":2000, "userId":1000, "time":"2017-12-12 14:34:00" }]
那麼我們需要把日誌表裏面的 userId 和 shopId 分別和用戶畫像和商戶 Join 操作,變成擁有所有屬性的樣本表。
[{ "exp":1, "click":0, "shopId":2000, "userId":1000, "age": "20", "shop_gmv":300000, "cateLevel1":"川菜", "cateLevel2":"火鍋", "falor":"辣", "sex": "男", "phone": "iphoneX", "time":"2017-12-12 12:34:00" }, { "exp":1, "click":1, "shopId":2000, "userId":1000, "age": "20", "shop_gmv":300000, "cateLevel1":"川菜", "cateLevel2":"火鍋", "falor":"辣", "sex": "男", "phone": "iphoneX", "time":"2017-12-12 14:34:00" }]
這樣我們就獲得了一條正樣本(曝光了並且點擊了)和負樣本(曝光了,沒點擊)。最後一步我們把數據做特徵變換,變成模型可以使用的數據,例如下面的樣子。
[{ "exp":1, "click":0, "shopId":2000, "userId":1000, "age": "0.3", //歸一化後值,最簡單的 minmax 歸一 "age_1": 1, //歸一化後分桶, //例如分桶爲[0,0.2),[0.2,0.4),[0.4,0.6]..用戶落在編號是1的桶中 "shop_gmv":0.8, //歸一化 "cateLevel1_川菜": 1, //one hot "cateLevel2_火鍋": 1, //one hot "falor_辣":1, //one hot "sex_男": 1, //one hot "phone_iphoneX": 1, //one hot "noon": 1, //根據時間做的自定義轉化,例如抽取時間部分中午 "dayOfWeek_1":1 //抽取星期部分,是星期一 }]
2. 樣本快照
先介紹下這個技術的前提,假設我們已經根據生成的樣本,訓練了模型,模型已經推上線。線上載入模型後,要對當前對用戶,商戶的點擊率做預測,那麼首先線上要載入各類畫像數據,然後做特徵變換,然後用變換後的值輸入模型獲得預測結果。那麼我們會發現,離線部分和線上部分都有Join畫像和做特徵變換這個步驟。而這兩個部分往往使用不同的語言實現,甚至是不同的開發人員實現,一旦出現不一致就很難發現問題所在。
所以,我們的做法是把線上做了特徵變換後的樣本值-樣本快照,傳到 kafka,落到 hdfs,用這部分數據和曝光點擊表做 Join 獲得到離線和線上一致的樣本數據,實踐證明有很明顯的提升。

模型
如果問,有什麼模型常常被同行投來鄙夷目光的,答案應該是邏輯迴歸(LR)吧;如果問,有哪些萬金油模型甚至都被別人忽略她是機器學習模型的模型,那麼應該也是 LR 吧。在很長一段時間裏,系統都是一個 LR 模型,用它預測CTR、CVR。。
在特徵工程發展到前文所提的所有內容後,開始朝着模型方向做很多嘗試,首先嚐試 GBDT,然後 GBDT+LR,再然後是 FM,FTRL,DNN(Deep & Wide)。其中模型部分提升很明顯的有 GBDT+LR,和 FTRL。
關於GBDT、GBDT+LR可以參考我的另外一篇文章,從原理到實踐都有深入的闡述:GBDT的原理和應用。這篇文章把我自行推導的時候不明白的地方都做了重點闡述,仔細閱讀相信可以弄清楚 GBDT 的來龍去脈。
重點說一下 FTRL ,其實它並不是一個模型,而是一種在線學習的模型訓練的方式。傳統的模型訓練和上線的方式一般都是隔天的,定時任務會拉取一定時間的區間的樣本數據,訓練後把模型推上線。而 FTRL,在線學習可以簡單理解爲根據線上用戶的實時瀏覽和訂單行爲,不斷更新模型。當初上線這個模型的時候,工程師們有一種養寶寶的感覺,隨着時間的流逝發現AUC不斷攀升。
FTRL 的訓練也可以使用融合模型,類似於GBDT+LR的思想,例如使用預先訓練好的 GBDT模型的葉子輸出(相當於組合特徵),作爲FTRL的輸入,然後實時更新 FTRL 部分的模型權重。線上使用同樣的 GBDT 模型,然後用該GBDT模型在樣本上的葉子輸出和 FTRL 訓練的權重計算出結果作爲結果。下圖反映的FTRL的在線學習框架。
實時數據源主要來源兩部分數據,UBT系統和業務數據,UBT的數據可以痛過消費 Kafka 的方式直接接入,業務數據可以通過 Canal 等組建(餓廠是自己的DRC)拉取 mysql binlog內容,然後把業務數據庫讀寫發送到 Kafka 上。FTRL 使用 storm 部署,逐條消費實時數據,對模型更新,並把模型參數寫入到 Redis 中。線上預測服務,根據需要讀取畫像數據、融合模型、以及FTRL的參數數據,進行預測。
既然打通了實時數據流,也可以做到實時的 AUC 監控。做法是線上每次執行一次排序,都會生成一個唯一隨機數 rankId,然後把排序結果通過 kafka 傳到 storm中。storm 通過消費 UBT 日誌、對比評分結果就可以實時的計算出模型的 AUC,再把這些數據實時推到 Metrcs 系統。事實上,實時監控非常強大好用,可以極大的提高模型的反饋速度。
當然不得不提的是,對於模型預測出來的值,還需要使用校準獲得逼近真實的點擊率,這樣使得計算 BID * CTR 真是反映營收期望,以便和其它指標融合的時候更有效。例如線上可能採用如下方式作爲平臺優化目標:
g = b*t + \beta *v
其中 b 代表商戶出價, t 代表預估點擊率, \beta 是一個係數可以配置, v 代表預估轉化率。有時候,廣告營收和產品體驗之間要做一些權衡,融合其它指標是個很好的方案。如果預測出來的點擊率不是真實的點擊率那麼融合其它指標的時候,整體目標就會失效。校準部分一般採用保序迴歸校準的方式。

在線引擎
隨着目標指標的增多,模型種類增多,融合的手段增多,線上部分也變得越來越複雜,下圖展示了線上引擎部分的框架。
首先接入AB測試平臺後,平臺會爲給用戶分配要執行的策略。規則引擎部分配置了該策略需要使用的指標(預估點擊率、轉化率等),每個預測指標需要的基礎數據以及每個指標需要採用的模型等。
然後按照規則引擎的定義,加載線上需要的各種基礎數據,做特徵轉換,輸入模型得到預測結果,然後進行校準。最後把各個指標的值,按照規則引擎的定義組合最後獲得商戶的排序分。
上圖中多了一塊插件模塊,真對廣告領域 CTR 預估,很多廠做了一些真對出價的優化,包括淘寶的OCPC等。這些部分可以真對所有指標預測都可以使用,可以做成插件的模式,可以做到隨時插拔使用。

結論
競價廣告這款產品走到今天,無論從變現效率,還是營收體量都是一款很成功的產品了。而本文內容,對於流量大廠會顯得一點也不陌生,甚至可能會略有初級。當然對於小廠或者剛剛嘗試流量變現的流量巨頭,依然是有借鑑意義的。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章