kaggle項目實戰(zhàn)——泰坦尼克號船員存活率預(yù)測

很久之前練習過的一個kaggle項目,有點記不清了,今天來溫習下,嘻嘻~
kaggle給初學者或者富有挑戰(zhàn)能力的選手們提供了一個非常好的平臺,希望自己以后盡量抽時間多做幾個這種項目,與大牛們一起交流學習~

1.下載理解數(shù)據(jù)集

下載地址:https://www.kaggle.com/c/titanic/data(需要注冊kaggle才能下載哦~)
下載完數(shù)據(jù)集要理解每個字段的含義,項目背景等,這個 很重要哦~

2.加載查看數(shù)據(jù)分布、缺失、異常情況

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
train=pd.read_csv("F:/titanic/train.csv")
test=pd.read_csv("F:/titanic/test.csv")
train.head() #大概看一下數(shù)據(jù)長什么樣
#查看數(shù)據(jù)類型,缺失情況等信息
train.info()
test.info()

通過上面的信息,我們可以得到:

  • 訓練集共有891個樣本,測試集共有418個樣本
  • 訓練集和測試集中Cabin這個特征缺失都比較多,了解到這個特征的意思是客艙號碼,跟我們要預(yù)測的船員是否生存關(guān)系應(yīng)該不大,因此后期考慮將這個特征刪除
  • 訓練集和測試集中Age這個特征都有缺失,但是缺失不多,可以通過眾數(shù)、中位數(shù)、均值、插值、特殊值等填充,鑒于時間和成本因素,后面我直接用眾數(shù)填充,有精力的可以多嘗試幾種方法,選擇最好的進行填充
  • Embarked僅在訓練集中有缺失,缺失2個,也是不多,且了解到這個特征的意思是登船港,共有3個不同的取值,因此后面直接用眾數(shù)進行填充
  • Fare僅在測試集中有1個缺失,且了解到這個特征的意思是旅客票價,應(yīng)該跟Pclass(Ticket class )相關(guān)性比較高,后面將結(jié)合Pclass進行填充
    好了,知道了數(shù)據(jù)大概的缺失情況,我們下面看一下他們的統(tǒng)計性描述信息:
train.describe()
test.describe()

通過上面的統(tǒng)計描述信息,我們可以發(fā)現(xiàn):

  • 訓練集中平均38%左右的人生還
  • Pclass即船票類型共分三等,分別是1、2、3
  • 數(shù)據(jù)集中年齡最大的是80,最小的是0.17,年齡在50歲以上的人很少,大部分集中在20-40歲之間
  • 船票價格差距較大,支付高價格的人很少
  • 帶父母或孩子出行的乘客很少
  • PassengerId只是每位乘客的一個唯一標識,訓練模型時可將該特征去掉
    上面描述的都是數(shù)值型的特征信息,也可以查看字符型的特征信息:
train.describe(include=["O"])

通過對訓練集的特征統(tǒng)計信息,可以發(fā)現(xiàn):

  • Name這個特征所有的名字都不一樣,但從名字中可能獲取不到更多的信息,但是發(fā)現(xiàn)名字都帶有Miss、Mr、Mrs這種稱謂信息,后續(xù)可以在特征工程時構(gòu)建此類信息
  • Sex特征中,男性占比更大,891人中577都是男性
  • Embarked特征中,共3個不同的取值,S即Southampton頻次最高,644次

3.數(shù)據(jù)探索,挖掘各個特征與目標特征之間的關(guān)系

先看一下這些數(shù)值特征與目標特征間的線性相關(guān)性:

import seaborn as sns 
#Seaborn是對matplotlib的extend,是一個數(shù)據(jù)可視化庫,提供更高級的API封裝,在應(yīng)用中更加的方便靈活
corrmat=train.drop('PassengerId',axis=1).corr()
f, ax = plt.subplots(figsize=(10, 7))
plt.xticks(rotation='90')
sns.heatmap(corrmat, square=True, linewidths=.5, annot=True)
plt.show()

通過上圖,可以發(fā)現(xiàn):

  • 是否生存與Fare程正相關(guān),相關(guān)性系數(shù)為0.26,與Pclass程負相關(guān),相關(guān)性系數(shù)為0.34,從實際含義也可以理解,因為票價越高,船票類型就越小,最好的船票是1等票,因此,F(xiàn)are與Pclass的相關(guān)性系數(shù)也很高,0.55
  • Parch與SibSp相關(guān)性也很高,為0.415,
    下面我們再單獨對這些特征進行分析:
    (1)對Pclass進行分析
