騰訊比賽總結反思-附top選手的方案


導語

作爲一個剛把python用熟了一點的並且從未接觸過數據挖掘比賽的新人,第一次參加比賽並獲得騰訊比賽rank19名,我有很多幸運的地方同時也留下了不少的遺憾。這篇文章的目的首要是想感謝帶我上分的兩名超強隊友@苜蓿@大萌王朝高肅卿 ,其次是對比賽中留下的種種遺憾作個總結。


這篇文章將分爲四個方面:第一,賽題簡介;第二,我們的解決方案;第三,top選手的解決方案以及反思;第四,我的新手比賽歷程。對於比賽選手來說,第二和第三部分可能會對你們有所幫助。對於數據挖掘的新手來說,第四部分我的學習經歷可能會更有用。

01

賽題簡介

本次騰訊比賽的目的是希望選手利用歷史的廣告曝光信息,來預測未來某一天某種廣告配置屬性下面的廣告的日曝光量大小。


賽題評判的規則主要分爲兩個方面,分別是準確性指標,也就是預測的日曝光量跟真實值是否接近,另一個是單調性指標,也就是廣告主的出價越高是否廣告的日曝光也越高。初賽給出了近一個月(需要分析)的每條廣告每天的曝光信息,複賽給出了十幾天的每條廣告曝光信息以及其競爭對手的信息(競爭對手的信息非常有用,隱含了廣告的競爭力)。賽題手冊上面出現了很多廣告相關的專有名詞,對於新手來說還是需要一定時間去理解的。


後臺發送“2019騰訊比賽”,返回賽題手冊連接。


02

我們的解決方案


初賽階段,我們主要採用的是規則+模型的方案,其中規則更勝一籌。規則主要是將新舊廣告分開,對於在歷史的日曝光量統計中出現的舊廣告,我們進行排序,然後取左右的日曝光量的中位數填充;對於沒有出現的新廣告,我們將曝光值填充0;然後全部的廣告的曝光量加上他們對應的出價除以10000,作爲測試集的日曝光量提交。初賽A榜最後的分數是86.1542分,這個時候我們模型和規則的算術平均加權的最高分是86.9811。但是模型的分數很差,只有84.9分。


模型主要就是提取廣告的基本特徵,曝光時間、廣告屬性特徵(尺寸,行業id等等)、人羣定向特徵還有廣告的動態特徵(廣告修改了多少次,修改哪些屬性)等等。模型主要還有的缺陷就是我們只考慮CPC廣告,這樣最後的數據集比較小,我記得好像只有6萬左右吧,這樣也導致模型的學習不夠。


初賽B榜的時候,我們增加了更多的特徵,尤其是增加了投放時段的細分48個特徵以及人羣定向的統計特徵以及動態特徵的countvector特徵,但是模型的分數仍然沒有長進,並且跟規則的融合也沒有讓分數更高。最後B榜我們提交的時候是完全依靠規則的,規則相對於初賽A榜,我們不再填充0,而是填充4,這樣提高了新廣告的曝光值,最後規則到了86.2633分。我們也因此成功晉級複賽。

到了複賽,整個賽題煥然一新,主要是將需要建模的廣告本身競爭力這一部分內容用廣告當天的競爭隊列信息體現了很多,因此很多隊伍到了複賽都大力挖掘競爭隊列的用法。這其中就出現了兩種不同的解題思路,第一種就是按照初賽的方法繼續做,從競爭隊列中挖掘新的特徵就可以了,第二種就是通過預測廣告的競爭力水平即total_ecpm,然後通過測試集提供的競爭隊列,將競爭力水平和隊列中的其他total_ecpm進行對比,如果勝出且沒有被後臺策略過濾的話,就曝光,然後統計曝光量就可以了。


