AdaBoost算法
集成算法通常有两种方式,分别是投票选举(bagging)和再学习(boosting)。
bagging的方式在做投票选举的时候可以并行计算,多个弱分类器单元的决策是相互独立的,不存在依赖性。
boosting是每次训练的时候都对上一次训练进行改进提升,在训练过程中弱分类器单元之间存在依赖性,当引入第K个分类器的时候,实际上是对前K-1个分类器的优化。
AdaBoost即为自适应提升算法,是对boosting算法的一种实现。
通过一系列弱分类器根据不同权重组合而成一个强分类器。
假设弱分类器为Gi(x),它在强分类器中的权重是αi,则得出的强分类器f(x)为:
f
(
x
)
=
∑
i
=
1
n
α
i
G
i
(
x
)
f(x)=\sum_{i=1}^{n} \alpha_{i} G_{i}(x)
f(x)=i=1∑nαiGi(x)
如果弱分类器的分类效果好,则权重应该较大,若效果一般权重应该降低。则可基于弱分类器对样本的分类错误率来决定其权重,公式表示为:
α
i
=
1
2
log
1
−
e
i
e
i
\alpha_{i}=\frac{1}{2} \log \frac{1-e_{i}}{e_{i}}
αi=21logei1−ei
其中ei代表第i个弱分类器的分类错误率
AdaBoost是通过改变样本的数据分布来实现在每次训练迭代过程中选择最优的弱分类器。
AdaBoost会判断每次训练的样本是否分类正确,对于正确分类的样本,降低它的权重,对于错误分类的样本,增加它的权重。再基于上一次得到的分类正确率,来确定这次训练样本中每个样本的权重,然后将修改过权重的数据集传递到下一层的分类器进行训练。因此可以通过每一轮训练样本的动态权重,让训练的焦点集中到难分类的样本上,最终得到的弱分类器的组合更容易得到更高的分类准确率。
AdaBoost的调用:
分类:
from sklearn.ensemble import AdaBoostClassifier
回归:
from sklearn.ensemble import AdaBoostRegressor
创建AdaBoost分类器:
AdaBoostClassifier(base_estimator=None, n_estimators=50, learning_rate=1.0, algorithm='SAMME.R', random_state=None)
- base_estimator:弱分类器,默认决策树
- n_estimators:算法最大迭代次数,也是分类器的个数,每一次迭代都会引入一个新的弱分类器来增加原有分类器的组合能力,默认50
- learning_rate:学习率
- algorithm:采用的boosting算法,有SAMME和SAMME.R两种,默认后者
- random_state:代表随机数种子的设置,默认None
创建回归:
AdaBoostRegressor(base_estimator=None, n_estimators=50, learning_rate=1.0, loss='linear', random_state=None)
- loss函数可以有linear、square、exponential三种选择
实例用AdaBoost对房价进行预测:
from sklearn.ensemble import AdaBoostRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.datasets import load_boston
#加载数据
data = load_boston()
#分割数据
train_x,test_x,train_y,test_y = train_test_split(data.data, data.target, test_size=0.3)
#使用ADABOOST模型进行回归
regressor = AdaBoostRegressor()
regressor.fit(train_x, train_y)
pred_y = regressor.predict(test_x)
mse = mean_squared_error(test_y, pred_y)
print('房价预测结果:',pred_y)
print('均方误差:', round(mse,2))
AdaBoost与决策树模型对比:
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.metrics import zero_one_loss
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import AdaBoostClassifier
n_estimators = 200
X, y = datasets.make_hastie_10_2(n_samples=12000, random_state=1)
test_x, test_y = X[2000:],y[2000:]
train_x, train_y = X[:2000],y[:2000]
dt_stump = DecisionTreeClassifier(max_depth=1,min_samples_leaf=1)
dt_stump.fit(train_x,train_y)
dt_stump_err = 1.0 - dt_stump.score(test_x, test_y)
dt = DecisionTreeClassifier()
dt.fit(train_x, train_y)
dt_err = 1.0 - dt.score(test_x, test_y)
ada = AdaBoostClassifier(base_estimator=dt_stump, n_estimators=n_estimators)
ada.fit(train_x, train_y)
fig = plt.figure()
plt.rcParams['font.sans-serif'] = ['SimHei']
ax = fig.add_subplot(111)
ax.plot([1, n_estimators],[dt_stump_err]*2, 'k-', label=u'决策树弱分类器错误率')
ax.plot([1,n_estimators], [dt_err]*2, 'k--', label=u'决策树模型错误率')
ada_err = np.zeros((n_estimators,))
for i, pred_y in enumerate(ada.staged_predict(test_x)):
ada_err[i] = zero_one_loss(pred_y, test_y)
ax.plot(np.arange(n_estimators)+1, ada_err, label='AdaBoost Test错误率',color='orange')
ax.set_xlabel('迭代次数')
ax.set_ylabel('错误率')
leg = ax.legend(loc='upper right', fancybox=True)
plt.show()