R: 学习Gradient Boosting算法,提高预测模型准确率

引言

预测模型的准确率可以用2种方法来提高:要么进行特征设计,要么直接使用boosting算法。参加过许多数据科学大赛后,我发现许多人喜欢用boosting算法,因为它只需更少的时间就能产生相似的结果。


目前有许多boosting算法,如Gradient Boosting、 XGBoost,、AdaBoost和Gentle Boost等等。每个算法都有自己基本的数学原理并且在使用它们时都会发现有一些细微的变化。如果你刚接触boosting算法,那太好了!从现在开始你可以在一周内学习所有这些概念。


在本文中,我解释了Gradient Boosting算法的基本概念和复杂性。另外,我也分享了一个实例来学习它在R中的应用。


简要的说明

一旦使用boosting算法,你很快就会发现两个频繁出现的术语:Bagging和Boosting。那么,它们有什么不同呢?下面将一一解释:


Bagging:这是一种方法,当你使用随机采样的数据,建立学习算法,采取简单的手段以找到bagging的可能性。


Boosting:与Bagging类似,但是,对样本的选择更智能。我们随后会对难以分类的样本分配较大的权重。


好!我明白你脑中会产生类似的疑问,像‘难以分类的样本’是什么意思?我怎么知道应该要给错误分类的样本多少额外的权重?不要着急,接下来我将回答你所有的疑问。


让我们从一个简单的例子开始学习

假设,你需要改进先前的模型M。现在,你发现模型已经有80%(在所有指标下)的准确率。你怎样提高M的性能呢?


一种简单的办法是利用一个新的输入变量集建立一个完全不同的模型,并尝试更好的学习模型。与之相反,我有一个更简单的方法,该模型是这样的:


Y = M(x) + error


如果我能够看到误差(error)并不是白噪声,而是跟输出结果(Y)有相关性呢?倘若我们在误差项(error)上再建立一个模型呢?比如,


error = G(x) + error2


也许,你会看到误差率提高到一个更高的数字,比如84%。让我们继续另一个步骤并对error2进行回归。


error2 = H(x) + error3


现在,我们把所有这些组合到一起:


Y = M(x) + G(x) + H(x) + error3


这也许会有超过84%的准确率。如果我们能够找到这三个学习模型的每一个的优化权重呢?


Y = alpha * M(x) + beta * G(x) + gamma * H(x) + error4


如果我们找到了好的权重,我们很有可能做了一个更好的模型。这是boosting学习的基本原则。当我第一次读到这个理论时,很快我就产生了2个问题:


1. 在回归/分类等式中我们能真正看到非白噪声误差么?如果不能,我们怎么能使用这个算法。


2. 如果这有可能的话,为什么没有接近100%的准确率呢?


在本文中我将以清晰简洁的方式来回答这些问题,Boosting通常用于弱学习,即没有分离白噪声的能力。第二,因为boosting会导致过拟合,所以我们需要在正确的时间点停止。


让我们试试把一个分类问题可视化


请看下面的图表:


我们从第一个箱线图开始。我们看到一条垂直线,这是我们的第一个弱学习模型。这时我们有3/10的误分类率。现在我们对3个误分类的样本分配更高的权重,此时,对它们分类非常重要。因此,垂直线向右边缘靠近。我们重复这个操作,然后以恰当的权重组合每个学习模型。


相关数学概念的解释


如何给样本分配权重


我们以均匀分布的假设开始。将它记作D1,即在n个样本中出现的概率为1/n。


步骤1:假设alpha(t)

步骤2:得到弱分类结果h(t)

步骤3:在下次迭代中更新的总量分布


步骤4:在下次迭代中使用新的总量分布来找到下一个学习模型


被步骤3的数学表达式吓到了么?我来给你解释一下。简单地看一下e指数的参数,alpha是学习率,y是真实的响应(+1或-1),h(x)是通过学习得到的预测分类。本质上,如果学习有错误的话,e指数的值变成1*alpha或者-1*alpha。重要的是,如果最后一次预测出错,权重将会增加。那么接下来怎么做呢?


步骤5:迭代步骤1至步骤4直到找不到假设可以进一步提高。


步骤6:到目前为止,在所有用到的学习模型前使用加权平均。但是权重是多少呢?这里权重就是alpha值,alpha的计算公式如下:


是时候实践一下了,下面是个实例


最近我参加了由Analytics Vidhya组织的在线编程马拉松。为了变量转换更容易,我把文件complete_data中的测试数据和训练数据组合起来使用。我从基本的导入函数开始,把总量分到Devlopment、ITV和Scoring中。