train[['Survived','Pclass']].groupby(['Pclass']).mean()


通過上面的結(jié)果,可以發(fā)現(xiàn)Pclass等級越高,存活率越高,這是一個比較重要的特征
(2)對Age進行分析

target = sns.FacetGrid(train,col='Survived')
target.map(plt.hist,'Age',bins=20)

通過上圖,可以發(fā)現(xiàn):

  • 大部分乘客年齡都在20-40歲之間
  • 0-10歲之間存活下來的兒童較多,大量13-35歲之間的乘客沒有存活下來,年齡最大(80歲)的老爺爺存活下來
  • 并不是年齡越大或者越小存活率越大,因此我們需要對年齡進行分段,具體劃分方法可以通過人為經(jīng)驗、圖像觀察、決策樹輔助等劃分
    (3)對SibSp和Parch進行分析
train[['Survived','SibSp']].groupby(['SibSp']).mean()
train[['Survived','Parch']].groupby(['Parch']).mean()

通過上圖,可以發(fā)現(xiàn):

  • 是否生存與SibSp、Parch線性相關(guān)性不是很明顯,可以看后期模型中的效果再做判斷
    (4)對Fare進行分析
target = sns.FacetGrid(train,col='Survived')
target.map(plt.hist,'Fare',bins=20)

通過上圖,可以發(fā)現(xiàn):

  • 票價越低,存活率越低
  • 這個可以跟Pclass對應(yīng),船票等級越高,存活率越高,但這兩個特征具有高度共線性,后期如果用線性回歸之類的模型可以只用其中的一個特征
    (4)對Embarked進行分析
train[['Survived','Embarked']].groupby(['Embarked']).mean()

可以發(fā)現(xiàn):

  • 從C口進入的乘客存活率更高,從S口進入的乘客存活率最低,改特征是定性特征,很多模型都無法直接運行,后續(xù)可以對改特征進行亞編碼
    (5)對Sex分析
train[['Survived','Sex']].groupby(['Sex']).mean()

可以發(fā)現(xiàn):

  • 女性的存活率明顯高于男性,因此這個特征可能對最后的預(yù)測結(jié)果非常重要,后期需要進行亞編碼,或者直接0、1二值化
    (6)對Pclass和Age一起分析
target = sns.FacetGrid(train,col='Survived',row='Pclass')
target.map(plt.hist,'Age',bins=20)

可以發(fā)現(xiàn):

  • 船票類型是3,年齡在15-40歲之間的乘客存活率很低
  • 船票類型是2或3,年齡在0-15歲之間存活率很高
  • 是否能存活與年齡和船票類型都有關(guān),可以在特征工程時構(gòu)造這樣一個特征
    還可以分析很多特征組合的特點,充分發(fā)揮你的想象力,腦洞大開,這里就不再分析了,進行下一個環(huán)節(jié)咯~

4.數(shù)據(jù)清洗、特征變換等

經(jīng)過上面的分析,我們需要:

  • 刪掉PassengerId、Cabin這兩個特征,Ticket這個特征貌似也沒有太大的用處,這里也直接刪除掉,然后對Age進行缺失值填充,這里用眾數(shù)填充,Embarked也用眾數(shù)填充,F(xiàn)are只在測試集中有缺失,可以根據(jù)Pclass用訓練集中的Fare均值進行填充
  • Embarked和Sex進行亞編碼
  • Age分段和亞編碼
  • Name提取稱謂信息和亞編碼
del train['PassengerId']
del train['Cabin']
del train['Ticket']
train = train.fillna({"Age":train.Age.mean(),'Embarked':"S"})
train['Name']=train['Name'].map(lambda line: line.split(",")[1].split(".")[0])
train.head()

發(fā)現(xiàn)稱謂除了 Mr、 Miss、 Mrs、 Master,其他的都很少,所以這里把剩下的都統(tǒng)一改成other

train['Name']=train['Name'].map(lambda line: (line.strip() if line.strip() in ['Mr','Mrs','Miss','Master'] else 'other'))
train['Name'].value_counts()
train[['Survived','Name']].groupby(['Name']).mean().sort_values(by='Survived')

