Kaggle入門之泰坦尼克號生存率預測

1.項目概況

1.1項目背景

泰坦尼克號沉船時間是世界上最著名的海難事件,2224名船員及乘客中,1517人喪生。這個項目是利用根據已知數據構建模型,來測試其他乘客的生存率。

1.2初識kaggle

kaggle是一個數據科學學習的網站,泰坦尼克號生存率預測正是kaggle的入門案例。首先註冊kaggle帳號,然後登錄下載需要的數據:

在頁面下方網站提供了數據中變數的解釋:

2.理解數據

2.1導入數據

首先導入包

import warningswarnings.filterwarnings(ignore)#導入處理數據包import numpy as npimport pandas as pd

r是保持字元串原始值的意思#train = pd.read_csv("./train.csv")train = pd.read_csv(r"c:eamon rain.csv")#test = pd.read_csv("./test.csv")test = pd.read_csv(r"c:eamon est.csv")print(訓練數據集:,train.shape,測試數據集:,test.shape)

訓練數據集: (891, 12) 測試數據集: (418, 11)

訓練數據集比測試數據集多一列,是生存率,我們的目的是用訓練數據構建模型,來預測測試數據集中的生存率

rowNum_train=train.shape[0]rowNum_test=test.shape[0]print(kaggle訓練數據集有多少行數據:,rowNum_train, ,kaggle測試數據集有多少行數據:,rowNum_test,)

kaggle訓練數據集有多少行數據: 891 ,kaggle測試數據集有多少行數據: 418

為了方便同時對訓練數據和測試數據進行清洗,將兩個數據集合併。

full = train.append( test , ignore_index = True )print (合併後的數據集:,full.shape)

合併後的數據集: (1309, 12)

2.2查看數據集信息

查看前五行

full.head()

使用describe查看數據類型的描述統計信息.

full.describe()

使用info統計數據類型和數量

我們發現數據總共有1309行。

其中數據類型列:年齡(Age)、船艙號(Cabin)裡面有缺失數據:

1)年齡(Age)裡面數據總數是1046條,缺失了1309-1046=263,缺失率263/1309=20%

2)船票價格(Fare)裡面數據總數是1308條,缺失了1條數據

字元串列:

1)登船港口(Embarked)裡面數據總數是1307,只缺失了2條數據,缺失比較少

2)船艙號(Cabin)裡面數據總數是295,缺失了1309-295=1014,缺失率=1014/1309=77.5%,缺失比較大

這為我們下一步數據清洗指明了方向,只有知道哪些數據缺失數據,我們才能有針對性的處理。

3.數據預處理

3.1缺失值處理

對於數據值,處理缺失值最簡單的方法就是用平均數來填充缺失值。

print(處理前:)full.info()#年齡(Age)full[Age]=full[Age].fillna( full[Age].mean() )#船票價格(Fare)full[Fare] = full[Fare].fillna( full[Fare].mean() )print(處理紅後:)full.info()

full[Embarked].head()

登船港口裡面數據總數是1307,只缺失了2條數據,缺失比較少,我們將缺失值填充為最頻繁出現的值:S=英國南安普頓Southampton

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

full[Cabin].head()

缺失數據比較多,船艙號(Cabin)缺失值填充為U,表示未知(Uknow)

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

查看最終缺失值處理情況

full.info()

3.2特徵工程

特徵工程就是最大限度的從原始數據中提取特徵,以供機器學習演算法和模型使用。

如下圖所示,數據可以分為三種類型:

本案例的變數分為下面三大類,每類有不同的處理方法。

3.2.1分類數據:有直接類別的

1)乘客性別 2)登船港口 3)客艙等級

性別

full[Sex].head()

sex_mapDict={male:1, female:0}#map函數:對Series每個數據應用自定義的函數計算full[Sex]=full[Sex].map(sex_mapDict)full.head()

登船港口

登船港口(Embarked)的值是:出發地點:S=英國南安普頓Southampton途徑地點1:C=法國 瑟堡市Cherbourg途徑地點2:Q=愛爾蘭 昆士敦Queenstownfull[Embarked].head()

使用One-hot編碼對超過兩個的類別進行編碼,使用pandas中的get_dummies( )可以實現One-hot編碼。

embarkedDf = pd.DataFrame()embarkedDf = pd.get_dummies( full[Embarked] , prefix=Embarked )embarkedDf.head()

利用concat把合併到full裡面, axis=0代表往跨行(down),而axis=1代表跨列(across),inplace=True:不創建新的對象,直接對原始對象進行修改;再用drop把登船港口(Emabarked)刪掉。

#添加one-hot編碼產生的虛擬變數(dummy variables)到泰坦尼克號數據集fullfull = pd.concat([full,embarkedDf],axis=1)因為已經使用登船港口(Embarked)進行了one-hot編碼產生了它的虛擬變數(dummy variables)所以這裡把登船港口(Embarked)刪掉full.drop(Embarked,axis=1,inplace=True)full.head()

客艙等級

以此類推,把客艙等級進行one—hot編碼

#存放提取後的特徵pclassDf = pd.DataFrame()#使用get_dummies進行one-hot編碼,列名前綴是PclasspclassDf = pd.get_dummies( full[Pclass] , prefix=Pclass )pclassDf.head()

新序列合併到full後面,刪除多餘列。

