【学习笔记】kaggle案例之泰坦尼克号(基于R)

kaggle案例之泰坦尼克号(基于R)

泰坦尼克号案例

泰坦尼克号数据集为1912年泰坦尼克号撞击冰山沉没事件中一些乘客和船员的个人信息及是否幸存的状况。可利用该数据进行分析,挖掘数据中有用的信息。
<本文是学习《R语言统计分析与机器学习》后的学习笔记>

数据预处理

数据概况:
数据概况
该数据集中,训练数据集包含891个样本,共有12个特征,测试数据集包含418个样本,11个特征。两个数据集的原始数据中包含很多缺失值,或不能直接用于分析的信息。故我们需要对其进行预处理,便于挖掘分析。

  1. 导入需要的包 ,导入需要的包;
library(readr)
library(VIM)
library(caret)
library(rpart)
library(rpart.plot)
library(Metrics)
library(ROCR)
library(readxl)
library(stringr)
library(ggplot2)
  1. 计算幸存者和遇难者的数量 ,将训练集和测试集数据组合在一起,方便对数据特征的统一处理;
## 读取训练集和测试集
Ttrain <- read_csv("C:/Mathmodel/Titanic train.csv")
Ttest <- read_csv("C:/Mathmodel/Titanic test.csv")
##查看训练集和测试集的数据形式
dim(Ttrain)
colnames(Ttrain)
dim(Ttest)
colnames(Ttest)
## 组合数据(其中Ttrain[,-2]指删除训练集Ttrain第二列数据
Alldata <- rbind.data.frame(Ttrain[,-2],Ttest)
##上面这样就是按行将两个数据集拼接在一起
summary(Alldata)#可利用summary观察数据情况
Survived <- Ttrain$Survived
table(Survived)

运行结果

> dim(Ttrain)#训练集维度
 891  12
> colnames(Ttrain)#指标名称
  "PassengerId" "Survived"    "Pclass"      "Name"        "Sex"         "Age"         "SibSp"       "Parch"       "Ticket"      "Fare"        "Cabin"       "Embarked"   
> dim(Ttest)#测试集维度
 418  11
> colnames(Ttest)#指标名称
 "PassengerId" "Pclass"      "Name"        "Sex"         "Age"         "SibSp"       "Parch"       "Ticket"      "Fare"        "Cabin"       "Embarked"   
##可发现训练集和测试集之间,测试集没有指标Survived
> Survived <- Ttrain$Survived
> table(Survived)
Survived
  0   1 
549 342 

利用summary观察数据情况结果如下

> summary(Alldata)
  PassengerId       Pclass          Name               Sex           
 Min.   :   1   Min.   :1.000   Length:1309        Length:1309       
 1st Qu.: 328   1st Qu.:2.000   Class :character   Class :character  
 Median : 655   Median :3.000   Mode  :character   Mode  :character  
 Mean   : 655   Mean   :2.295                                        
 3rd Qu.: 982   3rd Qu.:3.000                                        
 Max.   :1309   Max.   :3.000                                        
                                                                     
      Age            SibSp            Parch          Ticket         
 Min.   : 0.17   Min.   :0.0000   Min.   :0.000   Length:1309       
 1st Qu.:21.00   1st Qu.:0.0000   1st Qu.:0.000   Class :character  
 Median :28.00   Median :0.0000   Median :0.000   Mode  :character  
 Mean   :29.88   Mean   :0.4989   Mean   :0.385                     
 3rd Qu.:39.00   3rd Qu.:1.0000   3rd Qu.:0.000                     
 Max.   :80.00   Max.   :8.0000   Max.   :9.000                     
 NA's   :263                                                        
      Fare            Cabin             Embarked        
 Min.   :  0.000   Length:1309        Length:1309       
 1st Qu.:  7.896   Class :character   Class :character  
 Median : 14.454   Mode  :character   Mode  :character  
 Mean   : 33.295                                        
 3rd Qu.: 31.275                                        
 Max.   :512.329                                        
 NA's   :1         

从输出结果我们可看出:训练数据集中存活下来的人数有342人,遇难人数有549人。
数据中的特征有:
乘客ID(passengerId),是否获救(Survived),乘客分类(Pclass),姓名(Name),性别(Sex),年龄(Age),有多少兄弟姐们/配偶同船(Parch),票号(Ticket),票价(Fare),客舱号(Cabin),出发港口(Embarked)。

  1. 针对合并后的数据集首先需要分析数据的缺失值情况,可利用VIM包中的aggr()函数
aggr(Alldata)

得到缺失值分布图,结果如下
缺失值分布图
由上图可发现,Cabin变量的缺失值已经超过70%,所以该变量可以直接剔除,Age的缺失值也较多,且Fare和Embarked变量也有较少部分的缺失值。

  1. 对数据进行缺失值处理和特征筛选
