機器學習之泰坦尼克號生存預測

本文主要通過提取船員特徵,通過邏輯回歸演算法,訓練模型,並對一些測試樣本的生存情況進行預測,然後將預測結果上傳到kaggle網站,進行系統評分。

行文按照提出問題,分析數據,清洗數據,構建模型,模型評估,方案實施這六個步驟來逐漸推進。這六個步驟,構成機器學習,對泰坦尼克號上乘客生成情況的預測。

提出問題

船上總共有1309名乘客,由於船上的救生艇很少,只有一部分乘客可以生還。需要通過一些數據特徵,如性別,年齡,社會階層,家庭大小等來判斷乘客是否可以生還。

分析數據

先從表格中導入數據。

import numpy as npimport pandas as pdtrain = pd.read_csv("./train.csv")test = pd.read_csv("./test.csv")print(訓練數據集:,train.shape,測試數據集:,test.shape)

train為訓練測數據,test為測試數據。訓練數據用來確定模型的,模型的準確程度,是由從數據中提取的特徵決定的。而測試數據,用來對最終測試結果的檢驗,這個判斷結果需要通過上傳到網站上,由網站最終評分。

先將導入的數據合併,並顯示出來。需要了解數據有哪些特徵,好做下一步處理。

full = train.append(test,ignore_index = True)full.head()

為了便於後續綜合處理,講訓練數據和測試數據合併在一起,存放在名為full的DataFrame中,並顯示前5個數據。

數據特徵顯示

對數據特徵的含義進行逐一說明

基於基本的人類倫理邏輯,可以從變數的特徵判斷和能否生存。如果年齡偏小或年齡偏大,很大概率能生存。女性的生產概率比男性的大。有子女的比沒有子女,生存概率要低。

數據清洗

由於有些數據確實,現實格式不對,不方面演算法進行處理,需要進行數據處理,變成計算機能夠處理的樣式。

原始三種數據,有三種類型

數值類型,可以直接用。時間類型,需要轉換成年月日。分類數據,用數字代替類別的one-hot編碼。

首先處理矩陣為空的數據。

full.info()函數用來檢查數據的情況,發現age,cabin,fare列都有空的數據。需要將空的數據填充處理。

這裡對年齡和船票為空的數據進行處理。

full[Age]=full[Age].fillna(full[Age].mean())full[Fare]=full[Fare].fillna(full[Fare].mean())

缺失的年齡數據,所有乘客的年齡的平均值來替換,票價也是一樣。

對登港口的數據進行處理,缺失值,默認是登港口是南安普頓。船艙號,為空的數據,用字元『U』來提替換。

full[Embarked]=full[Embarked].fillna(S)full[Cabin]=full[Cabin].fillna(U)

對於性別是用「Female」,「Male」這些字元串來表示,而字元串不是數字,這些關鍵信息不能用來計算,因此需要用數字來表示。

定義一個字典,用map函數實現矩陣的『Sex』列字元串和數字的影射。如下:

sex_mapDict = {male:1,female:0}full[Sex] = full[Sex].map(sex_mapDict)

對於登港口,船艙等級,頭銜,這些都是字元串,也需要轉換成可以計算的數字。為了方面,需要採用獨熱編碼方法對這些信息進行區分和識別。

這裡以頭銜進行說明,需要提取每個人頭銜的信息,並根據頭銜信息進行分類,包括先生,小姐,夫人,官員,皇室人員五類。

實現的代碼如下:

定義函數:從姓名中獲取頭銜def getTitle(name): str1 = name.split(,)[1] # split函數將字元串通過『,』,分成前後兩個字元串,按照規則,去逗號後面的字元串 str2 = str1.split(.)[0] # 取句號前面的字元串 str3 = str2.strip() #strip()方法用於移除字元串頭尾的指定的字元,默認為空格 return str3titleDf = pd.DataFrame()titleDf[Title]=full[Name].map(getTitle)title_mapDict ={ "Capt": "Officer", "Col" : "Officer", "Major": "Officer", "Jonkheer": "Royalty", "Don": "Royalty", "Sir": "Royalty", "Dr": "Officer", "Rev": "Officer", "the Countess":"Royalty", "Dona": "Royalty", "Mme": "Mrs", "Mlle": "Miss", "Ms": "Mrs", "Mr": "Mr", "Mrs": "Mrs", "Miss": "Miss", "Master": "Master", "Lady": "Royalty"}titleDf[Title]=titleDf[Title].map(title_mapDict)titleDf=pd.get_dummies(titleDf[Title])