複賽初期,我對第二種建模思路進行的嘗試,發現了以下幾個問題。第一,訓練集的數據龐大,因爲建模的是total_ecpm指標,所以每一條廣告數據都是訓練樣本,這樣連續13天的數據量累計起來共有達6億多條訓練樣本,電腦處理不了,運算速度差。第二,因爲每一條數據都可以作爲樣本,所以缺少很多數據的統計特徵,特徵數目較少。第三,利用預測出來的total_ecpm再進行排序,這是一個誤差的累計過程,這樣可能因爲累計誤差使得模型的誤差偏大。第四,也是最重要的原因,複賽開始了好幾天後,出題人突然出了一個數據說明,說對競爭隊列並不是完整的,這樣一來,最後做排序的時候就根本不知道排序的結果是否正確,比賽方過了好幾天纔出這個說明,實在是有點說不過去,耽誤了我們隊伍很多時間。

於是複賽開賽一個多星期,我們隊伍三個人才齊心合力的進行繼續對方法一進行開發。方法一的思路直接明瞭,如下圖所示,是我們的工作流程。

複賽我們也是規則+模型融合方案。但是對於複賽來說,初賽的規則得分就不高了,因爲初賽的規則只是考慮到了廣告的歷史曝光信息的中位數,對於廣告的競爭信息和動態信息考慮的少,所以複賽我們的規則就是根據歷史的廣告競爭隊列,然後計算最近的某一天的廣告的歷史競爭勝率,再乘以測試集對應廣告的競爭次數,就得到了測試集廣告的曝光次數,對於測試集的新廣告我們用歷史的廣告勝率的25%填充,最後加上bid/55000給與單調性提交。這樣A榜的時候,規則最高到了87.2636。到B榜,我們利用A榜最後得到的文件計算出了23號部分廣告的曝光量計算出了廣告的勝率,然後同樣的規則,在B榜最後規則爲85.4014分。


複賽模型方面,A榜我們採用的是時間滑窗模型,時間窗口是連續的,一共有5天,前四天是統計時間窗口,用來提取廣告的時間特徵,最後一天是預測的那一天,也被我們稱爲label天。特徵方面我們考慮的是A榜裏面的基礎特徵,以及前四天窗口當中一些統計特徵,包括歷史曝光值、pctr、total_ecpm、用戶請求數量、歷史最多請求用戶的數量、請求次數等等的最大值、最小值、中位數和平均值,以及歷史曝光數量的差值,變化量等等能統計的都被我們用來當作特徵。對於label天來說,我們選取的就是想A榜裏面的基礎特徵。總體而言,一階特徵,我們都考慮的差不多了,但是特徵組合我們就幾乎沒考慮到,而top選手則是更多的考慮到了特徵交叉組合。

03

top選手們的解決方案以及反思

導讀

作爲前20的選手,受邀到了決賽現場,有幸聆聽了top級選手的答辯,聽完之後,我感覺自己對於數據挖掘實在是理解的太過淺顯。在此我先貼出他們的解決方案並作出一定的歸納,之後有空我會詳細的根據那些開源的大佬的代碼進行進一步的解讀學習。

10


小人國蝸牛隊

3天的時間滑窗模型,當天label天,加上前天、大前天。沒有利用到23號的模型。特徵方面主要考慮1. 廣告本身特徵:得分(ecpm?)、點擊率、屏蔽率。2. 競爭特徵:得分、數目、屏蔽率等,我個人認爲應當還包含了勝率特徵。3. 用戶特徵:面向用戶的數量(具體細節沒有提出,但是這個計算量很大,運行速度不知道如何優化的)。對於歷史特徵,主要考慮單個賬戶、單個尺寸、單個商品下的一些中位數特徵。模型方面將LGB和FM有機的結合在一起,平滑了loss函數。

09


MindRank.ai隊

如圖所示,對過去3、7和10天(7天我忍住了,10天是如何搞出來的?)的數據都做特徵,類別特徵裏面的5折生成目標編碼統計特徵(不太理解)。有意思的是第9名對於舊廣告的預測結果利用規則進行的限制,限制舊廣告的預測結果在0.3倍的規則和3倍的規則之間。模型用的是nn+LGB。