## Cabin缺失值太多,可以直接剔除
Alldata$Cabin <- NULL
## 船票和ID具有识别性所以需要剔除
Alldata$PassengerId <- NULL
Alldata$Ticket <- NULL

其中Cabin变量因为缺失值过多,直接删除更好,而PassengerID和Ticket都可以直接对应到乘客个体,所以需要剔除。
对于其他的具有缺失值的变量,使用简单的缺失值填补方法。`


## 年龄变量的缺失值可以使用中位数来填补
Alldata$Age[is.na(Alldata$Age)] <- median(Alldata$Age,na.rm = TRUE)
## fare变量的缺失值可以使用均值来填补
Alldata$Fare[is.na(Alldata$Fare)] <- mean(Alldata$Fare,na.rm = TRUE)
## Embarked变量的缺失值,可以使用众数来填补
Embarkedmod <- names(sort(table(Alldata$Embarked),decreasing = T)[1])
Alldata$Embarked[is.na(Alldata$Embarked)] <- Embarkedmod

上面程序分别使用了中位数,平均值,众数来填补这三个变量的特征。

  1. 分析数据中的Name变量,该变量通常能体现样本的社会地位,年龄阶段,性别等信息;
## 获取新的特征,提取name变量中的特征
newname <- str_split(Alldata$Name," ")
newname <- sapply(newname, function(x) x[2])
sort(table(newname),decreasing = T)
> sort(table(newname),decreasing = T)
newname
         Mr.        Miss.         Mrs.      Master.          Dr.         Rev. 
         736          256          191           59            8            8 
           y         Col.      Planke,    Billiard,        Impe,       Carlo, 
           8            4            4            3            3            2 
     Gordon,       Major. Messemaeker,        Mlle.          Ms.       Brito, 
           2            2            2            2            2            1 
       Capt.    Cruyssen,          der         Don.    Jonkheer.      Khalil, 
           1            1            1            1            1            1 
  Melkebeke,         Mme.      Mulder,   Palmquist,  Pelsmaeker,      Shawah, 
           1            1            1            1            1            1 
      Steen,          the       Velde,       Walle, 
           1            1            1            1 

针对Name变量,因为名称中主要包含的称谓为Mr,Miss,Mrs,Master等,所以可将该特征转化为新的特征,即保留Mr,Miss,Mrs,Master四种称呼,其余使用other代替。

## 名字设置为 Mr.  Miss.  Mrs. Master. ,其余的使用other代替
newnamepart <- c("Mr.","Miss.","Mrs.","Master.")
newname[!(newname %in% newnamepart)] <- "other"
Alldata$Name <- as.factor(newname)
Alldata$Sex <- as.factor(Alldata$Sex)
Alldata$Embarked <- as.factor(Alldata$Embarked)
summary(Alldata)
str(Alldata)

结果如下:

> summary(Alldata)
     Pclass           Name         Sex           Age            SibSp       
 Min.   :1.000   Master.: 59   female:466   Min.   : 0.17   Min.   :0.0000  
 1st Qu.:2.000   Miss.  :256   male  :843   1st Qu.:22.00   1st Qu.:0.0000  
 Median :3.000   Mr.    :736                Median :28.00   Median :0.0000  
 Mean   :2.295   Mrs.   :191                Mean   :29.50   Mean   :0.4989  
 3rd Qu.:3.000   other  : 67                3rd Qu.:35.00   3rd Qu.:1.0000  
 Max.   :3.000                              Max.   :80.00   Max.   :8.0000  
     Parch            Fare         Embarked
 Min.   :0.000   Min.   :  0.000   C:270   
 1st Qu.:0.000   1st Qu.:  7.896   Q:123   
 Median :0.000   Median : 14.454   S:916   
 Mean   :0.385   Mean   : 33.295           
 3rd Qu.:0.000   3rd Qu.: 31.275           
 Max.   :9.000   Max.   :512.329

此时Alldata数据形式,已转化为因子变量

> str(Alldata)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame':	1309 obs. of  8 variables:
 $ Pclass  : num  3 1 3 1 3 3 1 3 3 2 ...
 $ Name    : Factor w/ 5 levels "Master.","Miss.",..: 3 4 2 4 3 3 3 1 4 4 ...
 $ Sex     : Factor w/ 2 levels "female","male": 2 1 1 1 2 2 2 2 1 1 ...
 $ Age     : num  22 38 26 35 35 28 54 2 27 14 ...
 $ SibSp   : num  1 1 0 1 0 0 0 3 0 1 ...
 $ Parch   : num  0 0 0 0 0 0 0 1 2 0 ...
 $ Fare    : num  7.25 71.28 7.92 53.1 8.05 ...
 $ Embarked: Factor w/ 3 levels "C","Q","S": 3 1 3 3 3 2 3 3 3 1 ...

上面的程序在处理好Name特征后,将Name,Sex,Embarked等特征转换为因子变量。最终数据集中就有3个因子变量和5个数值变量。

  1. 将处理好的训练数据和测试数据分开
## 与处理好的训练数据和测试数据分开
Ttrainp <- Alldata[1:nrow(Ttrain),]
Ttrainp$Survived <- Survived
Ttestp <- Alldata[(nrow(Ttrain)+1):nrow(Alldata),]
str(Ttrainp)
write.csv(Ttrainp,"data/chap9/Titanic_clean.csv",row.names = F)

上面的程序是将处理好的数据重新切分为训练数据集和测试数据集,并将新训练数据集写入csv文件。

决策树模型建立

  1. 数据集切分,将训练数据集Ttrainp再划分为两个部分,其中80%作为训练集,剩下的作为测试集,便于验证模型的效果。
## 切分训练数据集为训练集和测试集,70%训练
set.seed(123)
CDP <- createDataPartition(Ttrainp$Survived,p = 0.8)
#createDataPartition()就是数据划分函数
train_data <- Ttrainp[CDP$Resample1,]
test_data <- Ttrainp[-CDP$Resample1,]
  1. 建立决策树分类器利用rpart()函数对其建立决策树模型
mod1 <- rpart(Survived~.,data =train_data,method="class",cp = 0.000001)#利用决策树分类器建立决策树模型
summary(mod1)
## 看变量重要性
mod1$variable.importance
#cp是每次分割对应的复杂度系数
mod1$cp
## plot cross-validation results
plotcp(mod1)

运行结果如下

> ## 看变量重要性
> mod1$variable.importance
     Name       Sex      Fare       Age     Parch    Pclass     SibSp  Embarked 
111.91631  89.02461  61.63420  46.05885  38.32346  36.69987  30.46093   9.64527 
> #cp是每次分割对应的复杂度系数
> mod1$cp
           CP nsplit rel error    xerror       xstd
1 0.450549451      0 1.0000000 1.0000000 0.04754450
2 0.051282051      1 0.5494505 0.5604396 0.04015432
3 0.014652015      3 0.4468864 0.4615385 0.03730757
4 0.010989011      4 0.4322344 0.4798535 0.03787823
5 0.007326007      6 0.4102564 0.5091575 0.03874859
6 0.003663004     12 0.3589744 0.4835165 0.03798985
7 0.000001000     15 0.3479853 0.4798535 0.03787823

plot cross-validation results
利用rpart.plot()函数将决策树可视化

rpart.plot(mod1, type = 2,extra="auto", under=TRUE, 
           fallen.leaves = FALSE,cex=0.7, main="决策树")

j决策树结果可视化
可发现根节点为Name变量,而且如果Name=Mr或者Other,则更倾向于划分为遇难的叶子节点。说明有更多的男性会将危险留给自己,优先让发女性和儿童逃离危险。

3.使用测试集来验证模型的预测精度
先对模型进行预测,由于得到的结果是幸存和遇难的概率,我们需要将幸存概率大于0.5的归类于幸存,小于0.5的归类于遇难,便于后面的统计分析。

pre_train <- predict(mod1,train_data,type = "prob")
pre_train2<-as.factor(as.vector(ifelse(pre_train[,2]>0.5,1,0)))
pre_test <- predict(mod1,test_data)
pre_test2<-as.factor(as.vector(ifelse(pre_test[,2]>0.5,1,0)))

此时的数据情况如下:

#pre_train代表利用模型预测出来的值,但是由于是结果概率,故需要变换。
> print(pre_train)
             0          1
1   0.05882353 0.94117647
2   0.05882353 0.94117647
3   0.89085546 0.10914454
4   0.89085546 0.10914454
5   0.07692308 0.92307692
#pre_train2即为重新处理化为0,1之后的变量,0代表遇难
> print(pre_train2)
  [1] 1 1 0 0 1 0 1 1 0 0 1 0 0 1 0 1 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 1 0
 [38] 1 0 0 1 1 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 0 1 0 0

此时再计算准确度

sprintf("决策树模型在训练集精度为:%f",accuracy(train_data$Survived,pre_train2))
sprintf("决策树模型在测试集精度为:%f",accuracy(test_data$Survived,pre_test2))
## 计算混淆矩阵和模型的精度
cfm <- confusionMatrix(pre_test2,as.factor(test_data$Survived))
cfm$table

结果如下:

> sprintf("决策树模型在训练集精度为:%f",accuracy(train_data$Survived,pre_train2))
[1] "决策树模型在训练集精度为:0.866760"
> sprintf("决策树模型在测试集精度为:%f",accuracy(test_data$Survived,pre_test2))
[1] "决策树模型在测试集精度为:0.820225"
> cfm$table
          Reference
Prediction  0  1
         0 97 20
         1 12 49

可以发现,在训练集上决策树模型的精度为86.6760%,在测试集上决策树模型的精度为82.0225%。程序中还有32个样本归类错误,精度有待改进。

  • 5
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值