Kaggle入門-泰坦尼克生存概率預測
通過Kaggle上的入門項目,建立模型,預測生存概率。
1.提出問題
什麼樣的人在泰坦尼克號中更容易存活?
2.理解數據
2.1 採集數據
從kaggle下載數據
2.2 導入數據
#忽略警告提示import warningswarnings.filterwarnings(ignore)#導入處理數據包import numpy as npimport pandas as pd#導入數據#訓練數據集train=pd.read_csv(./train.csv)#測試數據集test=pd.read_csv(./test.csv)print(訓練數據集:,train.shape,測試數據集:,test.shape)rowNum_train=train.shape[0]rowNum_test=test.shape[0]print(訓練數據集行數:,rowNum_train, 測試數據集行數:,rowNum_test)#合併數據集,方便同時對兩個數據集進行清洗full=train.append(test,ignore_index=True)print(合併後的數據集:,full.shape)
2.3 查看數據集信息
#查看數據full.head()full.describe()#查看數據類型,總和full.info()
查看數據總和可以看出,數據總和有1309行。
1. 有缺失數據的數據類型列:Age(年齡),Fare(船票價格)2. 有缺失數據的字元串列:Embarked(登船港口),Cabin(船艙號),Survived(存活)3.數據清洗(Data Preparation)
3.1 數據預處理
缺失值處理
機器學習演算法為了訓練模型,要求特徵中不能有空值。下面是處理方法:
1. 如果是數值類型,用平均值取代2. 如果是分類數據,用最常見的類別取代3. 使用模型預測缺失值,例如:K-NN#處理數據類型列:Age, Fareprint(處理前:)full.info()#Age(年齡)full[Age]=full[Age].fillna(full[Age].mean())#Fare(船票價格)full[Fare]=full[Fare].fillna(full[Fare].mean())print(處理後:)full.info()#檢查數據處理是否正常full.head()處理字元串列:1. Embarked(登船港口)只缺失2條數據,用最常見的數據取代2. Cabin(船艙號)缺失1014條數據#Embarked:查看數據信息簡稱如下:出發地點:S=英國 南安普頓Southampton途徑地點1:C=法國 瑟堡市Cherbourg途徑地點2:Q=愛爾蘭 昆士敦Queestownfull[Embarked].head()#分類變數Embarked用最常見的變數填充full[Embarked].value_counts()#從計數結果來看,S類別最多,進行填充full[Embarked]=full[Embarked].fillna(S)#Cabin(船艙號):查看數據信息full[Cabin].head()#缺失數據較多,用U來填充,表示未知(Unknown)full[Cabin]=full[Cabin].fillna(U)#檢查數據集是否正常full.head()#查看缺失值處理情況,Survived(生存情況生存情況)是標籤,用於機器學習預測,不用處理full.info()
3.2 特徵提取
3.2.1 數據分類
查看數據類型,分為三種。對類別數據處理,用數值代替類別,並進行ont-hot編碼
- 數值類型:乘客編號(PassengerId),年齡(Age),船票價格(Fare),同代直系親屬人數(SibSp),不同代直系親屬人數(Parch)
- 時間序列:無
- 分類數據:
- 3.1 有直接類別:
- 乘客性別(Sex):男性male,女性female
- 登船港口(Embarked):出發地點S=英國南安普頓Southampton,途徑地點1:C=法國 瑟堡市Cherbourg,出發地點2:Q=愛爾蘭 昆士敦Queenstown
- 客艙等級(Pclass):1=1等艙,2=2等艙,3=3等艙
- 3.2 字元串類型:
- 乘客姓名(Name)
- 客艙號(Cabin)
- 船票編號(Ticket)
full.info()
3.2.1 分類數據:有直接類別
- 乘客性別(Sex): 男性male,女性female
- 登船港口(Embarked):出發地點S=英國南安普頓Southampton,途徑地點1:C=法國 瑟堡市Cherbourg,出發地點2:Q=愛爾蘭 昆士敦Queenstown
- 客艙等級(Pclass):1=1等艙,2=2等艙,3=3等艙
性別
#查看性別數據full[Sex].head()#將性別的值映射為數值:male-1,female-0sex_mapDict={male:1, female:0}#用map函數,對Series每個數據應用自定義的函數計算full[Sex]=full[Sex].map(sex_mapDict)full.head()
登船港口(Embarked)
#查看數據內容full[Embarked].head()#存放提取後的特徵embarkedDf=pd.DataFrame()#用get_dummies進行one-hot編碼,產生虛擬變數(dummy variables),前綴是embarkedembarkedDf=pd.get_dummies(full[Embarked],prefix=Embarked)embarkedDf.head()#添加one-hot產生的虛擬變數到數據集fullfull=pd.concat([full,embarkedDf],axis=1)full.drop(Embarked,axis=1,inplace=True)full.head()
客艙等級
#存放提取後的特徵pclassDf=pd.DataFrame()#使用get_dummies進行Ont-hot編碼,前綴是PclasspclassDf=pd.get_dummies(full[Pclass],prefix=Pclass)pclassDf.head()#添加one-hot編碼產生的虛擬變數到數據集fullfull=pd.concat([full,pclassDf],axis=1)#刪除客艙等級(Pclass)列full.drop(Pclass,axis=1,inplace=True)full.head()
3.2.1 分類數據:字元串類型
- 乘客姓名(Name)
- 客艙號(Cabin)
- 船票編號(Ticket)
從姓名中提取頭銜
#可以把乘客的頭銜提取出來形成一個新的變數,查看內容full[Name].head()#以逗號為分隔符,利用split進行分列name1=Braund, Mr. Owen Harrisstr1=name1.split(,)[1]#以圓點進行拆分str2=str1.split(.)[0]#用strip移除字元串頭尾指定的字元(默認是空格)str3=str2.strip()str3#定義函數,從姓名中提取頭銜def getTitle(name): str1=name.split(,)[1] str2=str1.split(.)[0] str3=str2.strip() return str3#存放提取後的特徵titleDf=pd.DataFrame()#map函數:對Series每個數據應用自定義函數計算titleDf[Title]=full[Name].map(getTitle)titleDf.head()定義以下幾種頭銜類別:Officer政府官員Royalty王室(皇室)Mr已婚男士Mrs已婚婦女Miss年輕未婚女子Master有技能的人/教師#姓名中頭銜字元串與定義頭銜類別的映射關係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" }#map函數titleDf[Title]=titleDf[Title].map(title_mapDict)#get_dummies進行One-hot編碼titleDf=pd.get_dummies(titleDf[Title])titleDf.head()#添加one-hot編碼產生的虛擬變數到數據集fullfull=pd.concat([full,titleDf],axis=1)#刪除姓名列full.drop(Name,axis=1,inplace=True)full.head()
從客艙號中提取客艙類別
#匿名函數:lambda 參數1,參數2:函數體或表達式#定義匿名函數:對兩個數相加sum=lambda a,b: a+b#調用sum函數print(相加後,sum(10,20))#客艙號的首字母是客艙的類別,查看內容full[Cabin].head()#存放客艙號信息cabinDf=pd.DataFrame()full[Cabin]=full[Cabin].map(lambda c:c[0])#one hot 編碼cabinDf=pd.get_dummies(full[Cabin],prefix=Cabin)cabinDf.head()#將one-hot產生的虛擬變數添加到數據集fullfull=pd.concat([full,cabinDf],axis=1)#刪除客艙號列full.drop(Cabin,axis=1,inplace=True)full.head()
建立家庭人數和家庭類別
#存放家庭信息familyDf=pd.DataFrame()#家庭人數=同代直系親屬數(Parch)+不同代直系親屬數(SibSp)+乘客自己familyDf[FamilySize]=full[Parch]+full[SibSp]+1家庭類別:小家庭Family_Single:家庭人數=1中等家庭Family_Small: 2<=家庭人數<=4大家庭Family_Large: 家庭人數>=5#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)familyDf.head()#添加One-hot編碼產生的虛擬變數到數據集fullfull=pd.concat([full,familyDf],axis=1)full.head()print(到目前為至的特徵值:,full.shape)
3.3 特徵選擇
相關係數法:計算各特徵的相關係數
#相關性矩陣corrDf=full.corr()corrDf#查看各個特徵與生成情況(Survived的相關係數corrDf[Survived].sort_values(ascending=False)
根據各個特徵與生成情況(Survived)的相關係數大小,選擇以下特徵作為模型的輸入:
頭銜(前面所在的數據集titleDf)、客艙等級(pclassDf)、家庭大小(familyDf)、船票價格(Fare)、船艙號(cabinDf)、登船港口(embarkedDf)、性別(Sex)
#特徵選擇full_X=pd.concat([titleDf,pclassDf,familyDf,full[Fare],cabinDf,embarkedDf,full[Sex]],axis=1)full_X.head()
4. 構建模型
4.1 建立訓練數據集和測試數據集
#原始數據集有891行sourceRow=891#因為行號從0開始,需要減去1#原始數據集:特徵source_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])from sklearn.cross_validation import train_test_split#建立模型用的訓練數據集和測試數據集train_X,test_X,train_y,test_y=train_test_split(source_X,source_y,train_size=.8)#輸出數據集大小print(原始數據集特徵:,source_X.shape, 訓練數據集特徵:,train_X.shape, 測試數據集特徵,test_X.shape)print(原始數據集標籤:,source_y.shape, 訓練數據集標籤:,train_y.shape, 測試數據集標籤:,test_y.shape)#原始數據查看source_y.head()
4.2 選擇機器學習演算法
選擇機器學習演算法,用於訓練模型。新手可以從邏輯回歸開始。
#第1步:導入演算法from sklearn.linear_model import LogisticRegression#第2步:創建模型:邏輯回歸model=LogisticRegression()
4.3 訓練模型
#第3步:訓練模型model.fit(train_X,train_y)
5. 評估模型
#分類問題,score得到的是模型的正確率model.score(test_X,test_y)
6. 方案實施
6.1 得到預測結果上傳Kaggle
#對預測數據集中的生存情況進行預測pred_Y=model.predict(pred_X)#轉把浮點數轉換成整型Pred_Y=pred_Y.astype(int)#乘客IDpassenger_id=full.loc[sourceRow:,PassengerId]#數據框:乘客id,預測生存情況的值predDf=pd.DataFrame({PassengerId:passenger_id, Survived:pred_Y})predDf.shapepredDf.head()#保存結果predDf.to_csv(titanic_pred.csv,index=False)
推薦閱讀:
※關於專欄文章說明
※機器學習基石筆記12:非線性轉換
※我的人工智慧學習筆記(一)
※關於不平衡數據集以及代價敏感學習的探討
※機器學習入門:邏輯回歸案例