泰坦尼克號生存預(yù)測

本次筆記主要記錄了一個機器學(xué)習(xí)的入門實戰(zhàn)者填,泰坦尼克號生存預(yù)測刻伊。主要涉及的知識點有,python的pandas包描验,機器學(xué)習(xí)包sklearn白嘁。

背景知識:

泰坦尼克號是英國一艘奧林匹克級郵輪,在1912年4月10日膘流,從南安普頓港碼頭出發(fā)絮缅,途徑法國和愛爾蘭,在駛向美國紐約的時候呼股,與一座冰山相撞耕魄,最終沉沒。在2224名船員及乘客中彭谁,逾1500人喪生吸奴。本次案例主要是通過機器學(xué)習(xí)方法對418人的生存狀況進行預(yù)測。案例取自kaggle: https://www.kaggle.com/c/titanic缠局。同時则奥,kaggle上提供了泰坦尼克號案例的訓(xùn)練集train.csv和測試集test.csv。

一甩鳄、提出問題

數(shù)據(jù)取自kaggle逞度,本次問題主要是探究泰坦尼克號中,各個特征與生存狀況的關(guān)系妙啃,并利用機器學(xué)習(xí)方法對生存狀況進行預(yù)測档泽。

二俊戳、 理解數(shù)據(jù)

首先導(dǎo)入數(shù)據(jù)集train.csv和test.csv:

import pandas as pd
import numpy as np

#導(dǎo)入訓(xùn)練集
train = pd.read_csv("train.csv")

#導(dǎo)入測試集
test = pd.read_csv("test.csv")

#查看測試集和訓(xùn)練集數(shù)據(jù)形狀
print("Train data: ",train.shape)
print("Test data: ",test.shape)
full=train.append(test,ignore_index=True,sort=False)
print("Full data:", full.shape)
full.head()

由以上代碼可以得出,訓(xùn)練數(shù)據(jù)為891行馆匿,12個字段抑胎,測試數(shù)據(jù)為418行,11個字段渐北,缺少的這一行字段便是要預(yù)測的生存狀況阿逃。

以下給出12個字段的含義解釋:
1. PassengerId:乘客ID
2. Survived:生存狀況;1:生存赃蛛;死亡:0
3. Pclass:船艙等級恃锉;1:一等;2:二等呕臂;3:三等
4. Name:乘客姓名
5. Sex:乘客性別
6. Age:乘客年齡
7. SibSp:乘客的兄弟姐妹以及配偶數(shù)量
8. Parch:乘客的父母與子女?dāng)?shù)量
9. Ticket:票的編號
10. Fare:船票費用
11. Cabin:乘客船艙座位號
12. Embarked:乘客登船的港口破托,有三個可選值:S:南安普頓,C:法國瑟堡Q:愛爾蘭昆士敦

full.info()
--------------------------------------------------
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1309 entries, 0 to 1308
Data columns (total 12 columns):
PassengerId    1309 non-null int64
Survived       891 non-null float64
Pclass         1309 non-null int64
Name           1309 non-null object
Sex            1309 non-null object
Age            1046 non-null float64
SibSp          1309 non-null int64
Parch          1309 non-null int64
Ticket         1309 non-null object
Fare           1308 non-null float64
Cabin          295 non-null object
Embarked       1307 non-null object
dtypes: float64(3), int64(4), object(5)
memory usage: 122.8+ KB

通過分析可以得出歧蒋,總數(shù)據(jù)為1309土砂,其中Survived, Age, Fare, Cabin, Embarked均有缺失值,其中Survived的缺失值是所需要求的生存狀況谜洽,其他值則需要通過數(shù)據(jù)清洗的方法來補全萝映。

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

  1. Fare為數(shù)值類型阐虚,缺失值為1序臂,因此采用平均值進行填充。
  2. Embarked為字符串類型敌呈,缺失值為2贸宏,因此采用眾數(shù)進行填充。
  3. Cabin為字符串類型磕洪,缺失過多,缺失值為1014诫龙,缺失率為77.46%析显,原因可能為很多乘客沒有艙位號,因此將缺失值用U來替代签赃,表示未知谷异。
  4. Age為數(shù)值類型,缺失值為263锦聊,本次采用平均值進行填充歹嘹,由于年齡對于生存影響可能相對較大,因此下次會介紹如何使用機器學(xué)習(xí)方法進行填充孔庭。
# Fare缺失值填充
full.Fare = full.Fare.fillna(full.Fare.mean())
# Embarked缺失值填充
full.Embarked = full.Embarked.fillna(full.Embarked.mode()[0])
# Cabin缺失值填充
full.Cabin = full.Cabin.fillna('U')
# Age本次使用平均值填充
full.Age = full.Age.fillna(full.Age.mean())

在處理完缺失值以后尺上,還需要對字符串類型的數(shù)值進行one-hot編碼材蛛,方便機器學(xué)習(xí)算法識別。這里對Sex, Cabin, Embarked進行重新編碼怎抛。

