機器學習:淺談kaggle泰坦尼克號生存概率

RMS泰坦尼克號的沉沒是歷史上最臭名昭著的沉船之一。1912年4月15日,在首航期間,泰坦尼克號撞上一座冰山後沉沒,2224名乘客和機組人員中有1502人遇難。這一聳人聽聞的悲劇震撼了國際社會,並導致了更好的船舶安全條例。

數據來源:

Titanic: Machine Learning from Disasterwww.kaggle.com

Kaggle是由聯合創始人、首席執行官安東尼·高德布盧姆(Anthony Goldbloom)2010年在墨爾本創立的,主要為開發商和數據科學家提供舉辦機器學習競賽、託管資料庫、編寫和分享代碼的平台。

新手學習數據分析可在kaggle中將自己學到的知識進行項目實踐

泰坦尼克號便是最受歡迎的初學者競賽的實踐項目


一.定義問題

  • 沉船導致生命損失的原因之一是乘客和船員沒有足夠的救生艇。雖然倖存下來的運氣有一些因素,但一些人比其他人更有可能生存,比如婦女,兒童和上層階級。
  • 我們將完成對什麼樣的人可能生存的分析

二.理解數據

  • 數據採集
  • 理解數據中的各個變數

三.數據預處理

  • 缺失值處理
  • 數據篩選
  • 數據變數轉換
  • One-hot編號
  • 相關性分析

四.模型構建

  • 分類
  • 預測
  • 實現過程

從kaggle網站將泰坦尼克號數據 train.csv、test.csv下載到本地

import pandas as pdimport numpy as np#訓練數據集train=pd.read_csv(...Administrator\Downloads\train.csv)#測試數據集test=pd.read_csv(...Administrator\Downloads\test.csv)print(訓練數據集:,train.shape,測試數據集:,test.shape)

輸出:

訓練數據集: (891, 12) 測試數據集: (418, 11)

將訓練數據及測試數據合併一起,方便我們接下來的數據處理

full=train.append(test,ignore_index=True)print(合併後的數據集:,full.shape)

輸出:

合併後的數據集: (1309, 12)

查看一下數據集信息

#查看數據信息詳情full.info()

<class pandas.core.frame.DataFrame>

RangeIndex: 1309 entries, 0 to 1308

Data columns (total 12 columns):

Age 1046 non-null float64

Cabin 295 non-null object

Embarked 1307 non-null object

Fare 1308 non-null float64

Name 1309 non-null object

Parch 1309 non-null int64

PassengerId 1309 non-null int64

Pclass 1309 non-null int64

Sex 1309 non-null object

SibSp 1309 non-null int64

Survived 891 non-null float64

Ticket 1309 non-null object

dtypes: float64(3), int64(4), object(5)

memory usage: 122.8+ KB

我們可以看到缺失數據有:年齡(Age)、

船艙號(Cabin)

登船港口(Embarked)

船票價(Fare)

常用的缺失數據處理的幾個方法:

  • 刪除缺失數據
  • 均值/中位數/眾數插補
  • 使用固定值
  • 最近臨插補

年齡和船票價的缺失值我們打算用均值插補

登船港口這一列使用樣本中最頻繁出現的值來插補

船艙號缺失數據較多。我們先用『U』值來插補。相當於Unknow(未知)

#使用.fillna()來插補缺失值full[Age]=full[Age].fillna(full[Age].mean())full[Fare]=full[Fare].fillna(full[Fare].mean())#使用頻繁出現的數值「s」插補full[Embarked]=full[Embarked].fillna(S)full[Cabin]=full[Cabin].fillna(U)

對性別(Sex)這一列數據值用數字代替

#用1和0表示Sexdict={male:1, female:0}full[Sex]=full[Sex].map(Sexdict)

接下來我們將One-hot編碼用於登船港口(Embarked)、客艙等級(Pclass)、名字(Name)、船艙號(Cabin)

#登船港口embarked=pd.DataFrame()embarked=pd.get_dummies(full[Embarked],prefix=embarked)full=pd.concat([full,embarked],axis=1)full.drop(Embarked,axis=1,inplace=True)#客艙等級pclass=pd.DataFrame()pclass=pd.get_dummies(full[Pclass],prefix=Pclass)full=pd.concat([full,pclass],axis=1)full.drop(Pclass,axis=1,inplace=True)

我們可以看到姓名(Name)這一列是由名字、稱謂、姓組成,

