袋裝法
#裝袋法是隨機森林在 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)
結果分析:此時得到的均方誤差略低。