# 對Sex進行編碼
sex = {'male':1,'female':0}
sex_num = full.Sex.map(sex)
sex_num.head()
# 對Embarked進行編碼
embarked = pd.DataFrame()
embarked = pd.get_dummies(full.Embarked,prefix="Embarked")
embarked.head()
# 對Pcclass進行編碼
pclass = pd.DataFrame()
pclass = pd.get_dummies(full.Pclass,prefix="Pclass")
pclass.head()

接下來將對名字的頭銜進行提取卑吭,因為不同的頭銜和職位可能會對生存情況產(chǎn)生影響。同時马绝,在提取名字頭銜后豆赏,會定義一個新字典作為身份,用來映射頭銜與身份的關(guān)系富稻,并對身份進行one-hot編碼掷邦。

# 提取名字中的頭銜
title = pd.DataFrame()
title['title'] = full.Name.map(lambda name:name.split(',')[1].split('.')[0].strip())
# 用groupby方法列出各種頭銜
title.groupby('title').count()
# 創(chuàng)建身份字典
position = {
    'Capt':'Officer',
    'Col':'Officer',
    'Dr' :'Officer',
    'Don':'Royalty',
    'Dona':'Royalty',
    'Jonkheer':'Royalty',
    'Lady':'Miss',
    'Major':'Officer',
    'Master':'Master',
    'Mlle':'Miss',
    'Mme':'Mrs',
    'Mr':'Mr',
    'Mrs':'Mrs',
    'Ms':'Miss',
    'Rev':'Officer',
    'Sir':'Royalty',
    'the Countess':'Royalty'
}
# 將字典映射到頭銜上
title['title'] = title['title'].map(position)
------------------------------
title
Master      61
Miss         5
Mr         757
Mrs        198
Officer     23
Royalty      5
Name: Name, dtype: int64
# 進行one-hot編碼
title = pd.get_dummies(title['title'])

完成上述步驟后,可以獲得one-hot表格如下:


one-hot編碼后的頭銜表格

接下來對Cabin列進行分類處理椭赋,首先提取首字母抚岗,然后按照首字母進行one-hot編碼。

# 提取cabin首字母
cabin = full.Cabin.map(lambda cabin:cabin[0])
# 進行one-hot編碼
cabin = pd.get_dummies(cabin,prefix='Cabin')

Parch字段和SibSp字段纹份,其實可以歸類為家庭成員的個數(shù)苟跪,可以將兩者相加組成一個新字段作為家庭成員數(shù)量

family = full.Parch+full.SibSp +1

最后,將原始數(shù)據(jù)復(fù)制保留一份蔓涧,并將重新編碼的字段包括(Pclass, Name,Sex,Age,SibSp,Parch,Cabin,Embarked)以及無用字段Ticket刪除件已。

# 復(fù)制一份原始數(shù)據(jù)
full_origin = train.append(test,ignore_index=True,sort=False)
# 建立一份新數(shù)據(jù)繼續(xù)繼續(xù)操作
full_data = full
# 刪除無用字段及重新編碼字段
full_data = full_data.drop(['Cabin','Name','Sex','Pclass','Embarked','Parch','SibSp','Ticket'],axis=1)
# 將重新編碼后的字段加入新數(shù)據(jù)
full_data = pd.concat([full_data,sex_num,embarked,pclass,title,cabin,family],axis=1)
# 最終得到數(shù)據(jù)如下
--------------------------------------------------
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1309 entries, 0 to 1308
Data columns (total 27 columns):
PassengerId    1309 non-null int64
Survived       891 non-null float64
Age            1309 non-null float64
Fare           1309 non-null float64
Sex            1309 non-null int64
Embarked_C     1309 non-null uint8
Embarked_Q     1309 non-null uint8
Embarked_S     1309 non-null uint8
Pclass_1       1309 non-null uint8
Pclass_2       1309 non-null uint8
Pclass_3       1309 non-null uint8
Master         1309 non-null uint8
Miss           1309 non-null uint8
Mr             1309 non-null uint8
Mrs            1309 non-null uint8
Officer        1309 non-null uint8
Royalty        1309 non-null uint8
Cabin_A        1309 non-null uint8
Cabin_B        1309 non-null uint8
Cabin_C        1309 non-null uint8
Cabin_D        1309 non-null uint8
Cabin_E        1309 non-null uint8
Cabin_F        1309 non-null uint8
Cabin_G        1309 non-null uint8
Cabin_T        1309 non-null uint8
Cabin_U        1309 non-null uint8
Family         1309 non-null int64
dtypes: float64(3), int64(3), uint8(21)
memory usage: 88.3 KB

四、 建模與評估

  1. 首先利用corr()函數(shù)建立相關(guān)系數(shù)矩陣元暴,并提取出生存字段的相關(guān)系數(shù)并進行排序篷扩。