可以發(fā)現(xiàn),Mrs和Miss的存活率更高,Mr的存活率最低,后續(xù)我們也要將這個特征亞編碼后加入模型中訓練
下面對Age進行分段,這里就直接根據(jù)前面的分析自己定義分段區(qū)間,有精力可以用決策樹輔助分段,效果應(yīng)該會更好

def age_parse(line):
    if line <=15:
        return '0-15'
    elif 15<line<=35:
        return '15-35'
    elif 35<line<=50:
        return '35-50'
    else:
        return '>50'
train['Age']=train['Age'].map(age_parse)
train.head()

下面對定性特征統(tǒng)一亞編碼:

train = pd.get_dummies(train)
train.head()
#去除亞編碼后線性相關(guān)變量
del train['Name_other']
del train['Age_>50']
del train['Embarked_S']
del train['Sex_female']
圖1
特征標準化

由于Fare這個特征含有較大的數(shù)值,為了避免由于量綱帶來的問題,我們將它進行標準化

from sklearn import preprocessing
scaler = preprocessing.StandardScaler().fit(np.array(train['Fare']).reshape(891,1))
fare = scaler.transform(np.array(train['Fare']).reshape(891,1))
train['Fare'] = fare
train.head()
注意: 測試集所有特征變換,特征清洗都是基于訓練集來的,例如:如果訓練集用訓練集的A特征均值填充A特征的缺失值,那么測試集也要用訓練集中A特征的均值填充缺失值,鑒于時間和精力有限,這里我只對訓練集統(tǒng)一進行處理,測試集先不做處理,以后有時間再進行處理(捂臉),由于數(shù)據(jù)處理存在許多轉(zhuǎn)換步驟,需要按一定的順序執(zhí)行,可以推薦用sklearn中的pipeline模塊,可以對訓練集和測試集統(tǒng)一數(shù)據(jù)處理,非常好用~

5.構(gòu)造特征工程

這個環(huán)節(jié)就可以充分發(fā)揮你的想象力,構(gòu)造與目標變量相關(guān)的線性特征、非線性特征、交叉特征等,可以構(gòu)造很多,后面特征篩選的時候過濾掉就好,例如可以構(gòu)造Age與Pclass的交叉特征,構(gòu)造Pclass與稱謂的交叉特征,sklearn也提供了相應(yīng)的函數(shù),如果有兩個特征(x1,x2),構(gòu)造2次多項式特征,則完后會生成(1, X1, X2, X1^2, X1X2, X2^ 2),這里我直接用特征構(gòu)造函數(shù),直接構(gòu)造所有特征的2次多項式特征(也可以構(gòu)造3次或者更高次,可以看下效果對比,這里我就直接生成2次多項式特征了)

survived = train['Survived']
from sklearn import preprocessing
#構(gòu)造2次多項式, 默認也是2次,設(shè)置參數(shù)include_bias= False,不包含偏差項數(shù)據(jù)
poly = preprocessing.PolynomialFeatures(2,include_bias=False)
poly_train = poly.fit_transform(train.drop(['Survived'],axis=1))
poly.get_feature_names()[0:20]
train_df =pd.DataFrame(poly_train)
train_df .columns=poly.get_feature_names()#特征重命名
train_df.head()


注意:這里的列名x0,x1...與圖一中除了‘Survived’的列名是一一對應(yīng)的,因為名稱太長,所以會自動生成新的名字
生成了這么多特征,我們可以看一下他們與目標特征的相關(guān)性:

可以發(fā)現(xiàn):
x0與x6,即Pclass與Name_mr相關(guān)性系數(shù)很高,x0與x10,即Pclass與Age_15-35相關(guān)性也很高,進一步查看下關(guān)系:

train_df[['Survived','x0','x6']].groupby(['x0','x6']).mean().sort_values(by='Survived')
train_df[['Survived','x0','x10']].groupby(['x0','x10']).mean().sort_values(by='Survived')

可以發(fā)現(xiàn):

  • 如果是Mr,那無論她的船票類型是什么,她的生存率都很高,但如果不是Mr,那只有他的船票類型是1等的時候,他的存活率才會較高,但還是沒有Mr的高,因此這兩個特征是非常重要的
  • 如果年齡在15-35之間,只有船票類型是1等的時候存活率才會較高,因此這兩個特征也是非常重要的
    后續(xù)還可以再對其他的特征進行類似的分析~

6.建模、調(diào)參、模型評估

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

相關(guān)閱讀更多精彩內(nèi)容

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