08


DataAI隊

當時好像沒有拍下來,方案不全。規則方面利用了不同天數的勝率與曝光次數的算術加權求和,利用23號數據,最後規則分數爲85.68分。

07


ddw隊

利用23號數據,並且有意思的是利用了廣告的隊列信息構建了廣告的競爭力環境評價指標。舉例說明說明就是,對於每一個請求,把這個請求內所有廣告的近兩天勝率找到,取曝光率最高的前10個廣告的對數曝光率均值作爲競爭力指標來刻畫當前請求的競爭情況,之後再把每個廣告所有請求的競爭情況的分佈信息作爲特徵。

06


長河落日圓隊

通過泄露特徵找到了用戶和曝光廣告之間的粘結度,也就是廣告在什麼樣的用戶上面獲勝的概率更大。這個特徵在我們的模型中top_uid特徵考慮到了,但是這裏長河隊還不同,他考慮的更細,廣告當天重複競爭的次數,以及廣告當天平均被召回的次數等。

05


慌呀哩隊

林有夕隊有開源代碼,github上面可以查到,非常有意思的是採用了基礎標籤和相對標籤的預測思想。ppt內容很多,但是沒有具體展開細緻說明,還得結合代碼解析。


04


人工智障

特徵工程描述的比較詳細,有用戶編碼部分,對用戶屬性類特徵處理比較好,但是也沒有詳細講出來如何根據廣告的用戶屬性便利詳細的用戶id,只是給出了編碼的細節,採用很多特徵降維的方法。模型運用了的是DeepCTR+LGB。規則方面跟我們大同小異。

03


小迷弟

強哥的方案一直比較讓人迷惑,總有一種聽不懂但是又覺得很牛逼的感覺。主要是做序列特徵,矩陣壓縮成向量 RNN的模型使用,利用的是相互之間的模型  QKV三層序列網絡,定義了以天爲單位的13個模型,以7天有單位的7個模型。總之,聽完我只能鼓掌,但是一點收穫都沒有。

02


Levy隊

非常有指導意義的線下數據集的構造方案。詳細的幾何平均融合以及算術平均融合的方案比較。從我當時現場的筆記來看,第二名對於每一個細節都有一些自己的優化方案,包括特徵優化、loss修正等等,相當於是前面一些隊伍小細節優化的集成方案。

01

第一名的方案,他們做出了詳細的開源解決方案,並且給出了代碼,有興趣的大家可以自行去知乎(搜索 “魚遇雨欲語與餘”即可,菜雞的我在此對魚佬表示崇高的敬佩和感謝),我印象最深的就是從我當時的筆記來看,幾乎其他隊伍的優秀思路,第1名的隊伍都考慮到了,是top選手們的集大成方案。


我的反思:

1. 沒有構建線下驗證集,線上驗證次數過少,調試機會降低,比賽進行中就會有一種玄學調參的感覺。加上線下測試集的流程應該如下圖所示。

2. 比賽trick缺失:幾何平均與算術平均的比較不知道。

3. Loss函數理解不到位,沒有對其進行修正,好多top選手幾乎都是對0和1的target做二分類方案,對於大於1的再做迴歸預測。

4. 神經網路模型的缺失,我們本次比賽雖然也有nn模型但只是簡單的mlp模型,沒有對不同類特徵的細緻處理。導致模型融合的時候差異性不大,提分不高。

5. 特徵的交叉組合沒有考慮到,top選手中至少有3隊都是有特徵的交叉組合方案,而魚佬的隊伍做的特徵交叉則是最爲出色,不僅有nn模型中的交叉方案,LGB模型也做了相應的交叉處理。

6. 出價信息的理解程度不夠,曾一度模型的預測值要麼很大要麼很小。

04

我的新手比賽歷程

