决策树与随机森林

一、决策树

决策树模型
决策树模型通常用于解决非线性的分类问题,该模型结果呈现出树状图形状,称为决策树。决策树从根节点排列某个叶子节点来分类,决策树的节点的不同分支表示不同的选择,最终达到叶子节点得到的逻辑规则。
常用的决策树算法有ID3、C4.5和CART算法。
(1) ID3(Iterative Dichotomiser 3)算法,是由澳大利亚计算机科学家Quinlan1986年提出的,它是经典的决策树算法之一。ID3算法在选择划分节点的属性时,使用信息增益来选择。由于ID3算法不能处理非离散型特征,而且由于没有考虑每个节点的样本大小,所以可能导致叶子节点的样本数量过小,往往会带来过拟合的问题。
(2) C4.5算法是对ID3算法的进一步改进,它能够处理不连续的特征,在选择划分节点的属性时,使用信息增益率来选择。因为信息增益率考虑了节点分裂信息,所以不会过分偏向于取值数量较多的离散特征。
(3) ID3算法和C4.5算法主要用于解决分类问题,不能用于解决回归问题,而CART(Classification And Regression Tree)算法则能同时处理分类和回归问题。CART算法在解决分类问题时,使用Gini系数(基尼系数)的下降值,选择划分节点属性的度量指标;在解决回归问题时,根据节点数据目标特征值的方差下降值,作为节点分类的度量标准。

提问:之前有讲到过多元线性回归,和Logistic回归,二者都用于解决线性问题,但是根据我们的认知,决策树模型是更为高级的算法,但它一定就优于线性回归模型吗?

这边我提出我的看法,越高级的算法不能说明越好,要根据模型的精度、拟合度、残差检验等多方面分析,一昧追求高级的算法容易陷入误区,认为越高级的算法越好,最终会导致简单的问题复杂化。数学建模里面,如何建立合适的模型,判断模型的好坏、在此基础上给出优化模型的方法非常关键。在数学建模国赛优秀论文里面,你会发现,有些人用的算法非常简单,但为什么能拿到国奖,这里的关键在于创新,简单的方法+优化模型的方法,例如随机森林+模拟退火/蚁群等,得到高精度的模型,往往比一昧最求高级的算法好使,毕竟有些人会用高级的算法,但是底层逻辑不明白,只是知道跑出一个结果,这个结果能用就行(知其然而不知其所以然)。

案例1:泰坦尼克号幸存者预测

## 泰坦尼克号数据集解释
## PassengerId 乘客ID
## Survived 是否幸存,0表示死亡,1表示存活
## Pclass 客舱等级,1,2,3存在3个等级
## Name 乘客姓名
## Sex 性别
## Age 年龄
## SibSp 乘客在船上的兄弟姐妹或配偶数目
## Parch  乘客在船上的父母或孩子数目
## Ticket 乘客的船票号码
## Fare 乘客购买的票价
## Cabin 乘客的舱位号
## Embarked 登船港口,S(Southampton)、C(Cherbourg)或 Q(Queenstown)

导入决策树相关包和数据集,合并数据集并对当中异常值进行处理。

library(readr)
library(VIM)
library(caret)
library(rpart)
library(rpart.plot)
library(Metrics)
library(ROCR)
library(readxl)
library(stringr)
library(ggplot2)

## 读取测试集和训练集合数据
Ttrain <- read_csv("Titanic train.csv")
Ttest <- read_csv("Titanic test.csv")
dim(Ttrain)
colnames(Ttrain)
dim(Ttest)

## 组合数据
Alldata <- rbind.data.frame(Ttrain[,-2],Ttest)
summary(Ttrain)
summary(Ttest)
summary(Alldata)

Survived <- Ttrain$Survived
table(Survived)

可视化数据集当中缺失值的情况,选择合适的方法处理缺失值。

## 数据探索与可视化,及特征变换
## 分析数据的缺失值情况,并进行处理
aggr(Alldata,prop=FALSE, numbers=TRUE,## prop=FALSE按计数作图,prop=TRUE按比例作图。
     cex.axis =.6)##cex.axis调整变量标字体大小,字体过大,图标会显示不全。
colnames(Alldata)

图中不难发现,Cabin缺失值最多,其次是Age,Fare和Embarked也存在少量缺失值,下面对缺失值进行处理。

# 训练集和测试集要同时作相同的操作
## Cabin缺失值太多,可以直接剔除
Alldata$Cabin <- NULL
## 船票和ID具有识别性所以需要剔除
Alldata$PassengerId <- NULL
Alldata$Ticket <- NULL

## 年龄变量的缺失值可以使用中位数来填补
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

## 获取新的特征,提取name变量中的特征
newname <- str_split(Alldata$Name," ")
newname <- sapply(newname, function(x) x[2])

sort(table(newname),decreasing = T)
## 名字设置为 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)

对于大规模缺失变量Cabin,填补缺失值数据会导致结果失真,因此直接剔除掉。PassengerID和Ticket两个变量都能对应乘客个体,剔除。对于缺失值较少的变量,Age、Fare和Embarked数据,更具情况可以用简单的中位数、平均值和众数来填补。因为名称中主要包含的称谓为Mr.、Miss.、Mrs.. Master.等,可以将该特征转化为新的特征,即保留Mr.、Miss.、Mrs.、Master.四种称呼,其余的使用other代替。

将处理完的数据80%切分为测试集、20%切分为训练集。用训练集建立决策树模型。

## 与处理好的训练数据和测试数据分开
Ttrainp <- Alldata[1:nrow(Ttrain),]
Ttrainp$Survived <- Survived
Ttestp <- Alldata[(nrow(Ttrain)+1):nrow(Alldata),]
str(Ttrainp)

## 切分训练数据集为训练集和测试集,70%训练
set.seed(123)##设置随机树种子
CDP <- createDataPartition(Ttrainp$Survived,p = 0.8)
train_data <- Ttrainp[CDP$Resample1,]
test_data <- Ttrainp[-CDP$Resample1,]

下为建立决策树模型的代码,R语言默认用ID3算法。

mod1 <- rpart(Survived~.,data = train_data,method="class",cp = 0.000001)
summary(mod1)
Call:
rpart(formula = Survived ~ ., data = train_data, method = "class", 
    cp = 1e-06)
  n= 713 

           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

Variable importance
    Name      Sex     Fare      Age    Parch   Pclass    SibSp Embarked 
      26       21       15       11        9        9        7        2 

不难发现Variable importance中,在建立决策树模型的当中,Name、Sex两个变量对Survived影响最大,可视化决策树模型的结果。

## 看变量重要性
mod1$variable.importance
#cp是每次分割对应的复杂度系数
mod1$cp
## plot cross-validation results
plotcp(mod1)

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

决策树的根节点为变量Name,且当Name变量为Mr.或者other时,则更倾向于遇难的叶子节点,检测模型在训练集和测试集上的精度。

## 查看模型在训练集和测试集上的预测效果
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)))
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
cfm

最后得到,决策树模型在训练集上的精度为0.866760,在测试集上的精度为0.820225,说明构建出来的决策树模型的效果非常理想。

决策树模型的剪枝和优化(鸽了,心情好再写)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值