一、使用包party创建决策树dom
这一节学习使用包party里面的函数ctree()为数据集iris创建一个决策树。属性Sepal.Length(萼片长度)、Sepal.Width(萼片宽度)、Petal.Length(花瓣长度)以及Petal.Width(花瓣宽度)被用来预测鸢尾花的Species(种类)。在这个包里面,函数ctree()创建了一个决策树,predict()预测另一个数据集。
在创建模型以前,iris(鸢尾花)数据集被分为两个子集:训练集(70%)和测试集(30%)。使用随机种子设置固定的随机数,可使得随机选取的数据是可重复利用的。函数
str(iris)学习
set.seed(1234)测试
ind <- sample(2, nrow(iris), replace=TRUE, prob=c(0.7, 0.3))优化
trainData <- iris[ind==1,]3d
testData <- iris[ind==2,]
加载包party创建一个决策树,并检测预测见过。函数ctree()提供一些参数例如MinSplit, MinBusket, MaxSurrogate 和 MaxDepth用来控制决策树的训练。下面咱们将会使用默认的参数设置去创建决策树,至于具体的参数设置能够经过?party查看函数文档。下面的代码中,myFormula公式中的Species(种类)是目标变量,其余变量是独立变量。
library(party)rest
myFormula <- Species ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Widthorm
iris_ctree <- ctree(myFormula, data=trainData)blog
table(predict(iris_ctree), trainData$Species)
显示结果以下:
ip
由上图可知,setosa(山鸢尾)40观测值所有正确预测,而versicolor(变色鸢尾)有一个观测值被误判为virginica(维吉尼亚鸢尾),virginica(维吉尼亚鸢尾)有3个观测值被误判为versicolor(变色鸢尾)。
print(iris_ctree)
plot(iris_ctree)
plot(iris_ctree, type="simple")
在图1中,每个叶子的节点的条形图都显示了观测值落入三个品种的几率。在图2中,这些几率以每一个叶子结点中的y值表示。例如:结点2里面的标签是“n=40 y=(1,0,0)”,指的是这一类中一共有40个观测值,而且全部的观测值的类别都属于第一类setosa(山鸢尾)。
接下来,须要使用测试集测试决策树。
testPred <- predict(iris_ctree, newdata = testData)
table(testPred, testData$Species)
结果以下:
从上图的结果可知,决策树对变色鸢尾和维吉尼亚鸢尾的识别仍然有误判。所以ctree()如今的版本并不能很好的处理部分属性不明确的值,在实例中既有可能被判到左子树,有时候也会被判到右子树上。
二、使用包rpart创建决策树
rpart这个包在本节中被用来在'bodyfat'这个数据集的基础上创建决策树。函数raprt()能够创建一个决策树,而且能够选择最小偏差的预测。而后利用该决策树使用predict()预测另一个数据集。
首先,加载bodyfat这个数据集,并查看它的一些属性。
data("bodyfat", package = "TH.data")
dim(bodyfat)
attributes(bodyfat)
bodyfat[1:5,]
跟第1节同样,将数据集分为训练集和测试集,并根据训练集创建决策树。
set.seed(1234)
ind <- sample(2, nrow(bodyfat), replace=TRUE, prob=c(0.7, 0.3))
bodyfat.train <- bodyfat[ind==1,]
bodyfat.test <- bodyfat[ind==2,]
library(rpart)
myFormula <- DEXfat ~ age + waistcirc + hipcirc + elbowbreadth + kneebreadth
bodyfat_rpart <- rpart(myFormula, data = bodyfat.train,
control = rpart.control(minsplit = 10))
plot(bodyfat_rpart)
text(bodyfat_rpart, use.n=T)
结果以下图所示:
选择预测偏差最小值的预测树,从而优化模型。
opt <- which.min(bodyfat_rpart$cptable[,"xerror"])
cp <- bodyfat_rpart$cptable[opt, "CP"]
bodyfat_prune <- prune(bodyfat_rpart, cp = cp)
plot(bodyfat_rpart)
text(bodyfat_rpart, use.n=T)
优化后的决策树以下:
对比结果就会发现,优化模型后,就是将hipcirc<99.5这个分层给去掉了,也许是由于这个分层没有必要,那么你们能够思考一下选择预测偏差最小的结果的决策树的分层反而没有那么细。
以后,优化后的决策树将会用来预测,预测的结果会与实际的值进行对比。下面的代码中,使用函数abline()绘制一条斜线。一个好的模型的预测值应该是约接近真实值越好,也就是说大部分的点应该落在斜线上面或者在斜线附近。
DEXfat_pred <- predict(bodyfat_prune, newdata=bodyfat.test)
xlim <- range(bodyfat$DEXfat)
plot(DEXfat_pred ~ DEXfat, data=bodyfat.test, xlab="Observed",
ylab="Predicted", ylim=xlim, xlim=xlim)
abline(a=0, b=1)
绘制结果以下:
三、随机森林
咱们使用包randomForest并利用鸢尾花数据创建一个预测模型。包里面的randomForest()函数有两点不足:第一,它不能处理缺失值,使得用户必须在使用该函数以前填补这些缺失值;第二,每一个分类属性的最大数量不能超过32个,若是属性超过32个,那么在使用randomForest()以前那些属性必须被转化。
也能够经过另一个包'cforest'创建随机森林,而且这个包里面的函数并不受属性的最大数量约束,尽管如此,高维的分类属性会使得它在创建随机森林的时候消耗大量的内存和时间。
ind <- sample(2, nrow(iris), replace=TRUE, prob=c(0.7, 0.3))
trainData <- iris[ind==1,]
testData <- iris[ind==2,]
library(randomForest)
rf <- randomForest(Species ~ ., data=trainData, ntree=100, proximity=TRUE)
table(predict(rf), trainData$Species)
结果以下:
由上图的结果可知,即便在决策树中,仍然有偏差,第二类和第三类话仍然会被误判,能够经过输入print(rf)知道误判率为2.88%,也能够经过输入plot(rf)绘制每一棵树的误判率的图。
最后,在测试集上测试训练集上创建的随机森林,并使用table()和margin()函数检测预测结果。
irisPred <- predict(rf, newdata=testData)
table(irisPred, testData$Species)
plot(margin(rf, testData$Species))
显示结果以下: