在众多数据科学竞赛中,发现许多参赛者更倾向于使用提升算法,因为它们不仅节省时间,而且能够产生相似的结果。提升算法有多种,如梯度提升、XGBoost、AdaBoost、Gentle Boost等。每种算法都有其自身的数学基础和应用时的细微差别。如果是新手,太好了!将在一周内学习到所有这些概念。
本文将解释梯度提升算法的基本概念和复杂性,并分享一个R语言的实现示例。注意:本指南面向初学者,如果已经掌握了这个概念,可以跳过本文。
在使用提升算法时,很快就会遇到两个经常出现的术语:Bagging和Boosting。它们有什么区别呢?这里有一个简单的解释:
Bagging:这是一种方法,从数据中随机抽取样本,构建学习算法,并采用简单的平均值来找到Bagging概率。
Boosting:Boosting类似,但样本的选择更加智能。随后给难以分类的观测值越来越多的权重。
好的!知道有很多问题,比如“所说的‘难’是什么意思?怎么知道应该给误分类的观测值增加多少额外的权重?”将在后续部分回答所有的问题。保持冷静,继续阅读。
假设已经有一个模型M需要改进。目前观察到模型的准确率为80%(任何指标)。如何进一步改进它呢?
一个简单的方法是使用一组新的输入变量构建一个完全不同的模型,并尝试更好的集成学习器。相反,有一个更简单的方法建议。它是这样的:
Y = M(x) + error
如果能看到错误不是白噪声,而是与结果(Y)值有相同的相关性。如果能在这个错误项上开发一个模型呢?比如:
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
如果找到了好的权重,可能就构建了一个更好的模型。这就是提升学习器的基本原理。当第一次读到这个理论时,有两个快速的问题:
真的在回归/分类方程中看到非白噪声错误吗?如果不是,怎么能使用这个算法呢?
哇,如果这是可能的,为什么不接近100%的准确率呢?
将在本文中以简洁的方式回答这些问题。提升通常在弱学习器上进行,它们没有能力留下白噪声。其次,提升可能导致过拟合,所以需要在正确的点停止。
看看下面的图表:
从第一个框开始。看到一条垂直线,它成为第一个弱学习器。现在总共有3/10的误分类观测值。现在开始给这3个加上误分类的观测值更高的权重。现在,正确分类它们变得非常重要。因此,垂直线向右边缘。重复这个过程,然后以适当的权重组合每个学习器。
如何给观测值分配权重?总是从一个均匀分布的假设开始。让称之为D1,对于所有n个观测值都是1/n。
步骤1. 假设一个alpha(t)
步骤2:得到一个弱分类器h(t)
步骤3:更新下一步的人口分布
其中,
步骤4:使用新的人口分布再次找到下一个学习器
害怕步骤3的数学吗?让为分解。简单地看指数中的参数。Alpha是一种学习率,y是实际响应(+1或-1),h(x)将是由学习器预测的类别。本质上,如果学习器上次预测错误,指数就变成1*alpha,否则是-1*alpha。本质上,如果上次预测错误,权重可能会增加。那么接下来呢?
步骤5:重复步骤1-4,直到没有假设可以进一步改进。
步骤6:使用到目前为止使用的所有学习器,对前沿进行加权平均。但是权重是什么?权重就是alpha值。Alpha的计算如下:
library(caret)
rm(list=ls())
setwd("C:\\Users\\ts93856\\Desktop\\AV")
library(Metrics)
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)
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(trainData$Disbursed,gbm_dev)
auc(trainData_ens1$Disbursed,gbm_ITV1)
auc(testData_ens1$Disbursed,gbm_ITV2)
运行这段代码后,会发现所有的AUC都非常接近0.84。将特征工程留给,因为比赛还在进行中。欢迎使用这段代码来竞争。GBM是最广泛使用的算法。XGBoost是另一个更快的提升学习器版本,将在将来的文章中介绍。
见过的提升学习器非常快速且高效。它们从未让在Kaggle和其他平台上获得高初始分数感到失望。但这一切都归结于如何进行特征工程。