AmbiRF 2019-05-11
Boosting是一个提高任意给定学习算法准确度的方法。他是一种框架算法,主要是通过对样本集的操作获得样本子集,然后用弱分类算法在样本子集上训练生成一系列的弱分类器。在实际应用中,我们不必费力寻找预测精度高的算法,只需要找到一个比随机猜测略好的弱学习算法,通过Boosting算法就可以将其提升为强学习算法。
Boosting算法的思想是先赋予训练集中每个样本相同的权重,然后进行T次迭代,每次迭代后,对分类错误的样本加大重采样权重,使得在下一次的迭代中更加关注这些样本。这样训练的多个弱分类器进行加权融合,产生一个最后的结果分类器。在这T个弱小分类器中,每个分类器的准确率不一定很高,但他们联合后的结果有很高的准确率,这样便提高了该弱分类算法的准确率。单个弱分类器训练的时候,可以用相同的分类算法,也可以用不同的分类算法,这些算法一般是不稳定的弱分类算法,如神经网络(BP) ,决策树(C4.5)等。
另外,Boosting算法容易收到噪声的影响,这是因为在迭代过程中总是给噪声分配较大的权重,使得这些噪声在以后的迭代中受到更多的关注。Boosting算法也应该选择一个合适的迭代次数T,在某些情况下迭代次数过多容易发生过拟合,可以用交叉验证找到合适的迭代次数。再者,算法运行速度较慢。
自从Boosting算法出现以来,在机器学习领域备受关注,得到了很多应用。可以用于手写字体字符识别、语音识别、医疗诊断、人脸检测等方面。
而我们常常听到的AdaBoost是Boosting发展到后来最具代表性的一类。所谓AdaBoost,即Adaptive Boosting,是指弱分类器根据学习的结果反馈Adaptively调整假设的错误率,所以也不需要任何的先验知识就可以自主训练。下面主要介绍Adaboost算法。
Adaboost
Adaboost算法可以做分类也可以做回归,本文主要介绍分类。其基本思想就是:首先给出任意一个弱学习算法和训练集(x1 , y1),(x2 , y2),…,(xm ,ym),此处x表示样本空间,y为类别值。初始化时,Adaboost为训练集每个样本指定相同的权重为1/m。接着,调用弱学习算法进行T次迭代,每次迭代后,按照训练结果更新训练集每个样本的权重,对于分错的样本赋予较大的权重,使得下一次迭代更加关注这些训练例,从而得到一个预测函数序列h1,h2,…,ht,每个预测函数h,也赋予一个权重,预测效果好的,相应的权重越大。T次迭代之后,在分类问题中最终的预测函数H采用带权重的投票法产生。
GradientBoost
Gradient Boost与传统的Boost的区别是,每一次的计算是为了减少上一次的残差(residual),而为了消除残差,我们可以在残差减少的梯度(Gradient)方向上建立一个新的模型。所以说,在Gradient Boost中,每个新的模型的建立是为了使得之前模型的残差往梯度方向减少,与传统Boost对正确、错误的样本进行加权有着很大的区别。
下面介绍使用方法
Python版本:
1. Adaboost
使用类:
class sklearn.ensemble.AdaBoostClassifier(base_estimator=None, n_estimators=50,learning_rate=1.0, algorithm='SAMME.R', random_state=None)
参数介绍:
base_estimator :(default=DecisionTreeClassifier) 选择哪种若分类器,scikit-learn中的分类器都可以
n_estimators :integer, (default=50) 最大迭代次数
learning_rate :float, (default=1.0) 迭代次数的每个弱分类器权重设置参数
algorithm : {'SAMME', 'SAMME.R'},(default='SAMME.R') 'SAMME.R'的话弱分类器需要支持概率预测,比如逻辑回归;'SAMME'这个是针对离散的变量。
类中方法:
fit(X, y[, sample_weight])
predict(X)
predict_proba(X)
score(X, y[, sample_weight])
注:sckit-learn模型类中方法基本都是类似的,这里就不做介绍,可以看前面的小编写的文章。
使用实例:
#导入AdaBoostClassifier类
from sklearn.ensemble import AdaBoostClassifier
#导入决策树类
from sklearn.tree import DecisionTreeClassifier
import numpy as np
#导入我们需要的数据,scikit-learn自带数据
from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data
y = iris.target
#创建adaboost类
abc =AdaBoostClassifier(DecisionTreeClassifier(max_depth=1),algorithm="SAMME",n_estimators=200)
#拟合adaboost模型
abc.fit(X, y)
#输出每个特征的权重,可以用于特征选择
abc.feature_importances_
#预测
abc.predict([[4.4, 2.9, 1.4, 0.2],[5.9, 3.0, 5.1, 1.8]])
2.Gradient Boost
使用类:
class sklearn.ensemble.GradientBoostingClassifier(loss='deviance', learning_rate=0.1, n_estimators=100,subsample=1.0, min_samples_split=2, min_samples_leaf=1,min_weight_fraction_leaf=0.0, max_depth=3, init=None, random_state=None,max_features=None, verbose=0, max_leaf_nodes=None, warm_start=False,presort='auto')
这里不做详细介绍,使用方法与上面的差不多。
R语言版本:
1.可以用caret包里面的BoostingModels,如下
> model = train(form, data, method,trControl)
method = 'AdaBoost.M1' #adaboost
method = 'xgbTree' #extreme gradient boost
#这里我们adabag包里面的boosting函数来构建adaboost模型
> library(adabag)
#这里我们还是用R语言自带数据集iris
#随机取一些样本做训练集合
> sub = c(sample(1:50,40),sample(51:100,40),sample(101:150,40))
> train = iris[sub]
#剩下的做测试集
> test = iris[-sub]
#拟合adaboost模型,boos设置为TRUE表示每次迭代更新样本权重,mfinal为10表示迭代10次,也就是建立10个弱分类器
> adb = boosting(Species ~. ,data = iris, boos=TRUE,mfinal = 10)
#查看feature的权重,可以用于特征选择
> adb$importance
#测试
> predict_result = predict(adb,test[1:4],type="class")
> table(predict_result$class,test$Species)
#这个包有个自带做交叉验证的函数boosting.cv,可以用于找到合适的迭代次数
> for (i in c(5,10,15,20)){
adbcv =boosting.cv(Species ~., v = 5, data = iris, mfinal = i)
cat("mfinal =",i,", error = ",adbcv$error,'')
}
#可以看到最大迭代次数为5的时候,就最好。
2. 用xgboost包可以做extremegradient boost,有兴趣可以看看说明文档,用法,也跟上述差不多。