袋裝法、隨機森林、提升法(迴歸)
袋裝法
#裝袋法是隨機森林在 m=p 時的一種特殊情況。 因此函式 randomForest() 既可以用來做隨機森林,也可以執行裝袋法。
library(randomForest)
set.seed(1)
dim(Boston)
bag.boston=randomForest(medv~.,data=Boston,subset=train,mtry=13,importance=TRUE) #引數 mtry=13 意味著樹上的每一個分裂點都應該考慮全部 13 個預測變數,此時執行裝袋法。
bag.boston
yhat.bag = predict(bag.boston,newdata=Boston[-train,])
plot(yhat.bag, boston.test)
abline(0,1)
mean((yhat.bag-boston.test)^2)
結果分析:裝袋法迴歸樹的測試均方誤差是 23.59。
bag.boston=randomForest(medv~.,data=Boston,subset=train,mtry=13,ntree=25) #用引數ntree 改變由 randomForest ()生成的樹的數目
yhat.bag = predict(bag.boston,newdata=Boston[-train,])
mean((yhat.bag-boston.test)^2)
set.seed(1)
隨機森林
#生成隨機森林的過程和生成裝袋法模型的過程一樣,區別只是所取的 mtry 值更小,函式randomForest ()預設在用迴歸樹建立隨機森林時取p/3個變數,而用分類樹建立隨機森林時取個變數,這裡取 mtry=6。
rf.boston=randomForest(medv~.,data=Boston,subset=train,mtry=6,importance=TRUE)
yhat.rf = predict(rf.boston,newdata=Boston[-train,])
mean((yhat.rf-boston.test)^2)
結果分析:測試均方誤是19.62
importance(rf.boston) #函式importance ()瀏覽各變數的重要性。
結果分析:上面列出了變數重要性的兩個測度,前者基於當一個給定的變數被排除在模型之外時,預測袋外樣本的準確性的平均減小值。後者衡量的是由此變數導致的分裂使結點不純度減小的總量。在迴歸樹中,結點不純度是由訓練集RSS衡量的,而分類樹的結點純度是由偏差衡量的。反映這些變數重要程度的圖可自函式 varlmpPlot ()畫出。
varImpPlot(rf.boston)
結果分析:結果表明,在隨機森林考慮的所有變繞中, lstat 和rm 是目前最重要的兩個變數。
提升法
#用gbm包和其中的 gbm() 函式對 Boston 資料集建立迴歸樹
library(gbm)
set.seed(1)
boost.boston=gbm(medv~.,data=Boston[train,],distribution="gaussian",n.trees=5000,interaction.depth=4) #由於是迴歸問題,在執行gbm() 時選擇 distribution =" gaussian" ;如果是二分類問題,應選擇 distribution =" bernoulli" 。物件n. trees = 5000 表示提升法模型共需要5000 棵樹,選項interaction.dept=4 限制了每棵樹的深度
summary(boost.boston) #用函式 summary ()生成一張相對影響圖,並輸出相對影響統計資料
結果分析:可見lstat和 rm 是目前最重要的變數。
#par(mfrow=c(1,2))
plot(boost.boston,i="rm") #畫出rm變數的偏相關圖
plot(boost.boston,i="lstat")
結果分析:這是兩個變數rm和lstat的偏相關圖 ( partial dependence plot) ,這些圖反映的是排除其他變數後,所選變數對響應值的邊際影響。在這個例子中,住宅價格中位數(響應值)隨rm的增大而增大,隨後lstat的增大而減小。
yhat.boost=predict(boost.boston,newdata=Boston[-train,],n.trees=5000) #用提升法模型在測試集上預測 medv。
mean((yhat.boost-boston.test)^2)
結果分析:測試均方誤差是18.85,這個結果與隨機森林類似,比裝袋法略好。
boost.boston=gbm(medv~.,data=Boston[train,],distribution="gaussian",n.trees=5000,interaction.depth=4,shrinkage=0.2,verbose=F) #取不同的壓縮引數做提升法
yhat.boost=predict(boost.boston,newdata=Boston[-train,],n.trees=5000)
mean((yhat.boost-boston.test)^2)
結果分析:此時得到的均方誤差略低。