1. 說明
?之前參加的都是往期賽,新人賽,這是第一人參加正式比賽,先談?wù)劯惺堋? 天池精準(zhǔn)醫(yī)療已開賽一周,排行搒上大家整體的誤差從0.9提升到0.8,也就是說一開始0.88分還名列前茅,一周之后,這個(gè)分?jǐn)?shù)早已榜上無名了。比想象中激烈,我也是反復(fù)出榜(榜單僅列出前一百名),偶爾僥幸進(jìn)入前十,時(shí)刻準(zhǔn)備著再次被踢出排行榜, 也算是體驗(yàn)了一把逆水行舟的樂趣。 很多時(shí)候反復(fù)實(shí)驗(yàn)仍然提高不了成績,感覺完全沒有方向,大家都在摸索,和一邊做一邊對照正確答案,確實(shí)不一樣。也有一些算法,我知道它,卻不知道什么時(shí)候用它。在此也記錄一下經(jīng)驗(yàn)教訓(xùn)。
2. 特征工程
?開始的時(shí)候做了一些特征工程,包括填充缺失值,為SVM計(jì)算排序特征,還找到化驗(yàn)單各項(xiàng)指標(biāo)的正常的范圍值,根據(jù)各項(xiàng)指標(biāo)正常與否做離散特征,根據(jù)指標(biāo)的合格數(shù)量計(jì)算統(tǒng)計(jì)特征等等。但相對于簡單地判斷中值,均值,效果都沒有明顯地提高。后來做了標(biāo)準(zhǔn)化,效果挺明顯的,而且轉(zhuǎn)換后缺失值就可以直接填0了。 也分析了一下,為什么正常范圍沒起到作用,化驗(yàn)之后不都是看這個(gè)嗎?后來在肉眼觀察血糖各個(gè)檔位特征統(tǒng)計(jì)值的時(shí)候,發(fā)現(xiàn)血糖高者某些生化指標(biāo)和整體均值有明顯差異,但仍在正常范圍之內(nèi),另外在不正常的情況下,差值的大小也很重要,所以這種一刀切的方法好像不行。
3. 分析結(jié)果分布
?本題預(yù)測結(jié)果是血糖值,大致分布如下:

我們把它稱為大地和星空問題,大地指的是5-6之間的區(qū)域,80%以上的血糖都分布在這個(gè)區(qū)域,此區(qū)域也是容易被預(yù)測的,而上面星星點(diǎn)點(diǎn)的是星空,雖然數(shù)量不多,卻起著決定性的作用。這還要從評分公式說起:

由公式可知,評估指標(biāo)是均方誤差MSE的二分之一,其中m是實(shí)例個(gè)數(shù),y’是預(yù)測值,y是實(shí)際值,關(guān)鍵是右上角的平方,它進(jìn)一步放大了大的誤差值。拿測試集來說,其中有1000個(gè)實(shí)例,即m=1000,如果把某個(gè)實(shí)例5.5預(yù)測成5,它對誤差的貢獻(xiàn)是(5-5.5)^2 /2000=0.000125,如果把20預(yù)測成5,誤差為(5-20)^2 /2000=0.1125,它是前者的900倍,這個(gè)距離可以在排行榜拉開好幾百名的差距了。這么看來,那些小的差異可以先不管。 再來看看訓(xùn)練集中血糖的分布:

