我的Kaggle入門:關於Titanic倖存者的預測
分析數據源:Kaggle中的數據集Titanic Machine Learning from Disaster。
鏈接:https://www.kaggle.com/c/titanic
分析目的:根據訓練集預測部分乘客在沉船事件中是否會存活?
簡介:給定了兩個數據集,分別為訓練集(891條記錄,12個變數)和測試集(418條記錄,11個變數),測試集中缺少一個目標變數(是否存活),這需要我們去預測。通過分析訓練集構建一個機器學習模型,再將該模型用於測試集,預測測試集中的乘客是否存活。在kaggle上對比模型得到的數據與真實數據,得到該模型正確預測的比例。
1、導入數據
①導入數據,用head()函數查看數據前幾行
> install.packages("readr")
> library("readr")n> train <- read.csv("train.csv")n> test <-read.csv("test.csv")n> head(train) #查看數據前幾行n
②查看變數名稱
> names(train) #查看變數名n> names(test) #查看變數名n
2、數據預處理
①合併訓練集與測試集
為了方便數據的處理,先將訓練集與數據集合併,由於測試集缺少Survived列,需先給test數據集添加一列Survived,再用rbind()函數進行合併。
> test$Survived <- NA #在test中添加Survived列n> combi <- rbind(train,test) #合併數據集n> nrow(combi) #查看總行數n
②轉換數據類型
> str(combi) #查看數據類型n
其中的Survived、Pclass屬於分類變數,應轉化為因子類型。Name應轉化為字元串類型。
> combi$Survived <- as.factor(combi$Survived)n> combi$Pclass <- as.factor(combi$Pclass) n> combi$Name <-as.character(combi$Name)n
3、對缺失值的處理
①查看缺失值
> sapply(combi,function(x) sum(is.na(x))) n
Survived列有418個缺失值
Age列有263個缺失值
Fare列有1個缺失值
②處理缺失值
1)Survived列418個缺失值來源於test數據集,是需要我們預測的,不用處理
2)Age缺失值較多,需要通過其他的變數來預測,暫時不進行缺失值的填補。
3)Fare列只有1個缺失值,屬於數值型數據,可以利用中位數進行填補,在計算中位數時要先把缺失值去掉
> combi$Fare[is.na(combi$Fare)] <- median(combi$Fare,na.rm = TRUE)n
4、探索各變數與Survived的關係
> install.packages("ggplot2")n> library("ggplot2")n
①Pclass的影響
> ggplot(data = combi[(1:891),],mapping = aes(x=Pclass,y=..count..,fill=Survived))+n+ geom_bar(stat = "count",position = "dodge")+n+ xlab("Pclass")+n+ ylab("Count")+n+ ggtitle("How Pclass impacts survival")+n+ geom_text(stat = "count",aes(label=..count..),position = position_dodge(width = 1),vjust=-.6)n
從上圖可見,Pclass=1的存活率最高,Pclass=2的存活率次之,Pclass=3的存活率最低。
②Name的影響
鑒於Name的重複度比較低,通過提取特徵值Title來進行分類,並將人數較少的類重新進行定義:
> combi$Title <- sapply(combi$Name, FUN = function(x) {strsplit(x, split = [,.])[[1]][2]})n> combi$Title <- sub( , , combi$Title)n> table(combi$Title)n> combi$Title[combi$Title %in% c(Mme, Mlle)] <- Mllen> combi$Title[combi$Title %in% c(Capt, Don, Major, Sir)] <- Sirn> combi$Title[combi$Title %in% c(Dona, Lady, the Countess, Jonkheer)] <- Ladyn> combi$Title <- factor(combi$Title)nn> ggplot(data = combi[1:nrow(train),],mapping = aes(x=Title,y=..count..,fill=Survived))+n+ geom_bar(stat = "count",position = "stack")+n+ xlab("Title")+n+ ylab("Count")+n+ ggtitle("How Title impacts Survival")+n+ geom_text(stat = "Count",aes(label=..count..),position = position_stack(vjust = 0.5))n
從上圖可見,Title為Mr的乘客存活率非常低,而Title為Miss和Mrs的乘客存活率非常高。
③Sex的影響
ggplot(data = combi[(1:891),],mapping = aes(x=Sex,y=..count..,fill=Survived))+n+ geom_bar(stat = "count",position = "dodge")+n+ xlab("Sex")+n+ ylab("Count")+n+ ggtitle("How Sex impacts Survival")+n+ geom_text(stat = "count",aes(label=..count..),position = position_dodge(width = 1),vjust=-.5)n
從上圖可見,女性的存活率非常高,而男性的存活率非常低。
④Age的影響(用的是train數據)
> ggplot(data = combi[(!is.na(combi$Age)) & row(as.matrix(combi[,"Age"]))<=891,],aes(x=Age,color=Survived))+n+geom_line(aes(label=..count..),stat = "bin",binwidth_=5,na.rm = TRUE)+n+labs(title="How Age impacts Survival",x="Age",y="Count",fill="Survived")n
從上圖可見,未成年人的倖存率要遠遠高於青壯年。
⑤SibSp的影響
> ggplot(data = combi[1:nrow(train),],mapping = aes(x=SibSp,y=..count..,fill=Survived))+n+ geom_bar(stat = "count",position = "dodge")+n+ xlab("SibSp")+n+ ylab("Count")+n+ ggtitle("How SibSp impacts Survival")+n+ geom_text(stat = "count",aes(label=..count..),position = position_dodge(width = 1),vjust=-.5)n
從上圖見,當配偶或兄弟姐妹的人數為1或2的乘客倖存率很高。
⑥Parch的影響
> ggplot(data = combi[1:nrow(train),],mapping = aes(x=Parch,y=..count..,fill=Survived))+n+ geom_bar(stat = "count",position = "dodge")+n+ xlab("Parch")+n+ ylab("Count")+n+ ggtitle("How Parch impacts Survival")+n+ geom_text(stat = "count",aes(label=..count..),position = position_dodge(width = 1),vjust=-.5)n
可見,Parch為1到3的乘客倖存率最高。
⑦FamilySize的影響
基於⑤、⑥兩點,我們假設家庭規模對生存率會有一定程度地影響。故加入新的變數FamilySize(家庭總人數)來進行研究。
> combi$FamilySize <- combi$Parch + combi$SibSp + 1n> ggplot(data = combi[1:nrow(train),],mapping = aes(x=FamilySize,y=..count..,fill=Survived))+n+ geom_bar(stat = "count",position = "dodge")+n+ xlab("FamilySize")+n+ ylab("Count")+n+ ggtitle("How FamilySize impacts Survival")+n+ geom_text(stat = "count",aes(label=..count..),position = position_dodge(width = 1),vjust=-.5)n
從上圖可見,2-4口人的家庭生存情況是最好的,過大或過小家庭規模生存率都不好。
⑧Fare的影響
> ggplot(data = combi[(!is.na(combi$Fare)) & row(as.matrix(combi[,"Fare"]))<=891,],aes(x=Fare,color=Survived))+n+ geom_line(aes(label=..count..),stat = "bin",binwidth_=5,na.rm = TRUE)+n+ labs(title="How Fare impacts Survival",x="Fare",y="Count",fill="Survived")n
從上圖可見,票價越高,越容易存活。
⑨Embarked的影響
> ggplot(data = combi[1:nrow(train),],mapping = aes(x=Embarked,y=..count..,fill=Survived))+n+ geom_bar(stat = "count",position = "dodge")+n+ xlab("Embarked")+n+ ylab("Count")+n+ ggtitle("How Embarked impacts Survival")+n+ geom_text(stat = "count",aes(label=..count..),position = position_dodge(width = 1),vjust=-.5)n
從上圖可見,Embarked=C的存活率最高,Embarked=S的死亡率非常高。
5、利用決策樹對Age的缺失值進行預測填補
> install.packages("rpart")n> library("rpart")n> Age.model <- rpart(Age~Pclass+Sex+SibSp+Parch+Fare+Embarked+Title+FamilySize,data = combi[!is.na(combi$Age),],method = "anova")n> combi$Age[is.na(combi$Age)] <- predict(Age.model,combi[is.na(combi$Age),])n
知識點:我們可以用hist()函數查看年齡的分布情況:
> hist(combi$Age[!is.na(combi$Age)],freq = F,main = "Age Distribution")n
6、模型設定與預測
①將訓練集與測試集分開
> train <- combi[1:891,]n> test <- combi[892:1309,]n
②建立模型--決策樹模型
> install.packages("rpart.plot")n> library("rpart.plot")n> titanic_tree <-rpart(Survived~Pclass+Title+Sex+Age+SibSp+Parch+FamilySize+Fare+Embarked,data=new_train,method="class")n> prediction<-predict(titanic_tree,test,type="class")n> submit <-data.frame(PassengerId=test$PassengerId,Survived=prediction)n> write.csv(submit, file=D:/submit.csv,row.names = FALSE)n> rpart.plot(titanic_tree)#畫出決策樹n
總結和思考:
(1)這次泰坦尼克生存預測還是照貓畫虎地模仿別人方法進行,變數處理和預測方法還有很多需要改進的地方。在完成寫代碼預測後,自己對R的建模等實踐有了初步的了解。結合書本知識、前面幾期的簡單數據處理和複雜數據處理學習,感覺對R語言的基本應用有了全面的了解和認識。
(2)在整個分析預測過程中,關於演算法累的知識極為匱乏。後續需加強這方面的學習。
(3)本次預測參考了幾篇自己認為很有價值的文章,很多思路和代碼也是借鑒別人而來的,後期自己要繼續學習,不斷改善,爭取能自己獨立完成。
推薦閱讀:
※數據分析師的思維是如何練出來的?| HackLife #10
※菜鳥數據科學入門01 - 工具包概略
※MySQL學習筆記匯總
※而立之人的數據分析學習之路
TAG:数据分析 |