#添加one-hot編碼產生的虛擬變數(dummy variables)到泰坦尼克號數據集fullfull = pd.concat([full,pclassDf],axis=1)#刪掉客艙等級(Pclass)這一列full.drop(Pclass,axis=1,inplace=True)full.head()

3.2.2分類數據:字元串

字元串類型:可能從這裡面提取出特徵來,也歸到分類數據中,這裡數據有:

  1. 乘客姓名(Name)
  2. 客艙號(Cabin)
  3. 船票編號(Ticket)

從名字里提取頭銜,先查看姓名前五列

full[ Name ].head()

定義一個獲取頭銜的函數:

def getTitle(name) str1=name.split(,)[1] str2=name.split(,)[0] str3=str2.strip() return str3

titleDf=pd.DataFrame()titleDf[Title]=full[Name].map(getTitle)titleDf.head()

定義幾種頭銜的映射

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)#使用get_dummies進行one-hot編碼titleDf = pd.get_dummies(titleDf[Title])titleDf.head()

full = pd.concat([full,titleDf],axis=1)#刪掉姓名這一列full.drop(Name,axis=1,inplace=True)

從客艙號中提取客艙類別

full[Cabin].head()

使用lambda創建匿名函數,提取客艙號的首字母

canbinDf = pd.DataFramefull[Cabin]=full[Cabin].map(lambda c : c[0])cabinDf = pd.get_dummies(full[Cabin],prefix=Cabin)cabinDf.head()

把新產生的虛擬變數添加到數據集full中

full = pd.concat([full,cabinDf],axis=1)full.drop(Cabin,axis=1,inplace=True)

建立家庭人數和 家庭類別

familyDf = pd.DataFramefamilyDf[FamilySize] = full[Parch]+full[SibSp]+1familyDf[Family_Single] = familyDf[FamilySize].map(lambda s : 1 if s==1 else 0)familyDf[Family_Small] = familyDf[FamilySize].map(lambda s : 1 if 2<=s<=4 else 0)familyDf[Family_Large] = familyDf[FamilySize].map(lambda s : 1 if 5<=s else 0)familyDf.head()

full = full.concat([full,familyDf],axis=1)full.shape

(1309, 33)

3.3特徵選擇

corrDf = full.corr() corrDf

查看各個特徵與生成情況(Survived)的相關係數,ascending=False表示按降序排列

corrDf[Survived].sort_values(ascending =False)

根據相關係數大小,我們選擇了這幾個特徵作為模型的輸入:頭銜(前面所在的數據集titleDf)、客艙等級(pclassDf)、家庭大小(familyDf)、船票價格(Fare)、船艙號(cabinDf)、登船港口(embarkedDf)、性別(Sex)

full_X = pd.concat( [titleDf,#頭銜 pclassDf,#客艙等級 familyDf,#家庭大小 full[Fare],#船票價格 cabinDf,#船艙號 embarkedDf,#登船港口 full[Sex]#性別 ] , axis=1 )full_X.head()

4.構建模型

4.1建立訓練數據集和測試數據集

#原始數據集有891行sourceRow=891sourceRow是我們在最開始合併數據前知道的,原始數據集有總共有891條數據從特徵集合full_X中提取原始數據集提取前891行數據時,我們要減去1,因為行號是從0開始的。#原始數據集:特徵source_X = full_X.loc[0:sourceRow-1,:]#原始數據集:標籤source_y = full.loc[0:sourceRow-1,Survived] #預測數據集:特徵pred_X = full_X.loc[sourceRow:,:]

從原始數據集(source)中拆分出訓練數據集(用於模型訓練train),測試數據集(用於模型評估test)

from sklearn.cross_validation import train_test_split #建立模型用的訓練數據集和測試數據集train_X, test_X, train_y, test_y = train_test_split(source_X , source_y, train_size=.8)#輸出數據集大小print (原始數據集特徵:,source_X.shape, 訓練數據集特徵:,train_X.shape , 測試數據集特徵:,test_X.shape)print (原始數據集標籤:,source_y.shape, 訓練數據集標籤:,train_y.shape , 測試數據集標籤:,test_y.shape)

4.2選擇機器學習演算法

這裡選用linear model的邏輯回歸演算法建立模型

#第1步:導入演算法from sklearn.linear_model import LogisticRegression#第2步:創建模型:邏輯回歸(logisic regression)model = LogisticRegression()

4.3訓練模型

#第3步:訓練模型model.fit( train_X , train_y )

5.評估模型

model.score(test_X , test_y )

0.82681564245810057

6.方案實施

我們看到預測結果pred_Y是浮點數,而官網範例給的是整型int,故需先進行數據類型轉換.

pred_Y = model.predict(pred_X)pred_Y.dtype

dtype(float64)

創建具有兩個欄位的.csv文件。

pred_Y=pred_Y.astype(int)#乘客idpassenger_id = full.loc[sourceRow:,PassengerId]#數據框:乘客id,預測生存情況的值predDf = pd.DataFrame( { PassengerId: passenger_id , Survived: pred_Y } )predDf.shapepredDf.head()#保存結果predDf.to_csv( titanic_pred.csv , index = False )

把生成的.csv文件上傳到kaggle中,排名如下:

假以時日,學了強大的演算法再來提高排名。


推薦閱讀:

TAG:科技 | 泰坦尼克號電影 |