機器學習:淺談kaggle泰坦尼克號生存概率
RMS泰坦尼克號的沉沒是歷史上最臭名昭著的沉船之一。1912年4月15日,在首航期間,泰坦尼克號撞上一座冰山後沉沒,2224名乘客和機組人員中有1502人遇難。這一聳人聽聞的悲劇震撼了國際社會,並導致了更好的船舶安全條例。
數據來源:
Titanic: Machine Learning from DisasterKaggle是由聯合創始人、首席執行官安東尼·高德布盧姆(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 1308Data columns (total 12 columns):Age 1046 non-null float64
Cabin 295 non-null objectEmbarked 1307 non-null objectFare 1308 non-null float64Name 1309 non-null objectParch 1309 non-null int64PassengerId 1309 non-null int64Pclass 1309 non-null int64Sex 1309 non-null objectSibSp 1309 non-null int64Survived 891 non-null float64
Ticket 1309 non-null objectdtypes: 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.344935Miss 0.332795Pclass_1 0.285904Family_Small 0.279855Fare 0.257307Cabin_B 0.175095embarked_C 0.168240Cabin_D 0.150716Cabin_E 0.145321Cabin_C 0.114652
Pclass_2 0.093349Master 0.085221Cabin_F 0.057935Royalty 0.033391Cabin_A 0.022287Familysize 0.016639Cabin_G 0.016040embarked_Q 0.003650PassengerId -0.005007Cabin_T -0.026456
Officer -0.031316Age -0.070323Family-Large -0.125147embarked_S -0.149683Family_Single -0.203367Cabin_U -0.316912Pclass_3 -0.322308Sex -0.543351Mr -0.549199Name: 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 種最搶手的數據分析職業,你會選擇?