R語言隨機(jī)森林全流程分析
引言
再2023年6月,如果你以Random Forest為關(guān)鍵詞在Google Scholar檢索唯鸭,時間降序须蜗。
你會發(fā)現(xiàn)這些方法用于各個領(lǐng)域的研究:GIS、環(huán)境、遙感(只要有大數(shù)據(jù))
發(fā)表的期刊水平也參差不齊明肮,有Frontiers菱农、Remote Sensing(MDPI)、總環(huán)晤愧。
除了很少有頂尖期刊大莫,但也不乏還不錯的期刊蛉腌,從一區(qū)到四區(qū)官份。為何這個方法一直在使用?這就引出了隨機(jī)森林的幾個優(yōu)點烙丛。
隨機(jī)森林是集成學(xué)習(xí)(Ensemble Learning)舅巷,集成學(xué)習(xí)的基本思想就是將多個分類器組合,從而實現(xiàn)一個預(yù)測效果更好的集成分類器河咽。
隨機(jī)森林既可以勝任分類任務(wù)又可以勝任回歸任務(wù)钠右。機(jī)器學(xué)習(xí)中有兩種任務(wù),回歸和分類忘蟹,而隨機(jī)森林可以同時勝任這兩種任務(wù)飒房。其中分類任務(wù)是對離散值進(jìn)行預(yù)測(比如將一景圖像中的植被,建筑媚值,水體等地物類型分類)狠毯;回歸任務(wù)是對連續(xù)值進(jìn)行預(yù)測(比如根據(jù)已有的數(shù)據(jù)預(yù)測明天的氣溫是多少度,預(yù)測明天某基金的價格)褥芒。
隨機(jī)森林能評估特征的相對重要性嚼松。集成學(xué)習(xí)模型的一大特點是可以輸出特征重要性,特征重要性能夠在一定程度上輔助我們對特征進(jìn)行篩選锰扶,從而使得模型的魯棒性更好献酗。在實際研究中,也能提供一定的物理意義坷牛。
代碼實現(xiàn)
借助于R語言的高效數(shù)據(jù)分析罕偎,我們使用R的randomForest
包實現(xiàn)這一效果
數(shù)據(jù)集載入
首先加載數(shù)據(jù)集:
library(tidyverse)
data(airquality)
airquality <- airquality %>% na.omit()
airquality
在airquality
數(shù)據(jù)集中,Ozone
是臭氧變量京闰,其它太陽輻射Solar.R
锨亏、風(fēng)速Wind
和溫度Temp
等等對臭氧的影響。
數(shù)據(jù)訓(xùn)練
這里首先把數(shù)據(jù)集劃分訓(xùn)練集(70%)
和測試集(30%)
使用randomForest
開始訓(xùn)練忙干,其中Ozone~
代表臭氧Ozone為因變量器予,其它數(shù)據(jù)為自變量。
# To evaluate the performance of RF
# split traning data (70%) and validation data (30%)
set.seed(123)
train <- sample(nrow(airquality), nrow(airquality)*0.7)
ozo_train <- airquality[train, ]
ozo_test <- airquality[-train, ]
# randomForest
library(randomForest)
# Random forest calculation(default 500 tress)捐迫,please see ?randomForest
set.seed(123)
ozo_train.forest <- randomForest(Ozone~., data = ozo_train, importance = TRUE)
ozo_train.forest
結(jié)果如圖:
結(jié)果中乾翔,
% Var explained
體現(xiàn)了預(yù)測變量(太陽輻射,溫度,降水和時間變量)對響應(yīng)變量(臭氧)有關(guān)方差的整體解釋率反浓。解釋了約70.44%的總方差萌丈,可以理解為該回歸的R2=70.44,相當(dāng)可觀的一個數(shù)值雷则,表明臭氧與這些變量密切相關(guān)
可視化結(jié)果
接下來可視化隨機(jī)森林的回歸效果:
# Scatterplot
library(ggplot2)
library(ggExtra)
library(ggpmisc)
library(ggpubr)
g <- ggplot(train_test, aes(obs, pre)) +
geom_point() +
geom_smooth(method="lm", se=F) +
geom_abline(slope = 1,intercept = 0,lty="dashed") +
stat_poly_eq(
aes(label =paste( ..adj.rr.label.., sep = '~~')),
formula = y ~ x, parse = TRUE,
family="serif",
size = 6.4,
color="black",
label.x = 0.1, #0-1之間的比例確定位置
label.y = 1)
g1 <- ggMarginal(g, type = "histogram", fill="transparent")
g <- ggplot(predict_test, aes(obs, pre)) +
geom_point() +
geom_smooth(method="lm", se=F) +
geom_abline(slope = 1,intercept = 0,lty="dashed") +
stat_poly_eq(
aes(label =paste( ..adj.rr.label.., sep = '~~')),
formula = y ~ x, parse = TRUE,
family="serif",
size = 6.4,
color="black",
label.x = 0.1, #0-1之間的比例確定位置
label.y = 1)
g2 <- ggMarginal(g, type = "histogram", fill="transparent")
ggarrange(g1, g2, ncol = 2)
# ggMarginal(g, type = "boxplot", fill="transparent")
# ggMarginal(g, type = "density", fill="transparent")
如圖所示辆雾,在訓(xùn)練集的擬合效果很好,R2可達(dá)0.94
在測試集上表現(xiàn)也較好月劈,R2可達(dá)0.71
重要性評估
接下來查看變量重要性
##Ozo 的重要性評估
importance_ozo <- ozo_train.forest$importance
importance_ozo
importance_plot <- tibble(var = rownames(importance_ozo),
IncMSE = importance_ozo[,1],
IncNodePurity = importance_ozo[,2])
%IncMSE
即increase in mean squared error度迂,通過對每一個預(yù)測變量隨機(jī)賦值,如果該預(yù)測變量更為重要猜揪,那么其值被隨機(jī)替換后模型預(yù)測的誤差會增大惭墓。因此,該值越大表示該變量的重要性越大而姐;
IncNodePurity
即increase in node purity腊凶,通過殘差平方和來度量,代表了每個變量對分類樹每個節(jié)點上觀測值的異質(zhì)性的影響拴念,從而比較變量的重要性钧萍。該值越大表示該變量的重要性越大。
對于%IncMSE
或IncNodePurity
政鼠,二選一作為判斷預(yù)測變量重要性的指標(biāo)风瘦。需注意的是,二者的排名存在一定的差異缔俄。
對重要性排序進(jìn)行可視化:
p1 <- ggplot(importance_plot, aes(x=var, y=IncMSE)) +
geom_segment( aes(x=var, xend=var, y=0, yend=IncMSE), color="skyblue") +
geom_point( color="blue", size=4, alpha=0.6) +
theme_light() +
coord_flip() +
theme(
panel.grid.major.y = element_blank(),
panel.border = element_blank(),
axis.ticks.y = element_blank()
)
p2 <- ggplot(importance_plot, aes(x=var, y=IncNodePurity)) +
geom_segment( aes(x=var, xend=var, y=0, yend=IncNodePurity), color="skyblue") +
geom_point( color="blue", size=4, alpha=0.6) +
theme_light() +
coord_flip() +
theme(
panel.grid.major.y = element_blank(),
panel.border = element_blank(),
axis.ticks.y = element_blank()
)
ggarrange(p1, p2, ncol = 2)
可以看到弛秋,溫度Temp
是臭氧的一個主要因素
交叉驗證
接下來進(jìn)行五折交叉驗證,來選取超參數(shù)(這里是變量個數(shù)):
-
replicate
用于重復(fù)n次所需語句俐载,這里進(jìn)行5次五折交叉驗證 -
rfcv
通過嵌套交叉驗證程序顯示模型的交叉驗證預(yù)測性能蟹略,模型的預(yù)測器數(shù)量按順序減少(按變量重要性排序)。 -
step
如果log=TRUE遏佣,則為每個步驟要刪除的變量的分?jǐn)?shù)挖炬,否則一次刪除這么多變量 -
cv.fold
為折數(shù)
#5 次重復(fù)五折交叉驗證
set.seed(111)
ozo_train.cv <- replicate(5, rfcv(ozo_train[-ncol(ozo_train)], ozo_train$Ozone, cv.fold = 5, step = 0.8), simplify = FALSE)
#ozo_train.cv
ozo_train.cv <- data.frame(sapply(ozo_train.cv, '[[', 'error.cv'))
ozo_train.cv$vars <- rownames(ozo_train.cv)
ozo_train.cv <- reshape2::melt(ozo_train.cv, id = 'vars')
ozo_train.cv$vars <- as.numeric(as.character(ozo_train.cv$vars))
ozo_train.cv.mean <- aggregate(ozo_train.cv$value, by = list(ozo_train.cv$vars), FUN = mean)
ozo_train.cv.mean
可視化誤差結(jié)果
ggplot(ozo_train.cv.mean, aes(Group.1, x)) +
geom_line() +
labs(title = '',x = 'Number of vars', y = 'Cross-validation error')
根據(jù)交叉驗證曲線,提示保留1個重要的變量(或前四個重要的變量)獲得理想的回歸結(jié)果状婶,因為此時的誤差達(dá)到最小意敛。
因此,根據(jù)計算得到的各ozone重要性的值(如“IncNodePurity”)膛虫,將重要性由高往低排序后草姻,最后大約選擇前4個變量就可以了。
#首先根據(jù)某種重要性的高低排個序稍刀,例如根據(jù)“IncNodePurity”指標(biāo)
importance_ozo <- importance_plot[order(importance_plot$IncNodePurity, decreasing = TRUE), ]
#然后取出排名靠前的因素
importance_ozo.select <- importance_ozo[1:4, ]
vars <- c(pull(importance_ozo.select, var), 'Ozone')
ozo.select <- airquality[ ,vars]
ozo.select <- reshape2::melt(ozo.select, id = 'Ozone')
# 查看下這些重要的 vars 與Ozone的關(guān)系
ggplot(ozo.select, aes(x = Ozone, y = value)) +
geom_point() +
geom_smooth() +
facet_wrap(~variable, ncol = 2, scale = 'free_y') +
labs(title = '',x = 'Ozone', y = 'Relative abundance')
這就是R語言進(jìn)行隨機(jī)森林分析的全流程了撩独,希望對大家的科研有所幫助敞曹。
本文由mdnice多平臺發(fā)布