剛做完華爲軟挑比賽,我的python的語法纔算剛剛搞明白了一點吧,數據挖掘什麼的根本一點概念都沒有。所以沒有遇到現在的兩位大神隊友之前,我每一天都是瘋狂摸索的狀態。


剛公佈賽題的那幾天,我完全看不懂題目,更別說數據,太大了電腦都打不開。一個人天天看python讀數據的方法,但還是一無所獲。那個時候我就開始痛苦的思考人生,我爲什麼要對自己這麼狠,參加這種完全不懂的比賽,時時刻刻想放棄。後來激勵我繼續堅持下去的是去年18年程序媛 “燒賣”大佬分享的經驗,這裏給出文章鏈接:https://mp.weixin.qq.com/s/GK-vUiHD5TmGWh9bJxCXXA。我當時天天要放棄的時候,就唸叨文章當中的那句話,大大小小的比賽當中,都可以看到很多算法初學者最後名列前茅。就這樣,我繼續堅持下去了,事實證明最後前10名top選手中就有好多初出茅廬的新手。


——新手入題的迷茫階段

解決了迷茫時期的困惑,我一直都不知到如何上手這個題目,就這樣,我想到了去年2018年的比賽,這個時候,我就github上面找以往比賽的代碼,看看別人都是怎麼做的。就這樣,我在別人import的庫中發現了很多有用的東西,比如pandas(數據分析常用的工具庫)、sklearn(機器學習常用的工具庫)、tqdm(帶進度條的跌代工具)、gc(內存清理的工具庫)等等有意思的工具庫,還有一些模型訓練的庫比如lightGBM(樹模型),TensorFlow(nn模型)。


找到這些有利的工具之後,就是深入的去學習如何使用了。對於工具庫,我最認真學習的是pandas。至於pandas怎麼學習,晚上博客很多,書也有一部分。但我最喜歡的是直接閱讀原始的官方社區出的英文用戶手冊,pandas手冊包括其他的手冊都一樣,手冊是最直接給出接口函數如何調用的文檔,也可以最系統的讓新手入門這個庫。所以對於初學者來說,最好最直接的方法,我覺得還是讀文檔,至於你說百度、谷歌的話,那都是用來治一時病痛而已,最行之有效的還是文檔。


文檔跳躍着瞭解了庫的梗概之後,就要開始動手實踐了,不僅是文檔中的實例代碼,自己動手jupyter輸出看看,就一下都懂了。


經歷了文檔洗禮之後,我正式進入賽題,處理完數據清洗和訓練集的構建一共花了我2周的時間,經歷了這些之後,我pandas的運用速度明顯提升,文檔使用已經比較熟悉了。於是開始嘗試各種特徵構造的思路以及lightGBM訓練的方法。


結果到了初賽A榜快結束的時候,我最後規則+模型的融合分數差不多隻有84.5分左右,很難生存,本來準備A榜做的差不多,再找找隊友一起努力的,結果A榜成績太差當時有點心灰意冷。


好在我不忍心自己之前的努力都白費掉,所以我厚着臉皮對羣裏求組隊的大佬們一個一個的發出請求,實事求是的講明我的情況,經歷很多拒絕之後,我遇到了現在的兩名大神隊友。


有強隊友一起拼搏的日子,我感覺學習更快了一些,因爲直接閱讀了隊友寫的很出色的代碼和他們的特徵構造方法。除此之外,我還收穫了隊友非常出色的團隊管理技巧,學會了運用git以及在線文檔。之後的日子就都一一記錄在了github上面。


以上就是我作爲新手,經歷的我的第一次數據挖掘比賽。比賽真的很累,賽後的我全身心的投入了保養身體的日子。


簡單的總結一下,新手做數據挖掘比賽最重要的應該還是虛心學習,不要放棄


                                         ——新手上手的學習方案

歡迎加入公衆號羣聊 探討AI

AI成長社

助理AI,快樂成長

掃碼立即關注

本文分享自微信公衆號 - AI成長社(ai-growth)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章