kaggle項目:泰坦尼克號生存率分析

一展运、提出問題:

1912年4月15日孔厉,號稱“永不沉沒”的泰坦尼克號巨輪,在首航期間谎亩,撞上冰山之后沉沒梢薪。船上的2224名乘客和機組人員蹬铺,只有772人存活了下來,生存率只有32%秉撇,讓人唏噓不已甜攀。

導(dǎo)致大量的沒法存活的重要原因之一秋泄,就是沒有足夠的救生艇,在上船前规阀,露絲就曾向船長提出救生艇不夠的問題恒序。雖然幸存下來有一些運氣因素,但是谁撼,有一些人可能比其他人更有可能生存歧胁,比如婦女,兒童以及上層階級厉碟。

所以喊巍,我們研究的問題是:什么樣的人能夠更容易在泰坦尼克號存活?


二箍鼓、理解數(shù)據(jù):

1.采集數(shù)據(jù)

數(shù)據(jù)來源于kaggle平臺項目:點擊下載Kaggle泰坦尼克號數(shù)據(jù)

2.導(dǎo)入數(shù)據(jù)

import os??#查看工作路徑崭参,首先要導(dǎo)入os工作包。

os.getcwd()??# 查看默認(rèn)工作路徑款咖。

os.chdir("/Users//Desktop/KAGGLE/datas/")??#修改工作路徑為文件存放路徑何暮。


導(dǎo)入處理數(shù)據(jù)包

import numpy as np

import pandas as pd


導(dǎo)入數(shù)據(jù)

訓(xùn)練數(shù)據(jù)集

train = pd.read_csv("./train.csv")

測試數(shù)據(jù)集

test??= pd.read_csv("./test.csv")

print ('訓(xùn)練數(shù)據(jù)集:',train.shape,'測試數(shù)據(jù)集:',test.shape)


合并數(shù)據(jù)集,方便同時對兩個數(shù)據(jù)集進行清洗

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


3.查看數(shù)據(jù)

查看數(shù)據(jù)

full.head()

查看每一列的數(shù)據(jù)類型之剧,和數(shù)據(jù)總數(shù)

full.info()

根據(jù)上面打印的結(jié)果郭卫,我們發(fā)現(xiàn)數(shù)據(jù)總共有1309行砍聊。

其中數(shù)據(jù)類型列:年齡(Age)背稼、船艙號(Cabin)里面有缺失數(shù)據(jù):

年齡(Age)里面數(shù)據(jù)總數(shù)是1046條,缺失了1309-1046=263玻蝌,缺失率263/1309=20%

船票價格(Fare)里面數(shù)據(jù)總數(shù)是1308條蟹肘,缺失了1條數(shù)據(jù)

字符串列:

登船港口(Embarked)里面數(shù)據(jù)總數(shù)是1307,只缺失了2條數(shù)據(jù)俯树,缺失比較少

船艙號(Cabin)里面數(shù)據(jù)總數(shù)是295帘腹,缺失了1309-295=1014,缺失率=1014/1309=77.5%许饿,缺失比較大

? ? 這為我們下一步數(shù)據(jù)清洗指明了方向阳欲,只有知道哪些數(shù)據(jù)缺失數(shù)據(jù),我們才能有針對性的處理陋率。


三球化、數(shù)據(jù)清洗

1.缺失值處理

在前面,理解數(shù)據(jù)階段瓦糟,我們發(fā)現(xiàn)數(shù)據(jù)總共有1309行筒愚。

?其中數(shù)據(jù)類型列:年齡(Age)、船艙號(Cabin)里面有缺失數(shù)據(jù)菩浙。?

?字符串列:登船港口(Embarked)巢掺、船艙號(Cabin)里面有缺失數(shù)據(jù)句伶。


用均值填充年齡以及船票價格的缺失值:

?#年齡(Age)缺失率為20%:

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

?#船票價格(Fare)缺失1條數(shù)據(jù):

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