一般把大于6.1的認(rèn)為是高血糖,大于11.1的認(rèn)為是糖尿病。在訓(xùn)練集提供的5642個(gè)實(shí)例中,大于6.1的911個(gè),大于11.1的97個(gè)。如果測試集的分布與訓(xùn)練集一致,大約有17個(gè)實(shí)例血糖在11.1以上。
?但是在討論群里面很多人對測試集的預(yù)測都沒有超過10的,按測試數(shù)據(jù)估計(jì),只占總?cè)藬?shù)1.7%的糖尿病人的誤差就占了總誤差的將近一半。
?再考慮這個(gè)題目要解決什么問題,如果根本測不出誰是糖尿病患者,只是糾結(jié)正常范圍內(nèi)的小誤差,這算法就沒意義了。
?一開始我的計(jì)算結(jié)果也是這樣的,這可能是源于大家都在使用Boost迭代改進(jìn)算法,它的原理是不斷迭代,并在每次計(jì)算時(shí)加大前一次算錯(cuò)實(shí)例的權(quán)重,可以想見,本題中80%多都是正常血糖值,于是它模型拉向了均值,大量分枝在5附近做細(xì)小切分,后來試了等深分箱,也沒什么用。 基于這個(gè)原因,我嘗試修改了算法的損失函數(shù),評價(jià)函數(shù),實(shí)例權(quán)重等等,但效果都太好,這也可能因?yàn)槲覀€(gè)人水平有限。后來直接把回歸問題改成了先分類后回歸,效果還可以。
4. 問題規(guī)模
?本題是一個(gè)小規(guī)模數(shù)據(jù)的問題,因?yàn)閿?shù)據(jù)量小,經(jīng)常引發(fā)線上與線下評分不一致,而且容易造成過擬合,以及和測試集相關(guān)的作弊問題。不過即使數(shù)據(jù)再少,也有20W+的數(shù)據(jù),人的大腦也處理不了。下面來看看不同數(shù)據(jù)量與算法選擇的關(guān)系,從另一角度分析一下星空問題的解法。假設(shè)下面三種情況:
第一種情況:從5000個(gè)實(shí)例中找到包含5個(gè)實(shí)例的類別。(血糖超20)
第二種情況:從5000個(gè)實(shí)例中找到包含100個(gè)實(shí)例的類別。(血糖超11.1,尿糖?。?br>
第三種情況:從5000個(gè)實(shí)例中找到包含1000個(gè)實(shí)例的類別。(血糖超6.1,不正常)
?第一種情況下,類中只有5個(gè)實(shí)例,實(shí)例太少,無法取均值,因?yàn)橹灰渲幸恢堤蠡蛱。紩?yán)重影響均值。此時(shí),每個(gè)實(shí)例都很重要,可以考慮使用距離類的算法,比如K近鄰。另外,可以查看這些實(shí)例中各個(gè)特征與均值的差異,從而構(gòu)建規(guī)則。
?第二種情況下,類中有100個(gè)實(shí)例,占整體的2%,這些實(shí)例之間可能有一些重合的特點(diǎn),可以統(tǒng)計(jì)的一些共同特征,一般不止一種模式,可嘗試聚類,找到一些規(guī)律。也可以用類的統(tǒng)計(jì)特征和整體的統(tǒng)計(jì)特征相比較,或者考慮貝葉斯類的算法。 ?第三種情況下,類中有1000個(gè)實(shí)例,占整體20%,這也是最常見的一種情況,它不再是從正常中找異常,而是從正常中找正常,基本屬于大地問題了,有1000個(gè)實(shí)例,量也足夠大,必然涵蓋了很多種情況,可以考慮分類樹比如GBDT類型的算法。
?以上三種情況都是從整體中選出少數(shù)實(shí)例,里面有一個(gè)隱含的特征非常重要:整體的均值,它的作用就像是人的常識一樣。
5. 算法
?選擇算法上有個(gè)誤區(qū):非此即彼。我們希望把每個(gè)實(shí)例都正確分類,但這往往是不可能的。比如在本題的情況下,可以先用GBDT的算法做一個(gè)baseline。在改進(jìn)的過程中,選擇一些規(guī)則類的算法。
?這里指的規(guī)則,比如說,我們只關(guān)心血糖高于11.1的(正例),就可以從樹分類器上切出一些只含有正例的分枝,而并不關(guān)注樹的其它部分,從而生成一套規(guī)則集。預(yù)測時(shí),符合規(guī)則的按糖尿病處理,不合規(guī)則的再用baseline預(yù)測。
6. 調(diào)參
?本題中我試用過SVM, RF, LightGbm, xgboost,評分最高的還是LightGbm和xgboost,除了速度有些差異以外,結(jié)果幾乎是一樣的,使用的是sklearn的cv調(diào)參。
?需要注意的是,有的參數(shù)還是需要具體問題具體分析,不能只依賴自動調(diào)參,比如說,像最小葉節(jié)點(diǎn)這種參數(shù),一般為避免過擬合,自動調(diào)參會建議5-6,但本問題中血糖超過20的只有4個(gè)實(shí)例,而且明顯不能歸為同一類,如果限定了最小葉節(jié)點(diǎn)為5,那這種大值就永遠(yuǎn)預(yù)測不到了。
7. 競賽方法
?一開始覺得技術(shù)圈里的交流實(shí)在是太少了,和Kaggle沒法比(雖然Kaggle中的文章和示例也主要在新手學(xué)習(xí)區(qū))。后來進(jìn)了釘釘群,發(fā)現(xiàn)還挺熱鬧的,可能因?yàn)槿豪锓答伕?,很多東西就在群里交流了,結(jié)果也沒能記錄下來。 盡管大家不會在釘釘群里詳細(xì)講算法,但有時(shí)只言片語也有很大的啟發(fā)作用,尤其是在沒有思路的情況下。另外,有的人會試一些算法,然后公開結(jié)論,這樣也能少走很多冤枉路。
?另外需要注意的是調(diào)整心態(tài),反復(fù)被踢出排行榜的心態(tài)必然不好,于是很想打回來,不斷尋找下一次提交的目標(biāo),每天提交兩次,每個(gè)計(jì)劃都是8小時(shí)以內(nèi)的,不斷尋找部局最優(yōu)解,微調(diào)再微調(diào)。但如果不在整個(gè)結(jié)構(gòu)上調(diào)整,提分會特別有限。