📋 文章目录
随着科技的进步,大数据从科学前沿逐渐深入到各行业。在土壤学、微生物学、农学和生态学等学科也并无例外。今天与大家分享一个比较稳健的机器学习法-基于 gbm 包的 GBRT (Gradient Boost Regression Tree),称为梯度 提升回归树,其"兄弟",GBDT(Gradient Boosting Decision Tree),称为梯度提升决策树。差异主要体现在分类树的衡量标准是最大熵,而回归树的衡量标准是最小化均方差。
🐣 一、梯度提升回归树的介绍(GBRT/GBDT)
wiki定义:
Gradient boosting is a machine learning technique for regression and classification problems, which produces a prediction model in the form of an ensemble of weak prediction models, typically decision trees. It builds the model in a stage-wise fashion like other boosting methods do, and it generalizes them by allowing optimization of an arbitrary differentiable loss function.
换句话说,该模型主要通过 一些弱分类器的组合来构造一个强分类器,并且每次的梯度提升(Gradient boosting)以减少上一次的残差,就可以在残差减少的梯度方向上建立一个新的模型 ,这与Boosting对错误的样本加大加权的做法有着很大的区别。比如:我们通常绘制两个变量(或者多个变量)的关系时,对于初学者来说,可能会选择 一次项线性模型来解释,但实际上该模型最佳拟合为二次项,这时候就会存在比较大的残差。 为了优化模型,我们只能继续选择二次项模型来拟合减小模型的残差。 同理 ,GBRT也是先根据初始模型的一个残差(伪残差,较大残差),然后建立学习器来解释这部分残差,并通过梯度提高过程减小残差。最后反复迭代就可以找到一个使残差达到最小的模型。
我们以一个示例进行解释:假设我们需要预测一群鸡的重量,第一颗树种某只鸡(A)的实际重量为8斤,预测出来的结果为5斤,真实值与预测值的差为3斤,那么残差为3。在第二颗树中,我们继续预设为3斤继续学习,如果第二棵树真的能把A分到3斤的叶子节点,那累加两棵树的结论就是A的真实结果。如果第二棵树的预测结果为2斤,则A仍然存在1岁的残差,第三棵树里A的结果为1斤,继续学习,然后依次迭代。。。。。
🐤 二、R语言代码学习过程
在R语言中,我们可以利用gbm(广义提升回归模型)包中的 gbm函数
# 下载gbm包
install.packages("gbm")
# 加载R包
library(gbm)
# 咨询help了解gbm函数
?gbm()
这是基本的用法和参数设定,可以根据自己的需求进行修改。
这里,以发表在Nature Climate Change一篇文章为例,来讲解GBRT模型。
这篇文章利用了GBRT,最后实现了中国各地区不同情况下作物产量的一个预测。
由于文章中存在多个地区和处理,其处理方式是重复的,因此数据以某个地区某个处理为例:
🥝 1、数据处理及处理
# Removing objects from the envrionment
rm(list = ls())
#==========================================================
# Loading library
library(gbm)
library(plyr)
library(dplyr)
library(ggplot2)
library(lattice)
library(caret)
library(hydroGOF)
library(gvlma)
library(car)
# set model for winter wheat in NCP
W_NCP<-read.csv("W-NCP.csv")
W_NCP$Year<-as.factor(W_NCP$Year)
W_NCP$Cultivar<-as.factor(W_NCP$Cultivar)
W_NCP$Soil.type<-as.factor(W_NCP$Soil.type)
W_NCP$Soil.texture<-as.factor(W_NCP$Soil.texture)
# set model for winter wheat in NCP
# set train and test data(random 10% for 50 times)
brt_WNCP_recyle<- NULL
best_inter_WNCP_recyle<-NULL
summary_recyle <- NULL
cor_1_recyle <- NULL
R2_1_recyle <- NULL
RMSE_1_recyle <- NULL
nRMSE_1_recyle<- NULL
ME_1_recyle <- NULL
P_value_1_recyle<-NULL
cor_2_recyle <- NULL
R2_2_recyle <- NULL
RMSE_2_recyle <- NULL
nRMSE_2_recyle<- NULL
ME_2_recyle <- NULL
P_value_2_recyle<-NULL
🍎 2、模型构建
进行多次的计算模型,并选择最小的残差模型,并进行了GBRT和LM的比较。。(这里作者可能是通过服务器进行循环计算的,因为我每次电脑循环都直接崩溃了),这里我们只做一次展示。
head(W_NCP)
set.seed(1)
train_WNCP <- sample(nrow(W_NCP), 0.9*nrow(W_NCP))
W_NCP_train <- W_NCP[train_WNCP,]
W_NCP_test <- W_NCP[-train_WNCP,]
# select required variables
sub_W_NCP_train <- W_NCP_train %>%
select(NO, Tave, Tmax, Tmin, GDD.0, PRE, SSD, RAD, Cultivar, Soil.type,
Soil.texture, SOM, OP , AK, pH, N, P2O5, K2O, Ynpk)
sub_W_NCP_test <- W_NCP_test %>%
select(NO, Tave, Tmax, Tmin, GDD.0, PRE, SSD, RAD, Cultivar, Soil.type,
Soil.texture, SOM, OP , AK, pH, N, P2O5, K2O, Ynpk)
#building brt model
set.seed(1)
brt_WNCP<-gbm(Ynpk ~ Tmax + Tmin + GDD.0 + PRE + RAD + Cultivar+ Soil.type
+ Soil.texture + SOM + OP + AK + pH + N + P2O5 + K2O,
data = sub_W_NCP_train, distribution = "gaussian", n.trees = 3000,
interaction.depth = 9, shrinkage = 0.01,
bag.fraction = 0.5,cv.folds = 10)
brt_WNCP_recyle[[1]]<-brt_WNCP
print(brt_WNCP)
从以下两张图来看,可以得出:模型再迭代2973次时达到了最小残差。
best_inter_WNCP<-gbm.perf(brt_WNCP,method = "cv")
best_inter_WNCP_recyle[[1]]<-best_inter_WNCP
summary_record<-summary(brt_WNCP,n.trees=best_inter_WNCP)
summary_recyle[[1]] <-summary_record
从上述两张图中可以看出各自变量对因变量的重要排序。
🍌 3、GBRT模型的预测
###predict for test data
#by GBRT
sub_W_NCP_test$Ynpk_pred_1<-predict(brt_WNCP,sub_W_NCP_test)
head(sub_W_NCP_test[, 19:20])
🍐 4、绘制真实值与预测值的散点图并检验模型结果
#plot of actual and predict values
plot(sub_W_NCP_test$Ynpk_pred_1,sub_W_NCP_test$Ynpk, xlim=c(3500,9500),ylim=c(3500,9500),
xlab="Predicted yield (kg/ha)", ylab="Observed yield (kg/ha)")
abline(a=0,b=1)
fitline<-lm(Ynpk~Ynpk_pred_1,sub_W_NCP_test)
abline(fitline,lty=2)
summary(fitline)
从上述散点图中的拟合线来看,真实值与预测值还是存在一定的差异。但是总体R2达到了35%,p值远远小于0.0001。
🍓 5、模型比较(与LM)
#by lm
lm_fit1_WNCP<-lm(Ynpk ~ Tmax + Tmin + GDD.0 + PRE + RAD + Cultivar+ Soil.type +Soil.texture
+ SOM + OP + AK + pH + N + P2O5 + K2O, data = sub_W_NCP_train)
summary(lm_fit1_WNCP)
进一步对模型进行预测绘图:
sub_W_NCP_test$Ynpk_pred_2<-predict(lm_fit1_WNCP,sub_W_NCP_test)
#plot of actual and predict values
plot(sub_W_NCP_test$Ynpk_pred_2,sub_W_NCP_test$Ynpk, xlim=c(3500,9500),ylim=c(3500,9500),
xlab="Predicted yield (kg/ha)", ylab="Observed yield (kg/ha)")
abline(a=0,b=1)
fitline2<-lm(Ynpk~Ynpk_pred_2,sub_W_NCP_test)
abline(fitline2,lty=2)
summary(fitline2)
从LM模型的真实值与预测值拟合效果来看,差异还是比较大的。R2仅有15%,小于GBRT模型的R2=35%。从初步结果来看,意味着GBRT模型优于LM模型。
进一步比较两个模型RMSE的结果:
RMSE_1_recyle[[1]] <- RMSE_1; RMSE_1_recyle
RMSE_2_recyle[[1]] <- RMSE_2; RMSE_2_recyle
nRMSE_1_recyle[[1]] <- nRMSE_1; nRMSE_1_recyle
nRMSE_2_recyle[[1]] <- nRMSE_2; nRMSE_2_recyle
GBRT的RMSE等指标均小于LM。确实证明了GBRT模型优于LM模型。
🦅 三、GBRT模型的优势
优点如下:
(1)防止过拟合;
(2)每一步的残差计算其实变相地增大了分错instance的权重,而已经分对的instance则都趋向于0;
(3)残差作为全局最优的绝对方向。
GBRT的两个版本理解:
(1)残差版本把GBRT认为是一个残差迭代树,每一棵回归树都在学习前N-1棵树的残差。 求解方法:残差----残差是全局最优值;优化目标:让结果变成最好。
(2)Gradient版本把 GBRT看作一个梯度迭代树,使用梯度下降法求解,每一棵回归树在学习前N-1棵树的梯度下降值。求解方法:局部最优方向 * 步长 ; 优化目标:让结果变成更好。
随机森林与梯度提升回归树的对比:
参考链接:https://www.cnblogs.com/zhizhan/p/5088775.html