#登船港口缺失2條數(shù)據(jù),用眾數(shù)填充:

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

#船艙號缺失值為77.5%陆淀,用U填充:

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


四考余、特征提取

1.數(shù)據(jù)分類:

? 數(shù)值類型:

? 乘客編號(PassengerId),年齡(Age)倔约,船票價格(Fare)秃殉,同代直系親屬人數(shù)(SibSp),不同代直系親屬人數(shù)(Parch)

? 時間序列:無

? 分類數(shù)據(jù):

? 1)有直接類別的

? 乘客性別(Sex):男性male浸剩,女性female

? 登船港口(Embarked):出發(fā)地點S=英國南安普頓Southampton钾军,途徑地點1:C=法國 瑟堡市Cherbourg,出發(fā)地點2:Q=愛爾蘭 昆士敦Queenstown

? 客艙等級(Pclass):1=1等艙绢要,2=2等艙吏恭,3=3等艙

? 2)字符串類型:可能從這里面提取出特征來,也歸到分類數(shù)據(jù)中

? 乘客姓名(Name)

? 客艙號(Cabin)

? 船票編號(Ticket)

2.分類數(shù)據(jù)處理:

2.1?乘客性別(Sex)

將性別的值映射為數(shù)值:

男(male)對應(yīng)數(shù)值1重罪,女(female)對應(yīng)數(shù)值0

sex_mapDict={'male':1,

????????????'female':0}

#map函數(shù):對Series每個數(shù)據(jù)應(yīng)用自定義的函數(shù)計算

full['Sex']=full['Sex'].map(sex_mapDict)

2.2?登船港口(Embarked)

#存放提取后的特征

embarkedDf = pd.DataFrame()

使用get_dummies進行one-hot編碼樱哼,產(chǎn)生虛擬變量(dummy variables),列名前綴是Embarked

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

embarkedDf.head()

#添加one-hot編碼產(chǎn)生的虛擬變量(dummy variables)到泰坦尼克號數(shù)據(jù)集full剿配,并把登船港口(Embarked)刪掉搅幅。

full = pd.concat([full,embarkedDf],axis=1)

full.drop('Embarked',axis=1,inplace=True)

2.3?客艙等級(Pclass)

客艙等級(Pclass):

1=1等艙,2=2等艙呼胚,3=3等艙

#存放提取后的特征

pclassDf = pd.DataFrame()

#使用get_dummies進行one-hot編碼茄唐,列名前綴是Pclass