顯示的效果如下圖所示:

家庭,登港口,船艙等級都用獨熱辦法進行編碼,編碼完成後,就是完成數據清洗工作。

構建模型

可以發現影響乘客生還因素很多,需要先求解相關係數,然後選取對生產率相關係數大的變數來構建模型。算出相關係數如下:

可以看出,已婚的女士生存率比較高,而結婚的男性生存率比較低,同時高等級船艙的乘客生存率比低等船艙的乘客生存率高。需要選取一些重點特徵,來進行邏輯回歸。

由於原始數據中,後面一部分是用來測試數據,因此在訓練之前需要分開。之前放在一起,是好批量處理。程序如下

#選取重要特徵的變數構成新的矩陣full_X = pd.concat([titleDf,pclassDf,familyDf,full[Fare],cabinDf,embarkedDf,full[Sex]],axis=1)sourceRow = train.shape[0] #獲取原始數據的行數source_X = full_X.loc[0:sourceRow-1,:] #構建訓練數據特徵矩陣source_y = full.loc[0:sourceRow-1,Survived]#構建訓練數據標籤矩陣pred_X = full_X.loc[sourceRow:,:] #構建測試數據特徵矩陣

邏輯回歸有現成的演算法,我們只要按照規則調用就好了。scikit-learn裡面提供了大量的機器學習演算法。前期我們先關注怎麼使用,等掌握了基本流程之後,才反過來仔細研究演算法。

調用如下:

#調用訓練數據和測試數據分開函數,這個是隨機劃分的,劃分比例是0.8from sklearn.cross_validation import train_test_splitrain_X,test_X,train_y,test_y = train_test_split(source_X,source_y,train_size = 0.8)#調用機器學習中邏輯回歸演算法from sklearn.linear_model import LogisticRegressionmodel = LogisticRegression()model.fit(train_X,train_y)

模型評估

模型評估重要是對訓練模型進行測試,檢測其測試準確率。可以通過score評分來最終測試模型的準確度。這裡可以直接調用score函數

model.score(test_X,test_y)0.8547486033519553

可以看出來,這個評估模型預測準確度為85.47%。

方案實施

主要是對測試數據集的數據進行預測,並將預測的結果上傳到kaggle網站,通過網站最終排名,來檢驗預測的結果。

pred_Y = model.predict(pred_X)

講預測數據集的特徵數據輸入到訓練好的模型中,調用預測函數,對乘客的生存情況進行預測。

passenger_id = full.loc[sourceRow:,PassengerId]predDf = pd.DataFrame( { PassengerId:passenger_id, Survived:pred_Y })predDf.to_csv(titanic_pred.csv,index=False)

構建一個DataFrame,只存儲乘客的身份以及對應生存情況預測數據,並把它保存在一個名為titanic_pred.csv的文件中。

將訓練好的數據上傳到kaggle網站,網站會根據預測結果,對我進行排名。

在網站排名如下

排名很低,而且評分是0.76555分。離1分差距還很遠,還有優化空間。

總結

這次通過一個實例進行操作,把機器學習的過程走了一遍,對其中的每一個步驟能夠理解。而在最後,是講評分的結果,通過上傳到kaggle網站,對預測結果進行評分。通過目前評分來看,這個還有很大的優化空間。後續需要繼續挖掘更多特徵變數,同時優化機器學習模型,讓評分更加準確。


推薦閱讀:

機器學習預測地震,信得過嗎?
第三章 線性模型
機器學習演算法簡介
課程安利:用物理學的眼光看機器學習--Deep Learning and Quantum Many-BodyComputation
機器學習筆記003 | 梯度下降演算法

TAG:人工智慧 | 機器學習 | 邏輯回歸 |