机器学习之十大经典算法(五) AdaBoost算法
一、AdaBoost算法简介:
Adaboost 是一种迭代算法,本身是通过改变数据分布来实现的,它根据每次训练集之中每个样本的分类是否正确,以及上次的总体分类的准确率,来确定每个样本的权值。其核心思想是针对同一个训练集训练不同的分类器(弱分类器),然后把这些弱分类器集合起来,构成一个更强的最终分类器(强分类器)。其算法本身是通过改变数据分布来实现的,它根据每次训练集之中每个样本的分类是否正确,以及上次的总体分类的准确率,来确定每个样本的权值。将修改过权值的新数据集送给下层分类器进行训练,最后将每次训练得到的分类器最后融合起来,作为最后的决策分类器。
对于boosting算法,需要解决好两个主要问题:
1. 如何调整训练集,使得在训练集上训练的弱分类器得以进行;
2. 如何将训练得到的各个弱分类器联合起来形成强分类器。
整个过程如下所示:
1. 先通过对 N 个训练样本的学习得到第一个弱分类器 ;
2. 将分错的样本和其他的新数据一起构成一个新的N 个的训练样本,通过对这个样本的学习得到第二个弱分类器;
3. 将 和 都分错了的样本加上其他的新样本构成另一个新的 N个的训练样本,通过对这个样本的学习得到第三个弱分类器;
4. 如此反复,最终得到经过提升的强分类器。
Adaboost是一种有很高精度的分类器,优点:
(1)可以使用各种方法构建子分类器,Adaboost算法提供的是框架。
(2)利用简单分类器进行组合,计算出的结果是可以理解的。
(3)简单,不用做特征筛选。
(4)不用担心overfitting(过拟合)。
目前 AdaBoost 算法广泛的应用于人脸检测、目标识别等领域。
二、AdaBoost算法实现原理:
1. 给定训练样本集S,其中X和Y分别对应于正例样本和负例样本;T为训练的最大循环次数;
2. 初始化样本权重为1/n ,即为训练样本的初始概率分布;
3. 第一次迭代:
(1)训练样本的概率分布相当,训练弱分类器;
(2)计算弱分类器的错误率;
(3)选取合适阈值,使得误差最小;
(4)更新样本权重;
经T次循环后,得到T个弱分类器,按更新的权重叠加,最终得到的强分类器,具体思路大家可以参考相关文献资料,这里不赘述了。
三、Sklearn中Adaboost算法实现代码。
scikit-learn中Adaboost类库比较直接,就是AdaBoostClassifier和AdaBoostRegressor两个,从名字就可以看出AdaBoostClassifier用于分类,AdaBoostRegressor用于回归。其中,AdaBoostClassifier使用了两种Adaboost分类算法的实现,SAMME和SAMME.R。而AdaBoostRegressor则使用了我们原理篇里讲到的Adaboost回归算法的实现,即Adaboost.R2。
基本步骤:
①选择数据:将你的数据分成三组:训练数据、验证数据和测试数据
②模型数据:使用训练数据来构建使用相关特征的模型
③验证模型:使用你的验证数据接入你的模型
④测试模型:使用你的测试数据检查被验证的模型的表现
⑤使用模型:使用完全训练好的模型在新数据上做预测
⑥调优模型:使用更多数据、不同的特征或调整过的参数来提升算法的性能表现
写了个AdaBoost类方便大家使用,代码如下:
# -*- coding: utf-8 -*-
“””
jcy 2018.6.5
“””
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble importAdaBoostClassifier
from sklearn.tree importDecisionTreeClassifier
from sklearn.datasets importmake_gaussian_quantiles
class MyAdaBoost:
def __init__(self,moudle=AdaBoostClassifier()):
self.moudle=moudle
def loadSet(self):
X1, y1 = make_gaussian_quantiles(cov=2.0,n_samples=600,n_features=2,n_classes=2, random_state=1)
# 生成2维正态分布,生成的数据按分位数分为两类,600个样本,2个样本特征均值都为3,协方差系数为2
X2, y2 = make_gaussian_quantiles(mean=(4, 4), cov=1.5,n_samples=600,n_features=2, n_classes=2, random_state=3)
X = np.concatenate((X1, X2)) #将两组数据合成一组数据,默认按列合并。
y = np.concatenate((y1, – y2 + 1)) #将两组数据合成一组数据,默认按列合并。
plt.scatter(X[:, 0], X[:, 1], marker=’8′, c=y)
self.X = np.array(X)
self.y = np.array(y)
def data_select_train_test(self):
from sklearn import cross_validation
self.X_train, self.X_test, self.y_train, self.y_test =cross_validation.train_test_split(self.X,self.y, test_size=0.25,random_state=5)
def fit_X_Complete(self):
self.moudle.fit(self.X, self.y)
self.y_pred = self.moudle.predict(self.X)
print(“Score:”,self.moudle.score(self.X,self.y))
def fit_X_train(self):
self.moudle.fit(self.X_train, self.y_train)
self.y_test_pred = self.moudle.predict(self.X_test)
def Plot_Meshgrid(self):
x_min, x_max = self.X[:, 0].min() – 1, self.X[:, 0].max() + 1
y_min, y_max = self.X[:, 1].min() – 1, self.X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02),np.arange(y_min,y_max, 0.02))
Z = self.moudle.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
cs = plt.contourf(xx, yy, Z, cmap=plt.cm.Paired)
plt.scatter(X[:, 0], X[:, 1], marker=’o’, c=y)
plt.show()
bdt =AdaBoostClassifier(DecisionTreeClassifier(max_depth=2, min_samples_split=20,min_samples_leaf=5),
algorithm=”SAMME”,n_estimators=200, learning_rate=0.8)
Mybdt=MyAdaBoost(bdt)
Mybdt.loadSet()
Mybdt.fit_X_Complete()
Mybdt.Plot_Meshgrid()
dictD1={‘algorithm’:”SAMME”,’n_estimators’:300,’learning_rate’:0.8}
dictD2={‘algorithm’:”SAMME”,’n_estimators’:300,’learning_rate’:0.5}
dictD3={‘algorithm’:”SAMME”,’n_estimators’:600,’learning_rate’:0.7}
for yy in[“dictD1″,”dictD2″,”dictD3”]:
bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=2,min_samples_split=20, min_samples_leaf=5),
**eval(yy))
Mybdt.moudle=bdt
Mybdt.fit_X_Complete()