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分類數據:字元串
字元串類型:可能從這裡面提取出特徵來,也歸到分類數據中,這裡數據有:
- 乘客姓名(Name)
- 客艙號(Cabin)
- 船票編號(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中,排名如下:
假以時日,學了強大的演算法再來提高排名。
推薦閱讀: