Python決策樹模型做 Titanic數據集預測並可視化(一)
kaggle上的Titanic數據集據說是學習機器學習必然要做的一道練習題,所以註冊了kaggle的賬號,然後下載了Titanic的訓練數據和測試數據。在註冊時注意需要科技爬梯出去才能通過郵箱驗證,不然你是註冊不了的。網址是:
Titanic: Machine Learning from Disaster一、數據導入與預處理
import pandas as pdnfrom sklearn.model_selection import cross_val_scorenfrom sklearn import treendf=pd.read_csv(D:datasetTitanic-train.csv)nprint(df.head())nprint(df.info())n
數據對應的意思分別是這樣的,除了Survived(0表示死亡,1表示倖存):
- PassengerId :乘客ID
- Pclass :乘客等級(1/2/3等艙位)
- Name : 乘客姓名
- Sex : 性別
- Age : 年齡
- SibSp : 堂兄弟/妹個數
- Parch : 父母與小孩個數
- Ticket : 船票信息
- Fare =:票價
- Cabin : 客艙
- Embarked : 登船港口
可以看到總共有891條數據,另外注意年齡和客艙數據有缺失,客艙數據缺失尤其嚴重。只有204個數據。
由於從df.head()中也可以看到客艙數據是類似於C85,C123等數據,這個數據本身對預測船上的人是否可以逃生應該是有幫助的,比如這個客艙位置是否靠近逃生通道,與撞擊冰山的位置的遠近等等,但由於沒有相關的領域知識,而且數據缺失嚴重,考慮不把這個數據作為特徵。年齡數據可以補充缺失值,一般可以用平均值來進行填充,我們先看一下有年齡數據的這些人的年齡平均值是多少。
print(df.Age.mean()) #結果顯示為29.699,我又試了下median,結果為28,相差不多,所以考慮就將平均數作為填充值。
df.Age.fillna(df.Age.mean(),inplace=True) n#data.fillna會返回新的對象,如果在原有列上把空值進行填充,需要添加參數inplace=Truen
二、特徵選擇
基本的數據處理完畢後,就進入到特徵選擇環節了,這一塊的話主要是會基於domain knowledge去選擇一些特徵,對於能否最後倖存,像姓名之類的一般無關。總體考慮下來像年齡,性別決定了個人的體力好壞,客艙級別也是一定的逃生的參考因素,以及是否有兄弟小孩也很有可能影響一個人是否能倖存,故而選取Pclass,Sex,Age,SibSp,Parch五個特徵。當然這一塊就如前所說通過領域知識和背景知識還可以創造出更多的特徵,但這裡也不是很熟練該如何創造特徵,所以就先使用這五個特徵。其中Sex給的是male和female由於是分類變數,演算法識別不了字元串,還需要處理,將其變為0,1這樣的數值,可以利用sklearn中的preprocessing
from sklearn.preprocessing import LabelEncodernle=LabelEncoder()nle.fit(df[Sex])n#用離散值轉化標籤值ndf[Sex]=le.transform(df[Sex])nprint(df.Sex)n
0 1
1 02 03 04 15 1
6 17 1....
可以看到都轉化為0和1的標籤了,其中男性是1,女性是0
三、建模預測
這五個特徵很多都是分類變數,覺得用決策樹來做可解釋性會更好,所以就用決策樹模型去做,最後產出決策樹的圖,便於使用者理解。
features=[Pclass,Sex,Age,SibSp,Parch]nX=df[features]ny=df[Survived]ndt=tree.DecisionTreeClassifier()nscore=cross_val_score(dt,X,y,cv=5,scoring=accuracy)nimport numpy as npnprint(np.mean(score))n
0.80365740391
準確度還算可以,我們將模型訓練一下後將決策樹可視化出來。
四、決策樹可視化
接下來將決策樹模型fit到原始的訓練集上,並將訓練出來的決策樹演算法給可視化出來,這樣有助於我們的理解。
dt.fit(X,y)nfrom sklearn.tree import export_graphviz #通過graphviz繪製決策樹nwith open(D:/dataset/Titanic.dot,w)as f:n f=export_graphviz(dt,feature_names=[Pclass,Sex,Age,SibSp,Parch],out_file=f)n #export_graphviz第一個參數填入決策樹的模型,feature_names填入參與的特徵名,out_file即指定輸出文件n
這時候運行完後就能產生一個.dot文件,這個我們打不開,需要去網上下載graphviz後安裝,安裝完後打開將其bin目錄添加到電腦的環境變數中,如我是放在D:Graphviz2.38bin下的
則需要將這個目錄放到環境變數中的Path下,然後點擊確定,隨後通過cmd命令進入到這個dot文件所在的目錄下後通過 dot -Tpng 文件名 -o 輸出文件名的形式進行轉化,當然也可以dot -Tpdf的形式,運行後我們就會在目錄下看到Titanic.png了
可以看到這個決策樹還是比較複雜的,如何解讀這樣一張圖呢,我放大了看一下根節點部分的決策樹:
可以看到根節點判斷的條件是sex,sex<0.5為true,則因為sex只有0和1,分別代表female和male,就是true則為女性,false為男性。這時還可以看到gini值,由於前面對決策樹分類器沒有設置任何參數,默認sklearn中的決策樹是用CART演算法。(除了CART演算法,還有ID3,和C4.5演算法),關於三種演算法的優劣如下:
基於我目前的理解,總體而言CART演算法是比較佔優的,特徵選擇上利用gini係數,而不是用信息增益,這個在計算上會有所簡化,出結果會更快。
簡單來說基尼係數代表了模型的不純度,基尼係數越小,則不純度越低,特徵越好。
最後Value中的兩個數字左邊代表在這些樣本中的死亡數,右邊的是倖存數。根據這一點結合上面的決策樹就可以看到,首先利用性別,劃分了女性314(根據Values得知其中81死,233倖存),男性577人(根據Value得知468死,109生),基本上Titanic上的男性在面對生離死別時還是很考慮到女性的~
五、預測測試集並上傳打分
kaggle上還可以下載test集,我們把train集得到的結果進行預測,然後根據kaggle的格式要求進行上傳,kaggle給了樣例的上傳要求,僅有兩列,一列為PassengerId,一列為Survived,我們也根據這樣去生成符合標準的CSV文件。
test=pd.read_csv(D:datasetTitanic-test.csv)ntest.Age.fillna(test.Age.mean(),inplace=True) nfrom sklearn.preprocessing import LabelEncodernle=LabelEncoder()nle.fit(test[Sex])n#用離散值轉化標籤值ntest[Sex]=le.transform(test[Sex])nX_test=test[features]nresult=dt.predict(X_test)ntest.insert(1,Survived,result)nfinal=test.iloc[:,0:2]nfinal.to_csv(D:/dataset/final.csv,index=False)n
這時候得到這樣兩列數據
將其上傳到kaggle,會進行評分計算,雖然在訓練集中取得80%的準確率,但上傳後顯示在測試集中正確率在70%左右,後續還需努力學習改進!但anyway也算是第一次完整做了一個kaggle案例並上傳測算。
推薦閱讀:
※數學 · 決策樹(一)· 混亂程度
※《Machine Learning:Classification》課程第4章Decision Trees: Handling Missing Data問題集
※神經網路能否代替決策樹演算法?
※機器學習演算法實踐-決策樹(Decision Tree)
※Python · 決策樹(三)· 節點