聊聊數(shù)據(jù)挖掘競賽中的套路與深度學習的局限
前言
剛好在暑假通過參加 kaggle 的 Zillow Prize 比賽來讓我在數(shù)據(jù)挖掘和機器學習中完成了菜逼到 Level 1 的轉(zhuǎn)變,借知乎的平臺總結(jié)一下比賽的經(jīng)驗,先聲明本文絕不是只列出名詞的文章,每一點背后都會有相應的文字解說,各位客官可以安心吃用和討論。
其次要強調(diào)的是這篇文章不承諾帶你上 kaggle top1%,不承諾你看完后就懂數(shù)據(jù)挖掘,就懂機器學習,這次的總結(jié)分享只針對下列有如下問題的人群。
-
網(wǎng)上其他的攻略文章看得不少,為啥自己還是一波操作猛如虎,一看比分 0-5?
-
為啥深度學習近年成績斐然,然而一些問題上了深度學習后,比分卻變成了 0-6?
這兩個問題會隨著介紹整個流程而和大家討論,所以先來對一般的流程進行總結(jié),流程無非是
-
數(shù)據(jù)預處理
-
特征工程
-
模型訓練與挑選(這里會討論深度學習可能存在的局限性)
-
模型融合
接下來我對每一個進行討論。
數(shù)據(jù)預處理
這一點我不談具體的技術,因為這些技術名詞時老生常談,什么歸一化,標準化恐怕數(shù)據(jù)挖掘的第一課就是談這些東東,這里只討論兩個問題,你知道什么時候該用什么技術手段進行預處理嗎?你知道預處理的目標是什么嗎?
按我自己的理解,數(shù)據(jù)本身決定了模型表現(xiàn)的上限,而模型和算法只是逼近這個上限,這和大部分數(shù)據(jù)挖掘教材中的 RIRO 原則是對應的,因此,對數(shù)據(jù)的預處理(和特征工程),要干的就是提高模型可逼近的上限,以及提高模型魯棒性
明白這兩個目標,在預處理階段你需要干什么就很容易反推出來了。
怎么提高模型可逼近上限?
-
提特征
-
特定領域還需要濾波和去噪
-
把干擾模型擬合的離群點扔掉
怎么提高模型的魯棒性?
-
數(shù)值型數(shù)據(jù)中的缺失值可以花式處理,默認值,平均值,中位值,線性插值
-
文本數(shù)據(jù)可以在字,詞,句等粒度不同進行處理
-
圖像數(shù)據(jù)進模型之前把圖像進行 90,180,270 等不同角度翻轉(zhuǎn)也是常見的處理方式了
總的來說,在這里就是需要在不同方面的進行數(shù)據(jù)的描述,將一份原始數(shù)據(jù)稍作擴展。
特征工程
特征工程應包括兩部分特征抽取和特征挑選,特征挑選的資料網(wǎng)上一搜一大堆,因此這里只討論特征抽取,為什么?因為巧婦難為無米之炊啊,沒有特征你挑選個寶寶嗎?
-
第一個方法叫做按業(yè)務常識抽取。
簡單點來說,就是通過對你需要分類 / 預測等領域的先驗知識來進行抽取,比方說,要區(qū)分男生和女生,直接使用性特征肯定要比其他的身高體重這些數(shù)據(jù)的準確率要高。當然,考慮到每一個人都不可能所有知識都精通,當面對一個陌生的業(yè)務領域時,建議優(yōu)先提取 X1/X2 這樣形式的特征(這里的 X1,X2 不一定是一個變量,也可能使一個式子),因為傳統(tǒng)的統(tǒng)計流派特別喜歡通過 X1/X2 組成一個叫做 *** 率這樣的指標,有時可能有奇效。
-
第二個方法叫做抽取非線性特征。
線性模型具有簡單,快速等優(yōu)勢,但它的劣勢也很明顯,他只能表達線性關系,而一般現(xiàn)實問題那有這么簡單的線性關系。因此,解決方案就是線性模型使用非線性特征。
可能有些同學有有點懵逼,什么叫線性模型搭配非線性特征?看完這個下面這個例子就清楚了:
假設一個回歸預測的問題,求的 y=f(x),那么有如下兩種形式的表達
…… (1)
……(2)
(1) 式是線性回歸,只能表達線性關系,(2) 式是多項式回歸,能夠表達非線性關系。這時我們令:
,
,
,
,
這時再回首去看 (2) 式,就能得到
…… (3)
有些童鞋應該反應過來了,是的,所謂的線性模型使用非線性特征的原理就是將非線性特征記作新的變量 t,然后扔進一個線性模型里面,這時得到的就是關于 t 的線性模型,但卻可以表達 x 的非線性關系。
至于提取非線性特征,除了人工提取這種多項式來做特征外,也可用深度學習,SVM 等非線性模型的中間輸出來作為非線性特征。這些非線性模型的方法,也大概是把低維度投影到高維度后塞進線性模型,至于說為什么要用非線性模型提取,一是因為省人力,二是因為模型往往能學習到人類常識上意識不到的特征的,至于為什么不適用非線性模型直接進去端對端的工作方式,則是因為每一個非線性模型提取非線性特征的方法都不一樣,那么提取出來的非線性特征自然也就不一樣了。
但要注意一點的是,是否使用模型來提取非線性特征這個決定要考慮實際情況,因為多個模型的非線性特征組合后,或者是模型融合技術,計算量或時延是不可接受的,有些方法連工程實踐上都不一定可?。词褂蟹植际接嬎愕沫h(huán)境),就更不要說打 kaggle 的大部分都是個人用戶,只有臺式機或筆記本。
模型訓練和選擇
合理的劃分數(shù)據(jù)集和訓練集,平衡樣本,交叉驗證這些東西是老生常談,網(wǎng)上一找一大堆,所以本文繼續(xù)不談。
先說說的是模型的選擇,機器學習經(jīng)常被稱為玄學,剛開始我以為說的是因為調(diào)包俠本根本不知道里面算法的原理,所以這樣造成,但后來我發(fā)現(xiàn),即使你知道里面的算法的原理,也依然是玄學。
為什么這么說,我們對比一下其他的一些類型的程序出錯是怎么解決的?print 大法?二分排查找 bug?無論是何種方法,只要 bug 可重新,你總是可以通過程序的表現(xiàn)而定位到錯誤,但機器學習不行,除了模型是否過擬合可以通過一些指標看出,然后調(diào)整對應得參數(shù)外,其他的一些問題,壓根無法通過現(xiàn)象而定位到需要修改的錯誤。
比如說,預測效果不好,我知道肯定是需要增加特征,但需要增加一個哪些方面的特征?這個特征是需要引入新的數(shù)據(jù)維度,還可以從現(xiàn)有的數(shù)據(jù)提取出來?或者說當前的數(shù)據(jù)的價值已經(jīng)被我榨干了嗎?又或者說,你通過算特征與預測值的相關系數(shù),相關系數(shù)低的特征就一定沒用了嗎?顯然不是,因為你現(xiàn)在只是算了單變量的,沒有算排列組合的結(jié)果,而至于算排列組合的結(jié)果,真的能算嗎?…… 諸如此類的是沒有 100% 準確的指導方案的(可能連 90% 準確的指導方案都沒)。
當然,解決方法還是有的,就是不斷的堆特征,和堆模型,挑選后來一波融合,指望不同的模型能學到不同的方面,然后互相互補。
落實到行動,就是那句老話,大膽假設,小心求證。
說了這么多,無非說明機器學習模型可能是理論科學,但實踐,一定是實驗性科學,既然是實現(xiàn)性科學,就要遵守一個原則,先簡單后復雜,過早優(yōu)化是萬惡之源,無腦優(yōu)化則是浪費時間。簡單是指模型的簡單,數(shù)值類型可以先從簡單的線性回歸開始,(若是圖片領域的話,可以選取一些比較基本的 DL 模型,比如預訓練好的 vgg 系列),這樣出結(jié)果的速度肯定優(yōu)于其他亂七八糟的復雜模型,出結(jié)果快,意味著你可以趁早在線下確定較為妥當?shù)臏y試方式,你的 baseline,快速驗證你的其他思路,然后再慢慢優(yōu)化和調(diào)參。
在這個小節(jié)最后,來說說這次比賽中關于使用深度學習的感想。
目前公認不適合使用深度學習的情況是當數(shù)據(jù)量偏少,但一般現(xiàn)在比賽方提供的數(shù)據(jù)量都非常可觀,所以數(shù)據(jù)量這個條件應該說是可以滿足的。
其次的一個公認不適合的地方是,數(shù)據(jù)不具有局部相關特性。意思就是像圖像 / 自然語言等領域,數(shù)據(jù)之間具有局部相關性,比如說一個像素不能表達足夠的信息,但一堆像素就能表示這是小狗還是小貓,語言中由單詞組成句子,而一旦這些東西組合的次序被打亂,那么整體所表達的信息亦同時被打亂。這些具有局部相關特性的數(shù)據(jù),可以通過一定的網(wǎng)絡拓撲提取其中的局部相關特性,同時配合深度達到層次特征的提取,從而達到較為優(yōu)秀的成果。對比三層 MLP 以及 CNN 在 minst 手寫數(shù)字識別上的效果差異,就能充分說明這個觀點。而對于不具有局部相關特性的數(shù)據(jù),沒法用特點的網(wǎng)絡拓撲來捕捉了他的信息,在深度學習中就只能用 MLP 來完成模型的訓練,而 MLP 的效果,一般要弱于 GDBT,RandomForest 等傳統(tǒng)模型。
深度學習對比傳統(tǒng)方法來說,最大的優(yōu)勢是自動特征的提取,但根據(jù)其他大牛分享的經(jīng)驗來說,當人工特征工程做到一定程度后,傳統(tǒng)模型是可以超越深度學習的,詳見 quora 相似文本匹配的比賽里面,yesofcourse 隊伍的視頻,里面有一段是關于深度學習和傳統(tǒng)機器學習模型的對比,另外亦有有人指出深度學習在面對 x 和 y 的關系是一次推理的情況時,深度學習能學到很好,如果是兩層或多層的推理的時候,相比傳統(tǒng)模型,深度學習卻完全處于劣勢,但深度學習結(jié)合知識圖譜可以有效的解決這個問題。
(個人猜想,這里大牛說到的推理應該是指在邏輯上的關系,比如你爸爸的媽媽的二叔的老婆的姐姐你應該稱呼她什么這種推理,而并非數(shù)學上 y=f(x) 這種關系)
而在這次比賽中的實際情況則比較有趣。在對數(shù)據(jù)集進行了基本處理后 (對缺失值填充,去除離群點),沒有做任何的特征提取,分別塞進 xgboost 和 3 層 128 單元的 MLP,其中 LB 和線下的表現(xiàn),兩個模型的結(jié)果非常接近,差別基本上是小數(shù)點后 6 到 7 位。但是后來我人工提取了幾個特征,這時兩個模型的差異就開始顯露出來了。線下差別不大,但 LB 上,xgboost 讓我的排名又十分可觀的上升,但 MLP 則讓我的 LB 得分有了十分可觀的…… 下降!起初覺得是產(chǎn)生了過擬合,后來分別加入了 dropout 和正則項嘗試,并沒有改善,也嘗試了使用 autoencoder 進行特征提取,然后應用到傳統(tǒng)模型上,效果都不盡人意,最后我決定不使用 DL 那套方法,改而采用傳統(tǒng)的機器學習模型 + 人工抽取特征。但在決定放棄 DL 之前,已經(jīng)浪費了太多的時間在嘗試上(因為對 DL 有盲目的信心,總覺得成績不好是自己的參數(shù)問題),沒有銀彈,具體情況具體分析,這也是以后處事應該要注意的地方。
其實通過分析我發(fā)現(xiàn) DL 產(chǎn)生較為嚴重的誤差原因大概是,lable 其實正負數(shù)對半,但模型的輸出幾乎都是正,即使是負數(shù),該預測值的數(shù)值也非常少,并沒有找到合適的解決方法。
但無論是 xgboost 還是線性回歸,其預測值都可以做到正負各占 50%,因此,目前的方案是對這兩個模型最后的結(jié)果取了加權(quán)平均,目前(2017.7.22)排名到達 342/1702,按照套路,接下來應該有一波模型融合,我是有自信再上升一定的名次的,但因為我還有參加今年的考研,另外這次比賽經(jīng)歷我覺得已經(jīng)有足夠的長進,便沒有繼續(xù)下去的打算,即使是繼續(xù)也是考研后的事了。
模型融合
關于模型融合,方法依舊在網(wǎng)上有一大堆,近幾年也沒有太大的創(chuàng)新,主要說一下的就是模型融合前應該畫一畫誤差曲線,確定模型之間是否有融合的需要,比如一個模型完爆另外一個模型,那融合價值就很低。
后話
讀萬卷書不如行萬里路;行萬里路不如閱人無數(shù);閱人無數(shù)不如高人指路。參與到面向全社會的比賽,其實比參加學校某些我不想提名字的比賽更有意義,雖然拿獎很難,但因為能接觸到的是近似真實的流程,不同水平,不同行業(yè)背景的人,尤其是認識一個的朋友后會以認識更多牛逼的朋友,這些機會對一個人的知識技能和人脈積累都有巨大的好處,如果你還處于學生時代,這個機會的潛在價值會翻倍。
最后,因為這個比賽還在進行中,所以代碼我不會給,但你真想要當伸手黨,去 kaggle 的 kernels 上有很多排名比我高的放在了上面,如果只是問題探討,歡迎在評論區(qū)或私信留言,文字應該足夠了。
最后的最后,因為我不知道國內(nèi)除了 top 的一些學校外,其余學校關于機器學習或深度學習方向的研究水平怎么樣 (子方向不太在意),廣東地區(qū)的考生,歡迎熱心的知友推薦學校和實驗室
,在這里先謝謝了,我保證看在推薦的份上不吃你。:P