#加载caret包,清空工作空间变量,并设置工作空间

library(caret)

rm(list=ls())

setwd("C:\\Users\\ts93856\\Desktop\\AV")

#导入Metrice包

library(Metrics)

#读取complete_data.csv文件

complete <- read.csv("complete_data.csv", stringsAsFactors = TRUE)

#提取训练集,评分集

train <- complete[complete$Train == 1,]

score <- complete[complete$Train != 1,]

#设置随机种子

set.seed(999)

#对训练集和测试集进行采样

ind <- sample(2, nrow(train), replace=T, prob=c(0.60,0.40))

trainData<-train[ind==1,]

testData <- train[ind==2,]

set.seed(999)

ind1 <- sample(2, nrow(testData), replace=T, prob=c(0.50,0.50))

trainData_ens1<-testData[ind1==1,]

testData_ens1 <- testData[ind1==2,]

table(testData_ens1$Disbursed)[2]/nrow(testData_ens1)

#Response Rate of 9.052%


下面你要做的是建立GBM模型。


fitControl <- trainControl(method = "repeatedcv", number = 4, repeats = 4)

trainData$outcome1 <- ifelse(trainData$Disbursed == 1, "Yes","No")

set.seed(33)

#将训练数据放入训练池中对模型参数训练,这里采样线性模型,方法采用gbm估计

gbmFit1 <- train(as.factor(outcome1) ~ ., data = trainData[,-26], method = "gbm", trControl = fitControl,verbose = FALSE)

#测试数据套入模型中进行验证预测

gbm_dev <- predict(gbmFit1, trainData,type= "prob")[,2]

gbm_ITV1 <- predict(gbmFit1, trainData_ens1,type= "prob")[,2]

gbm_ITV2 <- predict(gbmFit1, testData_ens1,type= "prob")[,2]

#计算模型AUC曲线

auc(trainData$Disbursed,gbm_dev)

auc(trainData_ens1$Disbursed,gbm_ITV1)

auc(testData_ens1$Disbursed,gbm_ITV2)


在这段代码运行结束后,正如你所看到的,所有AUC值将非常接近0.84,我将把特征设计的任务留给你,因为比赛还在继续进行中。同时欢迎你使用此代码来参加比赛。GBM是最为广泛使用的算法。XGBoost是另外一个提高学习模型的较快版本。


结语

我已经发现boosting学习非常快而且极其高效。它们从来不让我失望,总是能在kaggle或其它平台上能获得较高的初始评分。然而,这一切还取决你如何进行好的特征设计。


你以前使用过Gradient Boosting么?模型运行结果如何?你有没有使用boosting学习来提高其它方面的能力。


文章来源:大数据文摘

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Gradient Boosting是一种常见的Boosting算法,它通过迭代地训练模型,每次训练都会加入一个新的弱分类器,并调整样本的权重来逐步提高整体模型的准确率。在每一轮迭代中,Gradient Boosting会根据上一轮迭代的结果来调整样本的权重,使得上一轮分类错误的样本在下一轮迭代中得到更多的关注,从而使得整体模型更加健壮。 下面是一个使用Python实现Gradient Boosting的示例代码: ```python import numpy as np from sklearn.tree import DecisionTreeRegressor class GradientBoosting: def __init__(self, n_estimators=100, learning_rate=0.1): self.n_estimators = n_estimators self.learning_rate = learning_rate self.trees = [] def fit(self, X, y): # 初始化样本权重 sample_weights = np.ones(X.shape[0]) / X.shape[0] for i in range(self.n_estimators): # 训练一个新的弱分类器 tree = DecisionTreeRegressor(max_depth=1) tree.fit(X, y, sample_weight=sample_weights) self.trees.append(tree) # 根据当前模型的预测结果更新样本权重 predictions = tree.predict(X) residuals = y - predictions sample_weights *= np.exp(-self.learning_rate * residuals) sample_weights /= np.sum(sample_weights) def predict(self, X): predictions = np.zeros(X.shape[0]) for tree in self.trees: predictions += self.learning_rate * tree.predict(X) return predictions ``` 在这个示例代码中,我们使用了scikit-learn库中的DecisionTreeRegressor来实现弱分类器。在每一轮迭代中,我们都会训练一个新的弱分类器,并根据当前模型的预测结果来更新样本权重。最终,我们将所有弱分类器的预测结果加权求和,得到最终的模型预测结果。 使用Gradient Boosting算法时,需要根据具体的数据和任务选择合适的参数,比如迭代次数、学习率等。同时,由于Gradient Boosting是一种基于集成学习算法,因此它通常需要更多的时间和计算资源来训练和调整模型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值