# 建立相關(guān)系數(shù)矩陣
corrDf = full_data.corr()
# 對生存字段的相關(guān)系數(shù)進行排序
print(corrDf['Survived'].sort_values(ascending=False))
----------------------------------------
Survived       1.000000
Mrs            0.341994
Pclass_1       0.285904
Fare           0.257307
Cabin_B        0.175095
Embarked_C     0.168240
Cabin_D        0.150716
Cabin_E        0.145321
Cabin_C        0.114652
Pclass_2       0.093349
Master         0.085221
Miss           0.085083
Cabin_F        0.057935
Cabin_A        0.022287
Family         0.016639
Royalty        0.016040
Cabin_G        0.016040
Embarked_Q     0.003650
PassengerId   -0.005007
Cabin_T       -0.026456
Officer       -0.031316
Age           -0.070323
Embarked_S    -0.149683
Cabin_U       -0.316912
Pclass_3      -0.322308
Sex           -0.543351
Mr            -0.549199
Name: Survived, dtype: float64

經(jīng)過排序后發(fā)現(xiàn),呈正相關(guān)的字段有:頭銜茉盏,客艙等級鉴未,船票價格,船艙號等鸠姨;呈負相關(guān)的的字段有:頭銜铜秆,性別,客艙等級讶迁,船艙號连茧。

  1. 原訓(xùn)練數(shù)據(jù)為891行,因此將處理后的新數(shù)據(jù)集拆分成訓(xùn)練集和測試集
from sklearn.cross_validation import train_test_split
from sklearn.linear_model import LogisticRegression

# 訓(xùn)練數(shù)據(jù)數(shù)量
trainNum = 891
# 截取訓(xùn)練數(shù)據(jù)
data_X = full_data.loc[0:trainNum-1,:]
data_X = data_X.drop('Survived',axis=1)
data_y = full_data.loc[0:trainNum-1,'Survived']
# 配置訓(xùn)練數(shù)據(jù)和測試數(shù)據(jù)
X_train,X_test,y_train,y_test = train_test_split(data_X,data_y,train_size=0.8)
print('Orginal data x:', data_X.shape)
print('Train data x:',X_train.shape)
print('Test data x:',X_test.shape)
print('Orginal data y: ', data_y.shape)
print('Train data y: ',y_train.shape)
print('Test data y: ',y_test.shape)
  1. 導(dǎo)入模型算法巍糯,代入數(shù)據(jù)訓(xùn)練模型
# 導(dǎo)入邏輯回歸模型
model = LogisticRegression()
# 使用訓(xùn)練數(shù)據(jù)訓(xùn)練模型
model.fit(X_train, y_train)
# 測試模型準(zhǔn)確度
print(model.score(X_test,y_test))

利用訓(xùn)練數(shù)據(jù)中的測試集進行測試啸驯,發(fā)現(xiàn)模型準(zhǔn)確率為86.6%

  1. 利用訓(xùn)練好的模型對測試集進行預(yù)測
# 取出測試集
X_predict = full_data.loc[trainNum:,:]
X_predict = X_predict.drop(['Survived'],axis=1)
# 將測試基代入模型進行預(yù)測
y_predict = model.predict(X_predict)
# 對測試集進行格式化
y_predict = y_predict.astype(int)
# 將預(yù)測結(jié)果用passengerId進行保存
passengerId = full_data.loc[trainNum:,'PassengerId']
predictDf = pd.DataFrame({'PassengerId':passengerId,'Survived':y_predict})
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市祟峦,隨后出現(xiàn)的幾起案子罚斗,更是在濱河造成了極大的恐慌,老刑警劉巖宅楞,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件针姿,死亡現(xiàn)場離奇詭異袱吆,居然都是意外死亡,警方通過查閱死者的電腦和手機搓幌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進店門杆故,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人溉愁,你說我怎么就攤上這事处铛。” “怎么了拐揭?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵撤蟆,是天一觀的道長。 經(jīng)常有香客問我堂污,道長家肯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任盟猖,我火速辦了婚禮讨衣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘式镐。我一直安慰自己反镇,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布娘汞。 她就那樣靜靜地躺著歹茶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪你弦。 梳的紋絲不亂的頭發(fā)上惊豺,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天,我揣著相機與錄音禽作,去河邊找鬼尸昧。 笑死,一個胖子當(dāng)著我的面吹牛旷偿,可吹牛的內(nèi)容都是我干的彻磁。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼狸捅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了累提?” 一聲冷哼從身側(cè)響起尘喝,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎斋陪,沒想到半個月后朽褪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體置吓,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年缔赠,在試婚紗的時候發(fā)現(xiàn)自己被綠了衍锚。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡嗤堰,死狀恐怖戴质,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情踢匣,我是刑警寧澤告匠,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站离唬,受9級特大地震影響后专,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜输莺,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一戚哎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嫂用,春花似錦型凳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至实夹,卻和暖如春橄浓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背亮航。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工荸实, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人缴淋。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓准给,卻偏偏與公主長得像,于是被迫代替她去往敵國和親重抖。 傳聞我的和親對象是個殘疾皇子露氮,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,630評論 2 359

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