機(jī)器學(xué)習(xí)入門實(shí)戰(zhàn) -- Titanic乘客生還預(yù)測(cè)-易學(xué)智能GPU云

機(jī)器學(xué)習(xí)入門實(shí)戰(zhàn) -- Titanic乘客生還預(yù)測(cè)

提出問(wèn)題:

本文主要是對(duì)泰坦尼克號(hào)沉船事件進(jìn)行預(yù)測(cè):在當(dāng)時(shí)的情況下,什么樣的人更容易存活?

獲取數(shù)據(jù):

在Kaggle中泰坦尼克項(xiàng)目主界面的Data欄獲取,有測(cè)試數(shù)據(jù)、訓(xùn)練數(shù)據(jù)和提交格式三個(gè)文件,本平臺(tái)已在云端配置好相關(guān)數(shù)據(jù),運(yùn)行下面的代碼塊即可讀取相應(yīng)的數(shù)據(jù)集。

In?[?]:

#首先導(dǎo)入相關(guān)的python包

import pandas as pd

import numpy as np

import sklearn as sk

In?[?]:

#讀取泰坦尼克數(shù)據(jù)集

import sys

sys.path.append('/home/ubuntu/MyFiles/PublicData/')

import os

import datasets_path

In?[?]:

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

train = pd.read_csv(datasets_path.titanic_train_dir)

#測(cè)試數(shù)據(jù)

test = pd.read_csv(datasets_path.titanic_test_dir)

print('訓(xùn)練集數(shù)量:',len(train), '測(cè)試集數(shù)量:',len(test))

In?[?]:

#合并兩個(gè)數(shù)據(jù)集,對(duì)數(shù)據(jù)集進(jìn)行數(shù)據(jù)清洗

Full = train.append(test)

print('合并后的數(shù)據(jù)集:',Full.shape)

數(shù)據(jù)清洗:

在處理數(shù)據(jù)之前,我們先觀察數(shù)據(jù)的形式對(duì)數(shù)據(jù)有一個(gè)大概的理解

In?[?]:

#查看數(shù)據(jù)的前5行

Full.head()

查看數(shù)據(jù)集的統(tǒng)計(jì)信息,查看是否有異常數(shù)據(jù)。

In?[?]:

#按列獲取數(shù)據(jù)類型的描述統(tǒng)計(jì)信息,非數(shù)字類型數(shù)據(jù)不會(huì)被統(tǒng)計(jì)

Full.describe()

按列查看數(shù)據(jù)關(guān)于不同特征屬性的數(shù)量,檢查數(shù)據(jù)是否有缺失值

In?[?]:

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

Full.info()

可以看到船艙號(hào)(Cabin)缺失的數(shù)據(jù)較多,接下來(lái)需要對(duì)相應(yīng)的特征屬性補(bǔ)全缺失值。在這個(gè)例子中,對(duì)于數(shù)值型數(shù)據(jù),我們采用平均值填補(bǔ);非數(shù)值型采用眾數(shù)填補(bǔ)。

In?[?]:

#票價(jià)(Fare)為數(shù)值型數(shù)據(jù),缺失一條可以采用均值補(bǔ)充

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

In?[?]:

#年齡(Age)同理

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

In?[?]:

#Embarked為非數(shù)值型數(shù)據(jù),采用眾數(shù)填充

print('眾數(shù):',Full['Embarked'].mode())

Full['Embarked'] = Full['Embarked'].fillna('S')

In?[?]:

#Cabin為字符串變量,用U補(bǔ)充表示UnKnown

Full['Cabin'] = Full['Cabin'].fillna('U')

In?[?]:

#查看填充結(jié)果

Full['Embarked'].value_counts()

對(duì)于字符型特征屬性,需要轉(zhuǎn)換為數(shù)值類型替代通常使用One-hot編碼,比如性別(Sex)

In?[?]:

#對(duì)于特征屬性(Sex),男(male = 1);女(female = 0)。

Sex_dict = {'male':1, 'female':0}

#下面使用map函數(shù)對(duì)數(shù)據(jù)進(jìn)行轉(zhuǎn)換,map函數(shù)對(duì)Series的內(nèi)個(gè)數(shù)據(jù)元素應(yīng)用自定義的函數(shù)計(jì)算

Full['Sex'] = Full['Sex'].map(Sex_dict)

Full.head()

#One-hot編碼是對(duì)操作2個(gè)類別以上的采集型編碼,因?yàn)樾詣e只有兩個(gè)類別,所以不需要使用One-hot編碼。

使用數(shù)據(jù)框的get_dummies( )方法可以實(shí)現(xiàn)One-hot編碼。所以,重編碼后新的特征,需要新建一個(gè)數(shù)據(jù)框存儲(chǔ)下來(lái):

Embarked的值分別為S,C,Q

In?[?]:

Full['Embarked'].head()

In?[?]:

embarkerDF = pd.DataFrame()

embarkerDF = pd.get_dummies(Full['Embarked'], prefix='Embarked')

embarkerDF.head()

添加One-hot編碼產(chǎn)生的虛擬變量到數(shù)據(jù)集Full,并將原有的Embarked屬性刪除

In?[?]:

Full = pd.concat([Full, embarkerDF], axis=1)

#刪除Embarked

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

Full.head()

接下來(lái)處理特征屬性Name

In?[?]:

#定義函數(shù),從姓名中提取頭銜

def getTitle(name):

? ? Name = name.split(',')[1] #split按指定符號(hào)分割字符串

? ? title = Name.split('.')[0]

? ? Title = title.strip() #移除字符串首尾制定的字符默認(rèn)為空格

? ? return Title

In?[?]:

