天天看点

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会导致过拟合,所以我们需要在正确的时间点停止。

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

请看下面的图表:

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

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

相关数学概念的解释

如何给样本分配权重

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

步骤1:假设alpha(t)

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

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

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

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

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

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

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

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

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

最近我参加了由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,] 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或其它平台上能获得较高的初始评分。然而,这一切还取决你如何进行好的特征设计。

原文发布时间为:2015-12-29

本文来自云栖社区合作伙伴“大数据文摘”,了解相关信息可以关注“bigdatadigest”微信公众号

继续阅读