天天看點

Kaggle Animal Shelter Outcome整個流程

本文主要對Kaggle的一個比賽項目,進行了分析說明,希望能夠查找到原因,提高資料分析的能力。

具體項目要求及資料請看[這裡]

簡而言之這是一個多分類的問題,并需要計算出屬于各個類的機率,項目評判的标準是交叉熵(Cross Entropy)最小。

1、資料的加載與清洗

由于所給資料為csv格式,而且還有header選擇使用了pandas中的read_csv函數作為加載資料的函數,具體代碼如下:

animals = pd.read_csv('D://shelter/train.csv') p_animals = pd.read_csv('D://shelter/test.csv')

觀察資料不難發現其中有不少資料缺失的情況,暫且先不考慮,提取特征的時候予以重點考慮。

2、特征提取

最開始時對這塊兒不太重視,隻想套用模型計算結果,後來發現特征提取(或稱之為特征工程)可以說是最關鍵的一步。好的特征 + 簡單的模型 >> 一般的特征 + 進階模型,這個方面會在後文詳細介紹。

  • 分析AnimalID,每一個Animal有唯一的ID,是以這一特征可以删除,不用考慮;
  • 分析Name這一列特征,可以發現有很多缺失資料,也就是說有些動物可能沒有名字,最開始的 時候我直接把這一行資料棄用了;後來發現這是一個很大的錯誤,因為有名字的動物可能以前已經被收養過,而沒有名字的動物,可能以前沒有被收養過(當然也可能存在漏統計等因素),但不管怎麼說我們從實際出發, 這個特征可能會對流浪動物的去向有影響,這點需要注意的是我們再最初篩選特征時,甯可多加特征,也不要漏加特征,也就是說,隻要我們覺得特征對預測結果有影響,我們就應該把該特征加入訓練集(即便該特征并沒有那麼重要,我們也可以在全部特征構造完成後,通過檢視特征的重要性去删除一些不必要的特征),說到這裡,我們就在訓練集加入了一列特征HasName;
  • 分析DateTime這一列特征,這列特征處理起來是比較讓我頭疼的,因為時間特征的處理可以變幻出很多的特征,很需要自己的imagination,考慮到實際情況,對于這列我的處理是把其拆成了year、month、weekday(即該天是周幾),早上(7~11點鐘),中午(11~14點鐘),下午(14~19點鐘),晚上(19~7)點鐘,總之對于時間特征的處理還有很多地方需要深入的學習。
  • 對于流浪動物去向類型,有四類, Return_to_owner(傳回主人,該種情況可能是動物丢失)、Euthanasia(安樂死)、Transfer(轉移)、Adoption(收養)這4類,而這正是需要我們想要通過測試集的特征,預測的4種情況,相當于Target。然後還有一列特征是去向的子特征,比如對于Euthanasia,可能的子類型是Suffering(遭遇痛苦),這一列我個人覺得沒有利用的價值(因為項目要求不需要預測子類型),是以沒有用。
  • AnimalType有兩種貓和狗,這列特征不用多說,處理起來很簡單。
  • 對于SexuponOutcome這一列,由于之前對流浪動物不太了解,不太重視這個特征。後來發現,是很重要的這個特征分為Neutered Male(已閹割的雄性)、Sprayed Female(不能生育的雌性)、Intact Male(未閹割的雄性)和Intact Female(能夠生育的雌性)、Unknown(未知)。比如收養的動物裡邊有很多可能是不能生育的雌性,是以這個特征對于預測來講很重要,将這列特征劃分為2個特征Sex(Male or Female or unKnown)、IsIntact(Yes or No or unknown);
  • AgeUponOutcome即出現該結果時動物的年齡,根據實際情況,人們可能更偏重于去收養一些年齡較小的動物,而一些年齡較大的動物可能會Euthanasia、一些年齡适中的動物可能會更偏向于重新傳回主人身邊。由于這些動物的年齡從days到10years不等考慮将特征用days表示;

    -Breed,我把他了解為出現結果前,流浪動物所在的流浪動物收容所或商店。這個特征對結果的影響可能在于,對于大型的流浪動物收容所,可能收養的機率會更高些;但該列特征處理起來相當麻煩,因為預測時會發現有一些流浪所或商店在訓練集中根本沒有出現過,而且流浪所或商店數目衆多,這就造成特征的次元過高或者資料分支過細,都不利于模型的訓練。最終我沒有将流浪所和商店的名字作為一個特征,而是将該流浪動物是否曾在多個流浪所或商店轉移過。構造出了IsMix這一列特征。

    -Color,即動物的顔色。雖說每個人都有自己喜歡的顔色,但畢竟有一個詞語叫大衆審美,說明我們人類對一些美醜還是有共識的通過檢視資料我們一可以發現,那些白色、黑色、灰色的動物更容易被收養

    還有就是動物是純色還是雜色的差別;由于訓練集中的顔色衆多,全部作為特征可能次元太高,我對于這些顔色的特征的處理是,選出大衆顔色即這些顔色在較多的訓練集動物中出現過,當然在測試集中我們也能發現,測試集中的有些顔色可能是訓練中所沒有的(我是沒有理睬這些顔色,1是這些顔色畢竟占少數。其次這些顔色由于訓練集中沒有出現,根本沒有合适的方法處理(至少我沒有)),是以通過這一列資料分裂了60多種顔色特征和IsMix(是否是混合色)這接近70維的特征。