pclassDf = pd.get_dummies( full['Pclass'] , prefix='Pclass’ )

#刪掉客艙等級(Pclass)這一列

full.drop('Pclass',axis=1,inplace=True)

字符串類型:

2.4 ?乘客姓名(Name)

定義函數(shù):從姓名中獲取頭銜:

def getTitle(name):

????str1=name.split( ',' )[1] #Mr. Owen Harris

????str2=str1.split( '.' )[0]#Mr

????#strip() 方法用于移除字符串頭尾指定的字符(默認(rèn)為空格)

????str3=str2.strip()

????return str3

#存放提取后的特征

titleDf = pd.DataFrame()

#map函數(shù):對Series每個數(shù)據(jù)應(yīng)用自定義的函數(shù)計算

titleDf['Title'] = full['Name'].map(getTitle)

titleDf.head()

定義以下幾種頭銜類別:

Officer政府官員

Royalty王室(皇室)

Mr已婚男士

Mrs已婚婦女

Miss年輕未婚女子

Master有技能的人/教師

#姓名中頭銜字符串與定義頭銜類別的映射關(guān)系

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"}

#map函數(shù):對Series每個數(shù)據(jù)應(yīng)用自定義的函數(shù)計算

titleDf['Title'] = titleDf['Title'].map(title_mapDict)

#使用get_dummies進行one-hot編碼

titleDf = pd.get_dummies(titleDf['Title'])

titleDf.head()

#添加one-hot編碼產(chǎn)生的虛擬變量(dummy variables)到泰坦尼克號數(shù)據(jù)集full

full = pd.concat([full,titleDf],axis=1)

#刪掉姓名這一列

full.drop('Name',axis=1,inplace=True)


2.5 ?客艙號(Cabin)

#存放客艙號信息

cabinDf = pd.DataFrame()


客場號的類別值是首字母,例如:

C85 類別映射為首字母C

full[ 'Cabin' ] = full[ 'Cabin' ].map( lambda c : c[0] )

##使用get_dummies進行one-hot編碼蝇更,列名前綴是Cabin

cabinDf = pd.get_dummies( full['Cabin'] , prefix = 'Cabin’ )

#添加one-hot編碼產(chǎn)生的虛擬變量(dummy variables)到泰坦尼克號數(shù)據(jù)集full

full = pd.concat([full,cabinDf],axis=1)

#刪掉客艙號這一列

full.drop('Cabin',axis=1,inplace=True)

2.6 ? ?家庭人數(shù)

#存放家庭信息

familyDf = pd.DataFrame()

家庭人數(shù)=同代直系親屬數(shù)(Parch)+不同代直系親屬數(shù)(SibSp)+乘客自己

(因為乘客自己也是家庭成員的一個沪编,所以這里加1)

familyDf[ 'FamilySize' ] = full[ 'Parch' ] + full[ 'SibSp' ] + 1

家庭類別:

小家庭Family_Single:家庭人數(shù)=1

中等家庭Family_Small: 2<=家庭人數(shù)<=4

大家庭Family_Large: 家庭人數(shù)>=5


#if 條件為真的時候返回if前面內(nèi)容,否則返回0

familyDf[ '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()

#添加one-hot編碼產(chǎn)生的虛擬變量(dummy variables)到泰坦尼克號數(shù)據(jù)集full

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

full.head()


五年扩、特征選擇

相關(guān)系數(shù)法:計算各個特征的相關(guān)系數(shù)

#相關(guān)性矩陣

corrDf = full.corr()

corrDf

查看各個特征與生成情況(Survived)的相關(guān)系數(shù)蚁廓,

ascending=False表示按降序排列

corrDf['Survived'].sort_values(ascending =False)

我們發(fā)現(xiàn)頭銜Mrs和生存情況有著很強的正線性相關(guān),頭銜Mr和生存情況有負(fù)線性相關(guān)性厨幻。有可能當(dāng)時船上執(zhí)行了相嵌,發(fā)生災(zāi)難時:婦女兒童優(yōu)先。雖然災(zāi)難發(fā)生况脆,很多人還是很好的遵守了這一人性的原則饭宾。

根據(jù)各個特征與生成情況(Survived)的相關(guān)系數(shù)大小,我們選擇了這幾個特征作為模型的輸入:

頭銜(前面所在的數(shù)據(jù)集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()



六肤频、模型構(gòu)建

1.建立訓(xùn)練數(shù)據(jù)集和測試數(shù)據(jù)集

用訓(xùn)練數(shù)據(jù)和某個機器學(xué)習(xí)算法得到機器學(xué)習(xí)模型叹括,用測試數(shù)據(jù)評估模型

#原始數(shù)據(jù)集:特征

source_X = full_X.loc[0:sourceRow-1,:]

#原始數(shù)據(jù)集:標(biāo)簽

source_y = full.loc[0:sourceRow-1,'Survived']???

#預(yù)測數(shù)據(jù)集:特征

pred_X = full_X.loc[sourceRow:,:]

source_y

source_X

pred_X


from sklearn.model_selection import train_test_split

#建立模型用的訓(xùn)練數(shù)據(jù)集和測試數(shù)據(jù)集

train_X, test_X, train_y, test_y = train_test_split(source_X ,

????????????????????????????????????????????????????source_y,

????????????????????????????????????????????????????train_size=.80)

#交叉驗證

#cross_validation.cross_val_score(LR, train_X , train_y, cv=10)

#輸出數(shù)據(jù)集大小

print ('原始數(shù)據(jù)集特征:',source_X.shape,

???????'訓(xùn)練數(shù)據(jù)集特征:',train_X.shape ,

??????'測試數(shù)據(jù)集特征:',test_X.shape)

print ('原始數(shù)據(jù)集標(biāo)簽:',source_y.shape,

???????'訓(xùn)練數(shù)據(jù)集標(biāo)簽:',train_y.shape ,

??????'測試數(shù)據(jù)集標(biāo)簽:',test_y.shape)

2.模型訓(xùn)練評估

邏輯回歸:

#第1步:導(dǎo)入算法

from sklearn.linear_model import LogisticRegression

#第2步:創(chuàng)建模型:邏輯回歸(logisic regression)

model = LogisticRegression()

#第3步:訓(xùn)練模型

model.fit( train_X , train_y )

# 分類問題,score得到的是模型的準(zhǔn)確率

model.score(test_X , test_y )

結(jié)果:0.83240223463687146

神經(jīng)網(wǎng)絡(luò):

from sklearn.neural_network import MLPClassifier

mlp = MLPClassifier(hidden_layer_sizes=(30,20,20,20), max_iter=1000)

# 計算交叉驗證的準(zhǔn)確率

mlp.fit(train_X,train_y)

mlp.score(test_X , test_y)

結(jié)果:0.83798882681564246

KNN:

from sklearn import neighbors

knn = neighbors.KNeighborsClassifier(n_neighbors=8)

scores = cross_validation.cross_val_score(knn, train_X , train_y, cv=5)

print(scores.mean())

結(jié)果:0.762612035851

決策樹:

from sklearn import tree

dtree = tree.DecisionTreeClassifier(max_depth=3, min_samples_split=4)

scores = cross_validation.cross_val_score(dtree, train_X , train_y, cv=3)

print(scores.mean())

結(jié)果:0.815921283768

隨機森林:

from sklearn.ensemble import RandomForestClassifier

RF = RandomForestClassifier(n_estimators=100, min_samples_split=4)

scores = cross_validation.cross_val_score(RF, train_X , train_y, cv=3)

print(scores.mean())

結(jié)果:0.81598062954

Bagging:

from sklearn.ensemble import BaggingClassifier

bagging_clf = BaggingClassifier(RF,n_estimators=20)

scores = cross_validation.cross_val_score(bagging_clf,train_X , train_y, cv=3)

print(scores.mean())

結(jié)果:0.831410530314

Adaboost:

from sklearn.ensemble import AdaBoostClassifier

adaboost = AdaBoostClassifier(bagging_clf, n_estimators=10)

scores = cross_validation.cross_val_score(adaboost, train_X , train_y, cv=3)

print(scores.mean())

結(jié)果:0.827196980487

Stacking:

from sklearn.ensemble import VotingClassifier

sclf = VotingClassifier([('LR',LR),('mlp',mlp),('bagging_clf',bagging_clf),('knn',knn),('dtree',dtree)])

scores = cross_validation.cross_val_score(sclf, train_X , train_y, cv=15)

print(scores.mean())

結(jié)果:0.829916895836

結(jié)果可以看出:神經(jīng)網(wǎng)絡(luò)預(yù)測結(jié)果最好宵荒。



七汁雷、方案實施

1.結(jié)果上傳

使用預(yù)測數(shù)據(jù)集到底預(yù)測結(jié)果,并保存到csv文件中报咳,上傳到Kaggle中侠讯,就可以看到排名。

#使用機器學(xué)習(xí)模型暑刃,對預(yù)測數(shù)據(jù)集中的生存情況進行預(yù)測

pred_Y = model.predict(pred_X)

'''

生成的預(yù)測值是浮點數(shù)(0.0,1,0)

但是Kaggle要求提交的結(jié)果是整型(0,1)

所以要對數(shù)據(jù)類型進行轉(zhuǎn)換

'''

pred_Y=pred_Y.astype(int)

#乘客id

passenger_id = full.loc[sourceRow:,'PassengerId']

#數(shù)據(jù)框:乘客id厢漩,預(yù)測生存情況的值

predDf = pd.DataFrame(

????{ 'PassengerId': passenger_id ,

?????'Survived': pred_Y } )

predDf.shape

predDf.head()

#保存結(jié)果

predDf.to_csv( 'titanic_pred.csv' , index = False )

2.結(jié)論

2.1 ? 從性別來看:女性比男性(負(fù)線性相關(guān))更容易存活,可能是在災(zāi)難來臨的時候岩臣,整個群體遵循了“女人小孩先走的”的人性原則溜嗜。

2.2 ?從倉位來看:高等級的倉位,生存率更高架谎,可能是因為高等級的倉位處于上層甲板炸宵,逃生比低級倉位更容易

2.3 ?從頭銜可以看出社會等級的差異,不同的社會等級往往生存率也有所不同谷扣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末土全,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子抑钟,更是在濱河造成了極大的恐慌涯曲,老刑警劉巖野哭,帶你破解...
    沈念sama閱讀 222,946評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件在塔,死亡現(xiàn)場離奇詭異,居然都是意外死亡拨黔,警方通過查閱死者的電腦和手機蛔溃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,336評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來篱蝇,“玉大人贺待,你說我怎么就攤上這事×憬兀” “怎么了麸塞?”我有些...
    開封第一講書人閱讀 169,716評論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長涧衙。 經(jīng)常有香客問我哪工,道長奥此,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,222評論 1 300
  • 正文 為了忘掉前任雁比,我火速辦了婚禮稚虎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘偎捎。我一直安慰自己蠢终,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,223評論 6 398
  • 文/花漫 我一把揭開白布茴她。 她就那樣靜靜地躺著寻拂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪丈牢。 梳的紋絲不亂的頭發(fā)上兜喻,一...
    開封第一講書人閱讀 52,807評論 1 314
  • 那天,我揣著相機與錄音赡麦,去河邊找鬼朴皆。 笑死,一個胖子當(dāng)著我的面吹牛泛粹,可吹牛的內(nèi)容都是我干的遂铡。 我是一名探鬼主播,決...
    沈念sama閱讀 41,235評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼晶姊,長吁一口氣:“原來是場噩夢啊……” “哼扒接!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起们衙,我...
    開封第一講書人閱讀 40,189評論 0 277
  • 序言:老撾萬榮一對情侶失蹤钾怔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蒙挑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宗侦,經(jīng)...
    沈念sama閱讀 46,712評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,775評論 3 343
  • 正文 我和宋清朗相戀三年忆蚀,在試婚紗的時候發(fā)現(xiàn)自己被綠了矾利。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,926評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡馋袜,死狀恐怖男旗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情欣鳖,我是刑警寧澤察皇,帶...
    沈念sama閱讀 36,580評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站泽台,受9級特大地震影響什荣,放射性物質(zhì)發(fā)生泄漏呀忧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,259評論 3 336
  • 文/蒙蒙 一溃睹、第九天 我趴在偏房一處隱蔽的房頂上張望而账。 院中可真熱鬧,春花似錦因篇、人聲如沸泞辐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,750評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽咐吼。三九已至,卻和暖如春商佑,著一層夾襖步出監(jiān)牢的瞬間锯茄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,867評論 1 274
  • 我被黑心中介騙來泰國打工茶没, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留肌幽,地道東北人。 一個月前我還...
    沈念sama閱讀 49,368評論 3 379
  • 正文 我出身青樓抓半,卻偏偏與公主長得像喂急,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子笛求,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,930評論 2 361

推薦閱讀更多精彩內(nèi)容