#同上,先新建一個(gè)數(shù)據(jù)框存放處理后的數(shù)據(jù)

titleDF = pd.DataFrame()

titleDF['Title'] = Full['Name'].map(getTitle)

titleDF['Title'].head(),Full['Name'].head()

In?[?]:

'''

數(shù)據(jù)集中的頭銜有很多,為了簡(jiǎn)化我們將其映射為下面幾種頭銜類別,并對(duì)其One-hot處理

例如:Ms已婚男士,Mrs已婚女士,Officer政府官員,Royalty皇室成員,Miss年輕未婚女子,Master有技能的人員

'''

title_dict = {'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_dict)

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

titleDF.head()

In?[?]:

#將titleDF添加到Full數(shù)據(jù)集并刪除特征屬性Name

Full = pd.concat([Full,titleDF], axis=1)

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

Full.head()

In?[?]:

#家庭情況信息處理

familyDF = pd.DataFrame()

familyDF['family_size'] = Full['Parch'] + Full['SibSp'] + 1#家庭人數(shù)=同代親屬(Parch)+不同代親屬(SibSp)+乘客本身

familyDF['family_single'] = familyDF['family_size'].map(lambda s:1 if s==1 else 0)

familyDF['family_small'] = familyDF['family_size'].map(lambda s:1 if 2<=s<=4 else 0)

familyDF['family_large'] = familyDF['family_size'].map(lambda s:1 if s>4 else 0)

familyDF.head()

In?[?]:

Full = pd.concat([Full, familyDF], axis=1)

Full.head()

特征選擇:

選取原則:根據(jù)所有變量的相關(guān)系數(shù)矩陣,篩選出與預(yù)測(cè)標(biāo)簽Survived最相關(guān)的特征變量。

In?[?]:

corrDF = Full.corr()

corrDF

這里選擇‘Survived’列,按列降序排列,就能看到哪些特征最正相關(guān),哪些特征最負(fù)相關(guān),將其篩選出來(lái)作為模型的特征輸入。

In?[?]:

#按相關(guān)系數(shù)降序排列

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

選擇title_df, pclass_df, family_df, Fare, cabin_df, Sex作為特征。

構(gòu)建整體數(shù)據(jù)集的特征數(shù)據(jù)框full_x(包含1309行整體數(shù)據(jù)集特征),再使用loc屬性拆分出891行原始數(shù)據(jù)集特征source_x和標(biāo)簽source_y、481行測(cè)試數(shù)據(jù)集特征test_x:

In?[?]:

Full_X = pd.concat([titleDF,

? ? ? ? ? ? ? ? ? Full['Pclass'],

? ? ? ? ? ? ? ? ? familyDF,

? ? ? ? ? ? ? ? ? Full['Fare'],

? ? ? ? ? ? ? ? ? embarkerDF,

? ? ? ? ? ? ? ? ? Full['Sex'],

? ? ? ? ? ? ? ? ? Full['Age']], axis=1)

Full_X.head()

建立模型

建模的時(shí)候,需要將原始數(shù)據(jù)集進(jìn)行二八拆分:80%訓(xùn)練集+20%測(cè)試集。

訓(xùn)練集用于訓(xùn)練模型;測(cè)試集用于評(píng)估模型效果。

建模:

因?yàn)楸纠龥](méi)有測(cè)試集的真實(shí)標(biāo)記,所以從訓(xùn)練集中拆分出訓(xùn)練集和驗(yàn)證集以調(diào)整我們的模型。(可以上傳模型提交到Kaggle驗(yàn)證自己模型的效果)

In?[?]:

#訓(xùn)練集特征屬性

Row = 891

data_x = Full_X.loc[:Row-1,:]

#訓(xùn)練集標(biāo)簽

data_y = Full.loc[:Row-1, 'Survived']

predict_x = Full_X.iloc[Row:, :]

#loc會(huì)從0開(kāi)始選取到指定的位置,所以Row需要減1

In?[?]:

data_x.shape,data_y.shape,predict_x.shape

依據(jù)8:2的比例劃分訓(xùn)練集與驗(yàn)證集的數(shù)量

In?[?]:

from sklearn.cross_validation import train_test_split

#劃分訓(xùn)練集與驗(yàn)證集

train_x, val_x, train_y, val_y = train_test_split(data_x,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? data_y,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? train_size=0.8)

開(kāi)始訓(xùn)練一個(gè)機(jī)器學(xué)習(xí)算法

這里我們選擇較為簡(jiǎn)單的邏輯回歸算法

In?[?]:

#導(dǎo)入算法

from sklearn.linear_model import LogisticRegression

#建立模型

model = LogisticRegression(C=1, max_iter=100)

In?[?]:

#訓(xùn)練模型

model.fit(train_x, train_y)

評(píng)估模型:

使用model.score方法,通過(guò)測(cè)試集得到模型預(yù)測(cè)準(zhǔn)確率。

In?[?]:

model.score(val_x, val_y)

保存結(jié)果上傳到Kaggle看看結(jié)果如何?

In?[?]:

pred_y = model.predict(predict_x)

pred_y = pred_y.astype(int)

passenger_id = Full.iloc[891:,4]

predDF = pd.DataFrame({'PassengerId':passenger_id,

? ? ? ? ? ? ? ? ? ? ? 'Survived':pred_y})

predDF.shape

predDF.head()

In?[?]:

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

期待你們更好的成績(jī)


易學(xué)智能云平臺(tái)任一主機(jī)后可體驗(yàn)本案例的操作與交互式運(yùn)行效果。傳送門https://www.easyaiforum.cn/instanceList

更多學(xué)習(xí)案例請(qǐng)?jiān)L問(wèn)https://www.easyaiforum.cn/case

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容