4、模型的訓練

a、樸素貝葉斯

剛開始嘗試的第一個模型就是樸素貝葉斯,因為我發現特征有很多都是離散的,對于處理離散特征,樸素貝葉斯的效果還是可以的,而且算法複雜度低,程式運作時間很快。可是結果并不理想,交叉熵達到了1.8左右,這是很大的一個值。後來調整Alpha的參數效果也不理想。于是,分析了一下原因,可能是年齡這一列特征種類太多,離散程度比較小吧,是以放棄了該方法。

b、随機森林

随機森林可以處理離散和連續的特征,是以理論上來說很适合處理該資料。用了随機森林的預設參數進行嘗試,結果效果并不好。結果對相關參數進行了調整包括n_estimator (即樹的數量)、分裂特征時所考慮的最大特征數量(max_features)以及最小葉子節點的數量。利用Grid Search進行搜尋,結果發現最小葉子數量對結果的影響挺大的,預設為1,當把其調整到2時,結果出現了巨大的提升,交叉熵降為了0.83左右,是以說過拟合對結果的影響還是挺嚴重的。

c、提升樹(GBDT)

記得在某個地方看到過,說GBDT在一般情況下和RF的效果不會相差太多,但由于利用随機森林的方法,沒有什麼提升,就想嘗試了一下,GBDT在調參時和RF是十分類似的畢竟都是CART tree的組合模型,嘗過之後效果果然和RF沒有太大差別,隻稍微提升了一點點。

d、bagging(投票)

既然RF和GBDT效果相當,那麼将他們兩者的機率結果取bagging回怎麼楊呢,我也嘗試了一下,但是效果很類似。

e、其他方法

嘗試了logistics Regression、Softmax、SVM、ANN,幾乎把比較主流的多分類方法都嘗試了一遍,但效果還是不甚理想,其實後來想想葉挺然亦了解,畢竟這些方法很多都需要處理連續的特征,對于離線特征的效果自然不會好。但神經網絡除外,神經網絡的調參是比較難的,隐含層的個數的确定是一個難題、而且由于是非凸優化,存在多個極值點,是以很容易陷入局部最優解。

4、幾點感悟

a、特征工程是重中之重,還是前面提到的,特征的提取做的好的話,就相當于成功了一半,甚至還要多。但難就難在特征提取沒有統一的範式,需要自己去仔細思考,有時甚至需要自己的相關的專業知識和一些常識。可能隻有通過不斷的去總結經驗才可以吧。

b、其次,參數的調節也是很重要的,像在RF裡将最小葉子節點從1調整到2,交叉熵幾乎減小了1半。很多人可能會覺得調參無非就是交叉驗證,但我并不這麼以為,因為這裡邊可能需要你對某些算法的特性十分的了解,換句話來說,你需要知道調節哪些參數、哪些參數比較重要,這些都依賴于經驗的積累。

c、對于類似kaggle的比賽,往往需要建立離線測試,什麼是離線測試呢,就是說你要用訓練資料的一部分作為驗證集,按照項目的要求進行測試,因為好多比賽的送出次數都是有限制的,是以你需要在送出之前明白自己的算法效果有多好,進而可以更友善快捷的進行模型的修改或者調參。

繼續閱讀