决策树R实现-CHAID,ID3,C5.0,CART算法
弄懂决策树的原理后,就需要实践了。我将使用不同类型的数据进行说明。
CHAID建模
使用的是MASS包的Pima数据(印第安人糖尿病二进制分类数据集),Pima.tr是测试数据集,Pima.te是测试数据集,通过构建CHAID决策树来判断是否患有糖尿病。
在决策树原理篇有提到过,CHAID的输入变量是分类型,而Pima数据集的数据是连续型,所以要将数据分类化:
程序如下:
Pima<-rbind(Pima.tr,Pima.te)#将数据集分类化
newpima<-{}
for (i in 1:7){
Pima[,i]<-cut(Pima[,],breaks=3)
newpima<-rbind(newpima,newpima(Pima[,i]))
}
newpima<-data.frame(newpima)
row.name(newpima)<-colnames(Pima)
colnames<-paste(‘L’,1:3,sep=’’)
set.seed(1)#随机生成训练样本和测试样本
selece<-sample(x=2,size=nrow(newpima),replace=TRUE,prob=c(0.8,0.2))
newpima.tr = newpima[selece1,]
newpima.te = newpima[selece2,]
CHAID_tree = chaid(type~.,newpima.tr)#CHAID建模
CHAID_tree#模型结果
Model formula:
type ~ npreg + glu + bp + skin + bmi + ped + age
Fitted party:
[1] root
| [2] glu in [55.9,104]
| | [3] bmi in [18.2,34.5]
| | | [4] ped in [0.0827,0.863]: No (n = 86, err = 1.2%)
| | | [5] ped in (0.863,1.64], (1.64,2.42]: No (n = 15, err = 26.7%)
| | [6] bmi in (34.5,50.8], (50.8,67.1]: No (n = 46, err = 23.9%)
| [7] glu in (104,151]
| | [8] npreg in [-0.017,5.67]: No (n = 138, err = 26.1%)
| | [9] npreg in (5.67,11.3], (11.3,17]: Yes (n = 50, err = 44.0%)
| [10] glu in (151,199]: Yes (n = 72, err = 27.8%)
Number of inner nodes: 4
Number of terminal nodes: 6
plot(CHAID_tree)
model<-predict(CHAID_tree,newdata=newpima.te)#模型预测
matrix = table(Type = newpima.te$type, predict = model)
matrix#预测结果
predict
Type No Yes
No 68 12
Yes 19 26
sum(diag(matrix))/sum(matrix)#正确率
[1] 0.752
CHAID决策树图
CART建模
使用的是R自带的iris鸢尾花数据。
set.seed(20)
select<-sample(150,120)
head(iris)
dim(iris)
traindata<-iris[select,]#训练数据
testdata<-iris[-select,]#测试数据
control <- rpart.control(minsplit=20,minbucket=10,maxdepth=10,xval=5,cp=0.01)#设置向前剪枝的条件,maxdepth为树的深度,minsplit为非叶节点最小样本量,minbucket为叶节点最小样本量
model<-rpart(Species ~.,data=traindata,method=“class”,control=control,parms = list(prior = c(0.3,0.3,0.4), split = “gini”))
#split = "gini"表示cart算法,method表示末端数据类型选择对应的变量分割方法:连续型method=‘anova’,离散型method=‘class’,计数型method=‘poisson’,生存分析型method=‘exp’
#control对应前向剪枝的控制参数,na.action为缺失数据的处理方法,默认为删除因变量缺失的观测而保留自变量缺失的观测na.rpart
summary(model)#得出模型的总述
library(rattle)
asRules(model)#输出规则
printcp(model)
#复杂度
CP nsplit rel error xerror xstd
1 0.5000 0 1.000000 1.00000 0.067017
2 0.4266 1 0.500000 0.59548 0.072011
3 0.0100 2 0.073403 0.13844 0.044481
敲重点!找出最小误差对应的cp值,进行剪枝。
但是在建模时会默认为0.01,所以不需要再额外进行剪枝了。
plotcp(model)#交叉验证画图
modelKaTeX parse error: Expected 'EOF', got '#' at position 8: cptable#̲交叉验证结果 library(…Species,predictmodel,dnn=c(‘真实值’,‘预测值’))
预测值
真实值 setosa