kaggle-(總結)泰坦尼克生存預測-R-隨機森林-TOP7%
參考文章:
Kaggle 入門:探索泰坦尼克號事故倖存情況分析
Kaggle----泰坦尼克的沉沒(2.0)
隨機森林——實現Kaggle排名Top2%的利器
前言
關於三大kaggle入門項目之一的泰坦尼克生存預測,我相信各位有關注知乎數據分析話題的朋友應該一點都不陌生,所以我在一開始就列出了三篇參考文章,也能看到這三篇參考文章大同小異,在此僅僅只是做個總結提煉一些步驟、代碼、要點,給各位和我一樣入門學習的朋友些許參考意見,我認為如果不能把這些代碼的思路消化理解並作為自己的知識儲備,那麼即使我的Submission能到TOP1,那也是沒有任何意義的,也希望各位指出不足和紕漏,感謝點贊關注收藏,謝謝!ok,開始。
正文
第一,我們要做什麼?
這個項目給出了train和test兩個數據集,我們需要通過對train的數據信息進行分析並建立模型,然後對test數據進行生存預測:
其中train數據集中有891條數據,test數據集中包含了418條數據,當然,test數據集中不包含Survived情況,這也正是我們要進行預測的,所以先關注train的欄位內容:
- PassengerId 整型變數,標識乘客的ID。
- Survived 整型變數,標識該乘客是否倖存。0表示遇難,1表示倖存。
- Pclass 整型變數,標識乘客的社會-經濟狀態,1代表Upper,2代表Middle,3代表Lower
- Name 字元型變數,除包含姓和名以外,還包含Mr. Mrs. Dr.這樣的具有西方文化特點的信息
- Sex 字元型變數,標識乘客性別。
- Age 整型變數,標識乘客年齡,有缺失值
- SibSp 整型變數,代表兄弟姐妹及配偶的個數。其中Sib代表Sibling也即兄弟姐妹,Sp代表Spouse也即配偶
- Parch 整型變數,代表父母或子女的個數。其中Par代表Parent也即父母,Ch代表Child也即子女
- Ticket 字元型變數,代表乘客的船票號
- Fare 數值型,代表乘客的船票價
- Cabin 字元型,代表乘客所在的艙位,有缺失值
- Embarked 字元型,代表乘客登船口岸
第二,載入包,導入數據,觀測變數
#載入包
library(data.table)library(dplyr) library(mice) library(randomForest) library(party)library(rpart)
#導入數據
train <- fread("train.csv")test <- fread("test.csv")full<-bind_rows(train,test)
ok,一個個來看看變數對生存是否有意義:
- PassengerId ,標識乘客的ID,遞增變數,對預測無幫助,OK,這個很好理解
- Survived,當然,所求就是test中的它
- Pclass,乘客等級,主觀來說,這個是有意義的
- Name,姓名,一開始的認知肯定是對是否生存沒有影響,總不能說你姓張,我姓李,姓李的就能活下來對吧,但是,這個姓名包含了Title,這個就有意義了,保護女人和孩子,讓他們先走對吧
- Sex,主觀來說,性別對是否生存肯定是存在一定意義的
- Age,主觀判斷,有意義,但是有很多缺失值
- SibSp、Parch,兄弟、配偶、父母、子女數量,主觀判斷有意義
- Ticket 船票號其中有重複的,意味著票號相同的有可能是一家人,有意義
- Fare、Cabin、Embarked類似於Pclass,有意義,但是Cabin包含了很多空白缺失值,所以不予分析
第三,增加變數
根據以上,可以增加些變數:
1.頭銜Title
- 根據姓名得出頭銜Title
full$Title <- gsub((.*, )|(\..*), , full$Name)
這裡用到了gsub函數加上正則表達式匹配字元串,需要好好理解貪婪匹配以及轉義
- 整理Title
table(full$Title)
使用頻數分布函數看看各個Title,可以看到有很多Title人數很少,有些Title意思重複
#把少數量的頭銜選出來,意思一樣的頭銜整合,少數量的頭銜合併
rare_title <- c(Dona, Lady, the Countess,Capt, Col, Don, Dr, Major, Rev, Sir, Jonkheer)full$Title[full$Title == Mlle] <- Miss full$Title[full$Title == Ms] <- Missfull$Title[full$Title == Mme] <- Mrs full$Title[full$Title %in% rare_title] <- Rare Title
2.根據SibSp、Parch,可以增加家庭人數Fsize
#記得加上自己full$Fsize <- full$SibSp + full$Parch + 1
3.根據2中的Fsize可以把家庭規模劃分一下,建立FamilyID變數,具體劃分的尺度、代碼可以參考其它文章
4.根據票號可以增加TicketCount變數,目的是分組出票是單獨票號還是共享票號
#通過票號進行分組,保存為單獨的數據框fulltfullt <- full %>% group_by(Ticket) %>% count()table(fullt$n)fullt <- as.data.frame(fullt)
說明:1309個人中,713種票號是不重複的,132種票號出現了2次,佔264人,以此類推……
#對full數據集的每一行進行操作,對應Ticket,把fullt第二列賦值給TicketCount ,即打上標識full$TicketCount <- apply(full, 1, function(x) fullt[which(fullt[Ticket] == x[Ticket]), 2])#根據標識不為1的賦值為share,否則賦值為uniquefull$TicketCount[full$TicketCount != 1] <-sharefull$TicketCount[full$TicketCount == 1] <-unique
第四,填補缺失值、空白值(主要填補的為Age、Fare、Embarked)
- 觀測缺失值、空白值
colSums(sapply(full,is.na)) #按列查看缺失值sapply(full,function(x)sum(x=="")) #按列查看空白值
- 先處理較少的空白值和缺失值,即含一個NA的Fare和兩個空白值的Embarked
找到這個Fare為NA的行號
which(is.na(full$Fare)) #顯示1044
通過full[1044,]觀察信息,可得到他的Pclass和Embarked,匯總分析並賦值,具體參考其它文章
full[1044,]$Fare <- 8.05
Embarked也是一樣的方法,得到基本信息,找到大類,匯總分析並賦值,具體參考其它文章
full$Embarked[c(62, 830)] <- S
- Age插補缺失值
這個是非常重要的,可以通過mice函數或者rpart函數進行插補
mice函數插補:
newdata <- bind_rows(train,test)imp <- mice(newdata[,-2],m=5,method = rf,maxit = 500,seed = 5514)miceout <- complete(imp)full$Age <- miceout$Age
rpart函數插補:
Agefit <- rpart(Age ~ Pclass + Sex + SibSp + Parch + Fare + Embarked + Title + Fsize,data=full[!is.na(full$Age),], method="anova")full$Age[is.na(full$Age)] <- predict(Agefit, full[is.na(full$Age),])
至此,該補該加工作已經結束
第五,建立train的模型
建立模型分為兩個步驟:
步驟一,篩選出對生存有影響的有關變數,這裡大家可以參考其它文章,主要思路就是通過ggplot2可視化探尋,IV與WOE值探尋等思路進行判斷
最後選入的變數為:
Pclass +Sex + Age + Fare + Embarked + Title + Fsize + FamilyID + TicketCount
其實也可以簡單理解如下:
name不選入,因為我們已經提取了其中有意義的Title,
SibSp、Parch我們進行重構成Fsize、FamilyID
ticket重構成TicketCount,Cabin空白缺失值太多不予考慮
步驟二,建立train的隨機森林模型,預測test,寫出結果
先把處理好的數據再分開
train1 <- full[1:891,]test1 <- full[892:1309,]
兩種方法建立train1的隨機森林模型:
隨機森林是一種多功能的機器學習演算法,能夠執行回歸和分類的任務,有很多優點,也是剛開始學習接觸,在此不予贅述,大家可以在參考文章中看到很多介紹內容,下面的代碼只是站在了巨人的肩膀上進行應用嘗試
- randomForest函數
#建模型model <- randomForest(as.factor(Survived) ~ Pclass + Sex + Age + Fare + Embarked + Title + Fsize + FamilyID + TicketCount, data = train1, ntree=2000)#給預測prediction <-predict(model,test1)#輸出結果solution <- data.frame(PassengerID = test1$PassengerId, Survived = prediction)write.csv(solution, file = Solution.csv, row.names = F)
- cforest函數
#建模型fit <- cforest(as.factor(Survived) ~ Pclass +Sex + Age + Fare + Embarked + Title + Fsize + FamilyID + TicketCount,data = train1, controls=cforest_unbiased(ntree=2500, mtry=3))#給預測Prediction <- predict(fit, test1, OOB=TRUE, type = "response")#輸出結果submit <- data.frame(PassengerId = test$PassengerId, Survived = Prediction)write.csv(submit, file = "solution.csv", row.names = FALSE)
第六,在kaggle中上傳submission,看看預測準確率,可以在個人主頁中看到自己的TOP排名
寫在最後
本文沒有進行一些欄位與生存關係的可視化展示,也省略了很多分析步驟,只是對重點部分及分析步驟進行總結,寫給大家的同時,自己也在努力消化並理解思路和代碼並化為己用,有什麼問題大家可以多閱讀參考文章或者私信討論,感謝點贊關注,謝謝!
推薦閱讀:
※R中的列表(list)和數據框(data.frame)有什麼區別?
※R語言分層抽樣的函數是什麼?
※R語言相關圖書?
※如何高效的在R里寫出一個循環?