天池數據挖掘競賽是國內數據挖掘圈是很正規,規模很大,組織很好的競賽平臺。作為在讀的一名數據挖掘小白,懷著當炮灰的念頭,毅然決然的參加了這次競賽。
賽題在這里就不詳細描述,有興趣的朋友可以去天池搜索,商鋪定位比賽。主要是告訴你用戶去逛商場的時候,手機會搜到wifi熱點,通過給你wifi列表,用戶交易時經緯度,交易時間,店鋪經緯度,店鋪類型,店鋪價格和商場名稱等信息,讓你去預測該用戶再次發生交易時,位于哪家店鋪。訓練集給出了2017年8月一整月的數據,讓你去預測2017年9月前兩周的商鋪定位情況。
數據挖掘競賽有一個基本的流程,首先對問題進行分析,然后進行數據預處理,然后繼續進行傳說中最厲害的特征工程,最后利用模型去對目標問題進行分析預測,得到結果。有些朋友的博客也分析的比較清楚,這里就不贅述了。在這里主要給出題目的分析思路和自己操作的結果
在比賽的開始階段,可以很明顯的想到wifi是能夠確定店鋪的關鍵因素。后續的事實也證明了wifi的重要性。起初我們在做規則學習,利用wifi的強度構造了wifi距離,也就是在訓練集中,對每一個樣本的wifi序列出現的強度值求均值,然后利用測試樣本中每一個樣本的wifi序列和訓練樣本中wifi序列中的交集部分求歐式距離,最終取距離最近的店鋪作為預測結果。起初這樣做,效果很差,正確率只有0.16。
后來發現會出現有兩個訓練樣本和一個測試樣本算距離,一個交集個數為4,一個交集個數為3,但是按照交集個數的算了相應wifi的距離后是4(假設每個wifi距離為1)和3,我們的思路會將測試樣本的答案分配給交集個數為3的店鋪,但這與實際不相符合,一般來說交集個數大,他離這家店鋪也就會比較近,因此我們在算完距離以后,將算出來的距離除了一個交集個數的平方,從而放大交集個數對結果的影響,經過這樣的改動,我們的成績提升到了0.8589,還是有質的提升。
最后我們發現在wifi中有很多公共wifi,還有手機熱點等,我們對求距離的條件進行了強化,對交集部分的個數大于5個的再來求距離,如果交集個數不大于5,就對其距離設為無窮大。這樣大大提升了預測的準確程度,預測分數也上升到了0.8893。這里尤其感謝新神,他是為這套方案創造了一套公式,方便編程實現和調參。下次給出。
這里再給出wifi相關思路。
1. 每一個wfi序列可以看成是wifi序列,我們可以從LCS的角度去考慮每家店鋪對應的wifi和測試樣本中擁有長度最大的最長公共子序列,因為這里既包含了最長公共子序列的長度的影響又包含了wifi的出現的順序信息。
2. 將每家店鋪對應的wifi序列當成是自然語言處理中一句話,然后利用諸如word2vec,gensim等對其進行訓練,挖掘每段wifi語言的相似性,然后從中找相似性最大的店鋪作為結果。
3. wifi出現在每家店鋪的順序不同,利用wifi出現的順序對wifi進行編碼。
后來做規則,實在是做不太動了,然后剛好群里面的麥芽大神開源了一份代碼。僅僅73行,但是能夠有高達0.9073的成績,實在讓人有點心動。然后就下載后進行了學習。
麥芽大神的開源思路其實比較簡單,就是將wifi出現次數比較少的wifi刪去,然后按照商場,將每一家商場下所有的wifi做onehot,在里面是1的位置填充強度值,將其作為特征,再加上交易時的經緯度,利用xgboost做多分類,就可以達到0.9073的分數。實在是羨慕,大神思路明了,代碼簡潔。然后在仔細看了代碼之后,居然發現大神不小心把rowid加入訓練和預測,我從中摘出來之后,居然又上升了萬分之5,哈哈還是挺開心的。
最后自己對代碼進行修改,想著加入特征。但分析數據后,因為測試集中沒有店鋪相關的信息,我沒有辦法將店鋪相關的特征加入進來,只能挖時間維度了。我通過tableau畫出了平日和周末的流量圖,發現兩者有著明顯的不同,因此我們將是否是工作日作為一列特征加入其中,通過多分類的訓練,居然上升了萬分之十六,還是比較開心。然后自己又重新審視數據,發現8月份有一個比較特殊的節日,那就是七夕節,我就將其加入周末中,成績又上升了萬分之一。之后我們通過觀察數據發現,發現用戶去店鋪的時間基本是有大概的規律,有的用戶只是早上而且是同一家,有的是很多家,因此我們將所有店鋪的記錄發生的時間統一到小時的角度,作為特征加入模型,又上升了萬分之四,最終成績終于有了較大的提升,最終由于自己思路的限制,止步復賽。但是感覺第一次參加這種比賽能夠從2897支隊伍中做到前200還是比較開心的,希望天池越來越好,希望自己下次能夠有好成績。這里也感謝隊友新神和林神,很強勢。
最后總結一下在比賽中自己的一些收獲和經驗教訓:
1. pandas在數據分析方面真的是利器,無與倫比。但是循環真的比較慢。而且在循環嵌套的過程中不要在循環中出現深拷貝,對時間上的損耗十分大。比賽之初的代碼居然可以跑三天。。。。。最終實在是等不起了,然后將所有的數據格式更改為dict,然后對其遍歷,30分鐘就可以搞定。
2. pkl文件序列化到硬盤,沒有壓縮參數,導致文件體積很大。
3. 在以后做比賽還是做開發的時候,需要統一py的版本,因為py改動激進,在字符編碼方面和py2完全不一樣,在這個問題上浪費了很多時間
4. 在碰到數據量大的情況,利用分而治之的思想比較重要,在這個題目中數據量比較大,因此我們分商場對其進行處理。劃分成子問題,這樣效果會好的多,并且執行速度上也會快的多。而且對有些變量的onehot也就變成了可能。
5. 碰到類別變量或者字符串變量,可以對類別等進行統計分組,或者找出類別之間的關系和特征,最后考慮onehot,或者利用自然語言處理中的詞向量的思想
6. 在分析真實數據的時候,是否是工作日,節假日等十分重要,這種特殊的時間段,往往會表現出不一樣的分布,分開處理,往往效果會好的多。
7. 時間維度刻畫特征,分段離散化,找起點形成時間距離。
8. 異常數據需要做剔除,會使得預測準確率變高。
9. xgboost調參,特征重要性畫法都比較重要