例如:Braund, Mr. Owen Harris

我們將取出稱謂,對應相應的頭銜分析頭銜與生存概率是否相關

#定義一個分割字元串的函數def segment(name): str=name.split(,)[1] #用split 分割(,)用索引【1】取出第二個數值 str1=str.split(.)[0] #用split 分割(.)用索引【0】取出第一個數值 str2=str1.strip() #取出頭尾的空格部分 return str2a=full.loc[:,Name] titDf=pd.DataFrame()titDf[title]=a.map(segment)

#將稱謂對應的頭銜代入,並使用One-hot編碼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" }titDf[title]=titDf[title].map(title_mapDict)titDf=pd.get_dummies(titDf[title])

船艙號這一列取出船艙號的首字母代替

full[Cabin]=full[Cabin].map(lambda c:c[0])CabinDf=pd.get_dummies(full[Cabin],prefix=Cabin)full=pd.concat([full,CabinDf],axis=1)full.drop(Cabin,axis=1,inplace=True)full.head()

看一下sibsp(同代直系親屬數)、parch(不同代直系親屬數)

由此得知家庭成員為:sibsp+parch+1(自己)

FamilyDf=pd.DataFrame()FamilyDf[Familysize]=full[Parch]+full[SibSp]+1#家庭類別:#小家庭Family_Single:家庭人數=1#中等家庭Family_Small: 2<=家庭人數<=4#大家庭Family_Large: 家庭人數>=5#if 條件為真的時候返回if前面內容,否則返回0FamilyDf[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) full=pd.concat([full,FamilyDf],axis=1)full.drop(Parch,axis=1,inplace=True)full.drop(SibSp,axis=1,inplace=True)full.head()

相關性分析

#查看生存情況(Survived)與其他變數的相關情況corrDf=full.corr()corrDf[Survived].sort_values(ascending=False)

Survived 1.000000

Mrs 0.344935

Miss 0.332795

Pclass_1 0.285904

Family_Small 0.279855

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

Cabin_F 0.057935

Royalty 0.033391

Cabin_A 0.022287

Familysize 0.016639

Cabin_G 0.016040

embarked_Q 0.003650

PassengerId -0.005007

Cabin_T -0.026456

Officer -0.031316

Age -0.070323

Family-Large -0.125147

embarked_S -0.149683

Family_Single -0.203367

Cabin_U -0.316912

Pclass_3 -0.322308

Sex -0.543351

Mr -0.549199

Name: Survived, dtype: float64

取其中具有相關的變數作為特徵:

  • 頭銜
  • 客艙等級
  • 家庭類別
  • 船票價格
  • 船艙號
  • 登船港口
  • 性別
  • 年齡

#full_X表示數據特徵full_X=pd.concat([titDf, pclass, full[Fare], CabinDf, embarked, full[Sex], FamilyDf, full[Age]],axis=1)

由於開頭將兩個數據集合併了,將訓練數據(train)作為原始數據,將其中的生存情況(Survived)作為標籤y。

sourcerow=891source_X=full_X.loc[0:sourcerow-1,:]source_y=full.loc[0:sourcerow-1,Survived]pred_X=full_X.loc[sourcerow:,:]print(原始數據行數:,source_X.shape[0])print(測試數據行數:,pred_X.shape[0])

輸出:

原始數據行數: 891

測試數據行數: 418

將原始數據以8:2的比例分割訓練數據和測試數據

模型構建:

使用Logistic回歸

#建立模型from sklearn.linear_model import LogisticRegressionmodel=LogisticRegression()#訓練數據model.fit(train_X,train_y)

LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,

intercept_scaling=1, max_iter=100, multi_class=ovr, n_jobs=1,

penalty=l2, random_state=None, solver=liblinear, tol=0.0001,

verbose=0, warm_start=False)

模型評估

#將訓練好的模型輸出到原始數據中的標籤pred_y=model.predict(pred_X)pred_y=pred_y.astype(int)Passenger_Id=full.loc[sourcerow:,PassengerId]

提交到kaggle,掌握知識不多,最終的成績不是很好。在接下來學習中繼續加強!


推薦閱讀:

一篇文章入門Python
Kaggle機器學習之泰坦尼克號生還預測
R語言實戰—02-創建數據集
大數據之數據分析精進之路:起跑
4 種最搶手的數據分析職業,你會選擇?

TAG:Python | 數據分析 | 機器學習 |