廣告系統架構:要啥自行車!
作者|面包包包包包包
修改|寒小陽 && 龍心塵
上一期我們一起探索了計算廣告的基本概念和四種形式(點擊查看《計算廣告小窺(上)》),和計算廣告的關鍵技術(點擊查看《計算廣告小窺(中)》)本期文章是我們為讀者帶來的【計算廣告小窺】專題的第三個部分。這個系列的專題到此就結束啦,希望系統學習計算廣告的同學可以回顧三篇文章。
(上)(中)(下)全文目錄
- 引言
- 廣告=>互聯網廣告:“您好,了解一下”
- 互聯網廣告=>計算廣告:指哪兒打哪兒!
- 計算廣告四君子:誰在弄潮?
- 計算廣告關鍵技術:這孫子怎么什么都知道?
- 廣告系統架構:要啥自行車,這里有寶馬。
- 手把手系列之教你搭建一個最小廣告系統:mieSys
6. 廣告系統構架:要啥自行車!
一句話解釋廣告系統架構:“道生一,一生二,二生三,三生萬物。”
場景1
坐在車里,手機打開為知筆記,想再瞅一眼的樹的幾種遍歷方法。眼睛跟著遞歸,思緒卻爆了內存:面試官長什么樣?他會問我什么問題?部門名字聽起來還挺高大上的?面試完在附近吃點什么呢?聽同學說附近的小吊梨湯很贊啊!面包包包,那就小吊梨湯吧?好啊好啊,出來再加個西少爺肉夾饃吧?好啊好啊!“噗”的一下笑出了聲,還好司機師傅并沒有在意。我連忙收起自己的小尷尬,平復一下心情,然后開口問道,“師傅,今天您拉幾單了?”
場景2
原來大家工位都是在一起的呀。這這會兒燈都關著,還有午休呢。門口小哥和我差不多大,聊的還不錯。面試官還沒來,先把簡歷和白紙都擺擺好。一切準備就緒,抿了一口水,可以,這很怡寶。
場景3
面試官:你好,請坐(拿著簡歷開始看),先簡單介紹一下自己。
我:blablabla…
面試官:嗯,來寫道題吧。
我:正面鋼,不能慫!揮筆寫下了一行代碼:
return "燙燙燙" == "屯屯屯" ? "燙屯燙" : "屯燙屯";
面試官:
我:
面試官:加個微信吧,以后要是沒事兒了咱們斗圖玩兒。
我:哪兒斗得過您呀,跟著您多收藏幾個表情,來我掃您二維碼。
場景 4
leader:聽說你們剛剛斗圖斗的很開心,我這兒沒圖,咱們換一種玩法吧。
我:我心想沒圖你說個。。說一聲啊,我發您。
leader:不鬧了哈,我看你簡歷上說你對計算廣告有些了解,那你能不能通過一個case能讓我知道你對計算廣告都了解到什么程度呢?
我:我也頓時來了精神,這個問題好啊!我覺得最好的case是走一遍廣告投放的整個流程,在商業邏輯的指導下帶出系統框架、功能模塊和關鍵技術,不知您是否感興趣?
leader:非常好,那你打算從哪里切入呢?
我:就從我們來的地方吧,不忘初心。
時間回到那個清晨,網站收入報表錯落著疊放在桌子的一角,左手旁是一杯冷了的速溶咖啡,鼠標有些油膩,用了一年的Cherry青軸依然趁手。敲下最后一個回車,他兩手交疊,揉了揉兩手酸脹的虎口,“呵,這一夜”。窗外已蒙蒙亮,他有點興奮,因為今天的太陽,特別好看。
我們在《計算廣告小窺[上]》中提到過,互聯網廣告相較于傳統廣告,顯著之處就在于廣告效果可以被衡量。在用結果說話的今天,數據自然擁有著至關重要的戲碼。對于媒體網站來說,最重要的數據莫過于用戶在什么時間,從什么地方,在網站上做了什么事情。有了這三方面的基礎數據,理論上我們可以做任何我們想做的事,譬如在《計算廣告小窺[中]》里我們討論過的受眾定向,為用戶打上標簽,這才有了餅圖中的男和女;又譬如點擊率預估,將用戶可能點擊的廣告放在最顯眼的位置上,提升網站收益。自計算廣告誕生以來,類似的應用和場景數不勝數,時刻為用戶、廣告主和用戶服務著。為了能夠準確無誤的完成上述使命,一個好的廣告系統必不可少。那么問題來了,想要完成一次廣告投放,需要我們的廣告系統具備哪些功能呢?下面我們實地走一遭,完成一次廣告投放,看看在這個過程中我們會遇到什么問題、我們如何分析以及如何去解決。所謂一個系統的設計思路,大抵如此吧。
萬事俱備,只欠case,具體的case怎么選呢?我替大家選啦!目前為止,我們對餅圖應該是最熟的,它那咱們就“重走長征路”,看看如何得到這張餅圖,然后用餅圖來指導廣告投放吧。OK,我們來定義一下問題,我們要完成的是:從數據中挖掘出用戶的性別,根據性別為用戶展示TA們最可能點擊的廣告。好了,問題定義完畢,在實際操作之前先從方法論的角度分析一下什么是廣告系統,主要有微觀和宏觀兩個方面。
6.0 方法論之——“先把書讀厚”
先看前半句,從數據中挖掘出用戶的性別,這個好理解,輸入是媒體網站的數據,輸出就是每個用戶的性別,典型的分類問題嘛,打個標簽,規則也好,機器學習也好,都是可以做的。后半句呢,根據性別為用戶展示TA們最可能點擊的廣告,輸入是用戶性別,輸出是廣告。這些廣告是哪兒蹦出來的?想必一定是有一個廣告庫,這些廣告是被挑選出來的,而挑選的依據就是性別。再有,什么叫最可能點擊的廣告?這個很好理解,當然是用戶感興趣的廣告啦,光感興趣還不行,你還得讓用戶看到,這就需要排序了,把用戶點擊率最高的廣告放在最顯眼的位置上。有沒有覺得這些字眼都很熟悉呢?分類,標簽,點擊率,排序,我們好像在哪兒見過?這不就是我們在中篇里討論過的關鍵技術嘛!看來那些高大上的關鍵技術也是很接地氣的,就這么一個看似簡單的投放場景,這些技術我們幾乎都用到了,好像有點意思哈!現在讓我們將上述過程進一步具體,讓程序員們可以看懂,便可歸納出下述表格。
根據這張表,一個模型已經清晰地呈現在我們眼前,如上圖。在這里,“輸入-系統-輸出”是一個非常基本且通用的模型,大家可以在很多交叉學科里見到它的身影,例如通信工程里的《信號與系統》和《通信原理》,或者控制工程里的《現代控制原理》,再如機器學習中模型的訓練過程,抽象出來都是如此。雖然應用場景各有千秋,但是核心問題只有三個:輸入是什么?輸出是什么?如何保證系統的穩定性?想要回答這三個問題其實也很容易,以問題場景與核心需求為導向,多問幾個為什么即可。所謂:“道生一,一生二,二生三,三生萬物”,就是這個道理。
方法論介紹完,微觀和宏觀都有了,現在讓我們回到廣告系統中來。系統的輸入是媒體網站的數據,輸出是排好序的廣告,中間部分便是我們要設計的了。得嘞,那咱們走著!
6.1 日志模塊
一句話解釋日志模塊:我有一個小咪咪秘密
系統的原始輸入是媒體網站的日志數據,具體而言就是網站的訪問日志以及用戶的行為記錄。想不想偷偷看一眼?就一眼哦。
挺丑的哈~丑不要緊,我們有split(” “)!從日志中我們可以看出,每一條記錄都是由IP地址、訪問時間、GET請求、資源URL和HTTP Header組成的,其中時間就是訪問時間,IP地址表示用戶所處位置,做了什么就是GET。可是所有人的數據都堆在一起,我哪能分清誰是誰呢?不是有IP地址嘛!IP地址相同的就是一個人。這個思路可以,但一般不這么用,因為IP地址一般是動態的,不夠穩定,而且有NAT這種東西存在,粒度不夠細。那怎么辦?用Cookie!
Cookie,這個?
噢不不,是這個。
Cookie往簡單了說,就是媒體網站給用戶起的名字,作為用戶在該媒體網站上的唯一標識。有了Cookie之后,媒體網站就能很方便的從日志文件里區分出每個人的行為記錄,然后就可以給每個用戶打上合適的標簽,做受眾定向了。哇噻,這么簡單呀!有數據,有Cookie,做完受眾定向就能輸出性別啦?沒錯,從原理上講的確就這么簡單,輸入和輸出都有了,這個日志模塊算是走完了。但工業上要更復雜一些,因為我們一直沒說這些日志文件都存哪兒了。心想這有什么好聊的呀,存個文件或者存個數據庫不就完了?NONONO,門戶網站每天訪問量都是按億算的,簡單方法達不到要求。那工業上用的是什么呀,答曰Hadoop——分布式數據處理平臺。(以下開源工具部分內容摘自劉鵬、王超老師著作《計算廣告》,人民郵電出版社)
通常情況下,數據處理需要一個能夠存儲和加工海量數據的基礎設施,實際上這也是大多數大數據系統都需要的平臺。在開源的這類平臺工具中,Hadoop幾乎是工業界的標準選擇。Hadoop的核心架構包括HDFS、Hadoop MapReduce和HBase,其中HDFS是GFS(Goole File System)的開源實現,MapReduce是Google MapReduce的開源實現,而HBase則是Google BigTable的開源實現。
HDFS是一種易于橫向擴展的分布式文件系統,提供大規模數據文件存儲服務,支持PB級數據規模。它可以運行在上萬臺的通用商業服務器集群上,提供副本容錯機制,為海量用戶提供性能優越的存取服務。計算廣告系統里的海量日志文件等就是通過數據高速公路傳送,最終存儲在HDFS上,為各種離線計算任務提供服務。
Hadoop MapReduce是一種分布式計算框架,顧名思義,它由兩個部分組成:Map和Reduce。Map是將一個作業分解成多個任務,而Reduce是將分解后多任務處理的結果匯總起來。在程序設計中,一項工作往往可以被拆分成多個任務,任務之間的關系可以分為兩種:以是不相關的任務,可以并行執行;另一種是任務之間有相互依賴,先后順序不能夠顛倒,MapReduce適用于第一種類型,龐大的集群可以看作是硬件資源池,將任務并行拆分,然后交由每一個空閑硬件資源去處理,能夠極大的提高計算效率,同時這種資源無關性對計算集群的橫向擴展提供了最好的設計保證。
在廣告系統中,Hadoop主要承擔著離線數據的存儲和計算需求,可以說是計算廣告系統進行大規模數據處理不可或缺的基礎平臺。無論受眾定向、點擊率預估還是基礎的報表生成,都需要在Hadoop上進行大規模的數據處理。
到這里,媒體網站數據的存儲方式就很清楚了,它們分布式的存儲在HDFS中。當我們需要做統計或者計算任務時,可以通過編寫MapReduce程序來實現。搞定了日志的存儲和Cookie分配,日志模塊就算是告一段落了。有了穩定的數據,系統才會有穩定是輸入。現在數據有了,怎么得到用戶性別吶?請看下一節,受眾定向模塊。
6.2 受眾定向模塊
一句話解釋受眾定向模塊:雙兔傍地走,安能辨我是雄雌?
日志模塊為媒體網站提供了大規模的存儲和計算服務,為廣告系統穩定的數據輸入提供了強有力的保障。接下來的任務是根據日志數據來判斷用戶性別,在開始之前,我們先來看看古人是怎么判斷兔子性別的。
《木蘭詩》中寫道“雄兔腳撲朔,雌兔眼迷離;雙兔傍地走,安能辨我是雄雌?”小時候每次讀到這里就覺得智商受到了侮辱,一個瞇著眼,一個亂撲騰,倆走一塊兒怎么就看不出來雌雄了?我看很容易嘛!提溜起耳朵,眼睛瞪的溜圓亂舞扎的是公的,瞇縫著眼睛畏手畏腳的是母的。所以木蘭你還真認為自己沒有被認出來嗎,我怎么覺得是大家不愿點破呢。至于不愿點破的原因,是個細思極恐的故事,一會兒電臺就不讓播了。
說完兔子現在來說人,上面我們用“腿+眼睛”的不同表現來判斷兔子公母,這種方法叫做“規則”,放程序里就是個if..else..。現在我們要判斷人的性別,場景雖然遷移,但解決問題的方法并沒有改變,那都有哪些規則可以用來判斷人的性別呢,先來看看下面兩個用戶的購買記錄吧。
用戶A和用戶B的性別分別是什么?這個應該還是很明顯的,因為他們分別買了多個有明顯性別傾向的商品,例如裙子和女鞋,男襪和男鞋,所以A是女性B是男性。從這里我們可以得到一個非常簡單并且符合直覺的假設:如果一個用戶經常瀏覽或購買女性的商品,那么該用戶可能是女性,反之是男性。假設有了,那我們假設的正確嗎?迭代驗證之后發現準確率高達90%(我編的),現在我們可以用它來區分用戶性別了。這種規則的實質上是一種投票與統計的方法,看這個的行為記錄是更像男性一些,還是更像女性一些,最后取其大者即可。一提到統計,大家都很熟悉,定義一個計數器即可。但是我們的場景是存儲在HDFS中的海量數據,如何來實現這步操作呢,用MapReduce嘛,下面我隨手寫個代碼,大神請輕噴!
話說這么著來判斷用戶性別,是不是太隨意了點。才不是呢!畢竟這個策略是符合業務場景的!好吧好吧我承認是我偷懶沒有去研究更多更先進的算法和模型,磚我是扔出來了,坑我也挖下了,下面就看您各位的了,口喜 口喜~
不經意間,我們已經完成了一個系統單元的設計了,它的輸入是HDFS中的日志數據,輸出是用戶性別,中間的數據處理是受眾定向,Step1搞定啦!
基本的說完了,再延伸一些工業中常用內容吧,以下內容來自《計算廣告》。我們得到的用戶性別通常情況下是一個{key : value}鍵值對,key是用戶的cookie_id,value是性別,1代表男0代表女。一般來說,這種鍵值對特征的數目非常龐大,無法放進廣告投放機的內存中,需要采用獨立的緩存服務。在這樣的需求下,這種緩存服務的特征非常明顯,一是往往只需要存儲簡單的鍵值對,二是大多數情況下需要支持高并發的隨機讀和不太頻繁的批量寫。在這樣的需求下,Redis是比較合適的開源工具之一。
Redis是一種NoSQL數據庫,它主要提供的是高性能的鍵值存儲,采用的是內存數據集的方式。Redis的Key可以包括字符串、哈希、列表、集合和有序集合等數據類型,因此也被稱作是一款數據結構服務器。Redis會周期性地把更新的數據寫入磁盤或者把修改操作寫入追加記錄文件,并且在此基礎上實現了主從同步,具有非常快速的非阻塞首次同步、網絡斷開自動重連等功能。同時Redis還具有其他一些特性,其中包括簡單的check-and-set機制,pub/sub和配置設置等,使得它能夠表現的更像高速緩存(cache)。Reids還提供了豐富的客戶端,支持現階段流行的大多數編程語言,使用起來比較方便。在使用了Redis存儲用戶性別之后,我們的廣告系統現在長這樣,思路應該還是挺清晰的,嗯嗯。
6.3 廣告檢索模塊
一句話解釋廣告檢索模塊:找我啊,找到我就讓你嘿嘿嘿
邁出了第一步,漸入佳境,趁熱打鐵我們來看第三個模塊:廣告檢索。在這個模塊中,輸入是用戶性別,輸出是候選廣告集合,這些廣告該怎么找呢?
有人說了,這簡單呀。現在要為一位女性喜歡買鞋的用戶找一些合適的廣告,直接在廣告數據庫里寫一句SELECT * FROM TABLE_NAME WHERE USER_TAG = "shoes" AND USER_SEX = "female" 不就搞定了嗎?沒錯,這是一種方法,我在mieSys最小廣告系統(Github)里也是這么做的,但是可以十分肯定的說,這么做是不太合適滴。
朝陽群眾:啥?
西城大媽:387,到北京西站387。 海淀網友:寶寶心里苦,但寶寶不說。 吃瓜群眾:自己用不讓我們用,要不要臉? |
好了好了大家消消氣,我承認是我將問題簡(偷)化(懶)了。誠然,用數據庫的確可以實現廣告的檢索,但是在大規模的場景下,這種方法幾乎不可用,感興趣的同學可以在一個1000W行的表里寫一個SELECT試試,耗時十分感人。阿里有10億商品,這要是檢索一次,嗯。。
朝陽群眾:嗯?
西城大媽:剛上車的乘客請往里走。 海淀網友:寶強真是可憐啊,不過以后當個經紀人好像也不錯。 吃瓜群眾:然后嘞,那還能咋查? |
除了數據庫,還有更通用的檢索方法,常見于搜索引擎中,這就是倒排索引。所謂倒排索引,就是根據結果查原因。舉個不恰當的例子,我們都知道1+1=2,從1+1得到2是正排索引,那么從2得到1+1就是倒排索引。如果這個解釋還是很抽象的話,那就用程序員的方式吧。
這段代碼中,doc_tokens是一個字典,key是文檔id,value是該文檔中出現的句子,分詞之后以單詞(token)的形式存在。tokens_docid也是一個字典,key是token,value是出現過該token的文檔id。當我們想要在搜索引擎中檢索同時包含“谷歌”和“Wave”的網頁是哪一個,對兩個token的結果求一下交集即可,即D3。
朝陽群眾:噢?
西城大媽:年輕人來少坐會兒,給老人小孩讓個座兒。 海淀網友:寶寶去上訴了,看他面容好憔悴啊。 吃瓜群眾:還是沒看懂倒排跟廣告檢索有啥關系? |
受眾定向模塊所完成的,就是給用戶打上各種標簽;而廣告檢索模塊將要完成的,就是根據這些標簽為用戶召回相關的廣告。這里面其實有三方關系:用戶標簽、廣告標簽和廣告。通常,用戶標簽和廣告標簽是存在著映射關系的,所以我們可以通過用戶標簽,來找到相應的廣告標簽。如果將廣告看作是doc,將廣告標簽看作token,那么通過廣告標簽找廣告的過程就是倒排索引。
鑒于上述描述,廣告檢索通常也用倒排索引來實現,其中查詢的條件可以看作一個由“與或”關系連接的布爾表達式,例如我們剛才提到的一位用戶標簽為“喜歡買鞋的女性”,其對應的廣告標簽就是“類別:鞋” 和 “性別:女”的交集。根據標簽“類別:鞋”我們可以檢索到廣告集合S1,根據標簽“性別:女”可以檢索到廣告集合S2,二者取交集之后的結果,記為我們檢索到的廣告。
朝陽群眾:哈?
西城大媽:前方到站是阜成門南,下車乘客請提前換到車門處,下車請刷卡。 海淀網友:寶強在美國那個別墅一般般啊,那個會說英語的“哥哥”會不會是經紀人呀。 吃瓜群眾:有點意思了,那這些檢索到的廣告都有用嗎? |
非常好的問題,檢索到的廣告都有用嗎?假設我們只有用戶的性別標簽,阿里有10億商品,男女各一半,那我這一下就得到了5億條商品的廣告。下面用這5億條去做CTR排序,我想那一定是瘋了,肯定不是這樣的。通常情況下,我們會將這些檢索得到的廣告通過模型的方法做一下截斷和粗選,將頭部相關性較高的保留下來作為廣告檢索的最終結果。其實在實際的工業場景中,類似具體的問題還有很多,例如用倒排索引的方法做廣告檢索其實還會遇到一些具體問題,這里暫不細表,感興趣的同學可以看一看《計算廣告》P223。
廣告檢索的完成,意味著我們的Step2完成了。萬事俱備,只欠Ranking,想想還有點小激動呢!現在我們的廣告系統,就長這樣啦。
朝陽群眾:嗯,沒人吸毒。
西城大媽:終點站北京西站到了,祝您旅途愉快。 海淀網友:兒子還真不像寶強-_-。 吃瓜群眾:原來是這樣,我聽懂了。那現在既然找到了廣告,說好的嘿嘿嘿呢? |
面包君滿臉黑線,撒腿就跑,邊跑邊說“追我呀,追到我我就讓你嘿嘿嘿。略~~~”
6.4 CTR預估模塊
一句話解釋CTR預估模塊:排排坐,吃果果。
終于來到了最后一個模塊,該模塊的輸入是候選的廣告集合,輸出是一個根據用戶pCTR從高到低排序的一個廣告序列。
在計算廣告[中]里我們曾經介紹過CTR預估相關內容,下面我們簡單回顧一下。
點擊率與點擊率預估的對比,就是0.1%與那80%。之所以點擊率預估十分重要,是因為它直接關系到媒體網站的收入,也直接關系到廣告主的推廣效果。廣告位的個數就那么幾個,顯眼的更少,憑什么把你放在頭條呢?靠的就是點擊率預估。
點擊率預估是機器學習中十分經典并且難度極高的問題。既然聊到了機器學習,那一定得聊一聊特征選擇及構造,模型的選擇和調參,這其中任何一個單拎出來都是工業界中十分熱門的話題。在這里,我就來個拋磚引玉,看看常用的思路都有哪些。
6.4.1 點擊率預估綜述
用于點擊率預估的數據主要是日志數據,一般會有點擊行為(點擊為1,沒點為0)、廣告信息(廣告位、廣告主id、廣告標簽和廣告描述等)、用戶信息(用戶id和用戶標簽等)、上下文信息和時間戳等。有了這些原始數據之后,需要對數據進行清洗,然后利用統計或模型的方法構造特征,進而做特征選擇和特征組合,最終特征的數量級大約在10億-100億維。完成了特征工作之后,在模型方面,較為經典的點擊率預估模型是線性模型Logistic Regression,由于LR在通過sigmoid之前是一個[0,1]之間的浮點數,利用LR的特點,我們可以將這個浮點數作為用戶點擊該廣告的概率,把廣告按照這個概率從高到低放置在相應廣告位上,就完成了廣告排序。
6.4.2 特征工程
1.特征分類
- 從數值上看,特征主要分為連續型特征和離散型特征。連續型特征是指特征值是一個可連續變化的實數,例如某個廣告的點擊次數{ad1:87, ad2:13, ad3:2};離散型特征是指特征值非0即1,例如{性別:0}表示該用戶是女性,{性別:1}表示該用戶是男性。
- 從來源上看,可以分為統計特征和概率特征。統計特征就好比上面提到的廣告點擊次數,是經過簡單統計得到的絕對值累加。概率特征例如某個廣告的點擊率(點擊量/展示量){ad1:0.01, ad2:0.13, ad3:0.07}。
2.特征表示
- 離散化。離散化要完成的任務主要是對連續型特征做分類,拿用戶年齡舉例。年齡是一個在0~100間的實數。在一般的業務場景中,我們不會去care用戶到底是21歲還是22歲,但是會care用戶是11歲還是21歲。鑒于此,我們可以將年齡按10歲為間隔做一下分類:1~10歲用1表示,11~20用2表示,以此類推。間隔的選取要依賴具體業務場景,在人口統計中間隔10歲可能比較好,但在電商中,可能1~18代表1,18~24代表2效果會更好一些。
- 歸一化。歸一化要完成的任務是使不同連續特征間建立起可比關系,拿成績和GPA來舉例。成績一般是百分制,比如{score:87},GPA一般是4分制,比如{GPA:4.0}。如果單看數值,那87肯定要比4大,但是實際上4.0在GPA中代表的是優秀:90~100分,比87要大。所謂歸一化,就是當前特征值在該特征范疇下的相對大小,score:87就是87/100=87%,GPA:4.0就是4.0/4.0=100%,這下兩個特征間就產生了可比性。歸一化的方法也有多種,這里就不多說了。
- Dummies。有人叫它“啞變量”,我總感覺怪怪的,就叫原名吧。Dummies是實現One-Hot的一種方式,例如特征性別{1:男, 2:女, 3:不詳}。在這里,1,2,3僅僅用于指代作用,并沒有數值上的大小關系,但是對于模型來說,1、2、3這樣的值會影響模型的迭代,因為在梯度下降中
1:男—-> [1, 0, 0]
2:女—-> [0, 1, 0]
3:不詳—>[0, 0, 1]
通過Dummies,我們將一維特征擴展到了三維,既保留了特征的物理含義,也使得模型訓練更加可信,是不是好了很多呢~
3.特征組合
特征組合是一個充滿了智慧和經驗的領域,花樣繁多,令人贊嘆。這里說一種常規的方法:笛卡爾積。
在數學中,兩個集合X和Y的笛卡兒積(Cartesian product),又稱直積,在集合論中表示為X × Y,是所有可能的有序對組成的集合,其中有序對的第一個對象是X的成員,第二個對象是Y的成員。
其實之前我們已經了解特征組合了,在哪里呢?嘿嘿,還記得那位“喜歡買鞋的女性”用戶嗎,讓我們看看在特征層面如何表示這種信息。假設我們有一個特征,叫做商品類別{1:上衣, 2:裙褲, 3:鞋, 4:其他}, 還有一個特征是用戶性別{1:男, 2:女, 3:不詳}。通過笛卡爾積,我們可以得到新特征“喜歡買鞋的女性”{(商品類別:鞋), (性別:女)},至于特征值嘛,一般常見的操作就是加減乘除對數之類的。
4.特征選擇
同特征組合一樣,特征選擇更是一個將“人工的智能”體現的淋漓盡致的領域。特征選擇的根本任務,是找出那些影響力大,冗余性小的特征集合。最理想的情況當然是獲得描述問題的不同“角度”,一個不多一個不少。
理想是求最優解,但是顯然這是一個NP Hard的問題,即便如此,也難不倒我們的各路數據英雄。他們個個身懷絕技,充分發揮主觀能動性,在實戰中練就了一身特征選擇的好本領。
從方法論上來說,特征選擇有三種方法:Filter、 Wrapper和Embedded。Filter通常用來做預處理,通過特征與label之間相關性(主要是統計信息,例如互信息、顯著性檢驗等)的評估,先過濾掉一部分;Wrapper是指將特征子集帶入模型,通過模型效果來進行特征重要性的評估;Embedded是指特征選擇和模型訓練同時進行,直接決定是選擇特征還是拒絕特征,比較經典的是決策樹和神經網絡。就實戰方面而言,我常用的有下面幾種方法,還請各路英豪多多指教:
- 利用統計方法,評估特征重要性
- 利用L1正則將不重要的模型,刪除權重為0的特征
- 特征帶入模型,根據權重算特征的相對重要性
- 暴力循環,如果加上該特征效果更好就保留,否則不加
不知不覺說了這么多,還是沒說廣告點擊率預估的特征工程到底該怎么做呀。其實任何機器學習問題都是有場景的,即便都是CTR預估,所面臨的數據規模,業務需求都不一樣,所對應的特征工程也各有千秋,但總歸起來方法大致就是這些。至于我是怎么做的,其實沒用太復雜的東西,能滿足我的需求即可。在下一章介紹最小廣告系統mieSys(Github)時會大致說一下,這里就略過啦。
6.4.3 模型選擇
就模型方面來說,DNN幾乎橫掃了數據領域各個會議,無論哪個領域都要把CNN, RNN和LSTM套進來試一試效果。即便如此,LR在CTR預估中的霸主地位還是很難撼動的,這玩意兒實在太好用了,經過優化那是又快又準。DNN在語音、圖像和自然語言處理領域的成效是有目共睹的,但是面對廣告這樣的高維向量也是犯起了老大難,直到最近注意到有用FM做embedding做降維的做法,倒是可以較好的解決這個問題。至于Online Learning方面,FTRL還是很好用的,國內好幾家都在用。
上面這一段說下來,忽然覺得自己好像懂很多的樣子。。好了,不裝了,我去啃論文推公式了!關于模型選擇就說這么多,我是忠實的LR粉,沒啥說的,表衷心!至于Deep Learning,這種沒有理論依據就靠矩陣運算顛過來倒過去不是Embedding就是梯度彌散再者就是Relu或者Dropout的東西,對此我只想說:請帶上我!
不知不覺,特征和模型都說完了,這就意味著CTR預估模塊講完了?CTR預估講完了,候選廣告有了序,TopN的一展示,我們的任務就完成了?來對照一下問題定義。我們要完成的是:從數據中挖掘出用戶的性別,根據性別為用戶展示TA們最可能點擊的廣告。我們將問題分解成多個基本的“輸入-系統-輸出”模塊之后,先后完成了單元模塊的設計,最終打通了整個系統的流程,經過多個模塊的處理和流水線式的輸入輸出,我們確實得到了我們想要的結果。
沒錯!你看那主頁上那廣告不是達芙妮的女鞋嗎!
我們的系統建成了,就是這么簡單!
興奮著興奮著,突然就清醒過來,看了看四周,原來我還在那個會議室里,已經過去了將近兩個小時。對面坐著leader,正慈眉善目的看著我,悠悠的說了句:
“不錯,挺好的。但是,是不是少了點什么?”
我一愣,少了點什么?不少呀!這不都挺好的,廣告也展示出來了,功能也實現了,還少啥?但是又仔細一想,難道leader是想問那些?噢噢那還真是少了。我不好意思的向leader吐了個舌頭,“嗯,確實還少了些東西”。
6.5 Server模塊
怎么把這個給漏了呢,說好的場景是媒體網站,沒有Server就意味著沒有頁面,給用戶看個啥?嗯嗯這個不能少。
6.6 計費模塊
這個是最不該漏掉的,既然是廣告系統,那怎么能不提錢呢?剛才的廣告確實是展示了,但是廣告商的賬戶里還有余額嗎?額…好像,沒了。。
6.7 反作弊模塊
這個模塊大家可能都不太熟悉,其實我也不太熟,但它卻至關重要。我們所有的決策和算法,都是建立在數據的基礎上,那么有一個非常嚴肅的問題:如果數據是錯誤的,甚至是假的呢,這些策略還有效嗎?想到這里,我是覺得背后一涼,很難想象那種金玉其外敗絮其中的場景,嗯補上補上。
leader點點頭,說“基本都補上了,那么,還有嗎?”。
面試到這種程度,看來必須要放大招了。“有,看圖!”
這張圖是劉鵬老師在網易公開課中講課時用到的,是工業級別的在線廣告系統的框架圖。從里面找找我們剛剛討論過的吧。
數據模塊找到了嗎?最下面綠色的,Data Highway以及Session log generation。受眾定向呢?就是Audience Targeting。然后到了中間,Ad retrieval就是廣告檢索,看到和它連著的Ad index了嗎,倒排呀!隨后就是CTR模塊,是CTR Model以及Ad Ranking。這就是最基本的四個模塊,那后來加的三個呢?Server就是Web,在左上角和中間上部;計費和反作弊都在右下角。嗯,看來咱們弄的還挺全乎的。
那其他那些模塊是什么呢?我也只是知道個大概,這里就不獻丑,有了解的同學還請多多指教。
場景5
leader沉思許久,最后沖著我重重的點了點頭,說了句河南話:“中!”
我趕緊回了句,“謝謝”。
leader神秘一笑,“那下面我們來做道算法題吧…”
我心說什么?廣告系統都有了,還要做題!要啥自行車?上表情包!
leader:哈哈開個玩笑,恭喜你,面試過了。
我:謝謝您!Mua~~~~
場景6
大眾點評搜索“小,吊,梨,湯”。噢!在這兒呢,不遠不遠,看了下評價還不錯。剛邁開步子準備過去,路邊站著一位小姑娘,懷里捧著一沓宣傳單,給過路行人發放著。我走過去,她注意到我,熟練的抽出一張,笑著說道:
“您好,請了解一下”。
6. 展示廣告最小系統mie Sys
這一章就隨便聊聊mieSys的來歷吧,不講技術了。
mieSys的地址是http://115.159.33.50/,這兩個月來多次被抓肉雞,可能是Redis的問題,最近穩定了。前不久我將系統開源了,代碼寫的不好,好多地方都可以優化,先放個v1.0吧Github地址:https://github.com/breadada/mieSys
為什么想做這個最小系統呢,僅僅是因為覺得好玩。之前在海淘的時候,就被Amazon的推薦效果給驚到了,我剛點了一雙鞋進去,再次退到首頁的時候,大多數廣告位都與我剛點的那雙鞋有關,或者是同一品牌,或者是同一款式。當時我就心想,我也要做一個。后來劉鵬和王超老師出了《計算廣告》,讀到后面有介紹開源廣告框架,我心想這好啊,比葫蘆畫瓢的整一個唄?還正在猶豫中,就被介紹Nginx的一句話打動了:
在廣告系統中,用Nginx作為前端Web服務器,而將廣告投放機的功能用C/C++語言實現成fastCGI插件,是一個開發成本較低、性能又很不錯的方案。實際上,這一方案已經實現了一個基本的廣告投放機,從事最簡單的廣告投放業務,而其他模塊和功能則可以根據需求逐步開發。 |
后 話
對相關內容感興趣的同學,還請參閱劉鵬和王超老師所著《計算廣告》,有更精準的定義、描述與更詳細的講解,到這里,整個《計算廣告小窺》系列就結束了。
【本文是51CTO專欄機構大數據文摘的原創文章,微信公眾號:大數據文摘 id: BigDataDigest】