根据Boosting的理论,通过弱分类器的组合可以得到强分类器。只要该弱分类器稍稍比随机猜测好即可,下面来看看如何一步一步的实现AdaBoost。
给样本分配权重
AdaBoost是顺序学习,每一轮的训练的样本的权重都是根据该样本在前一轮的表现经过了重新的分配。对于第一轮,我们自然就想到赋予每个样本相等的权重。
代码实现为:
D = mat(ones(m,1)/m) #这里将m替换为每一轮训练样本的个数。
至于如何更新下一轮的样本权重,在后续有说明。
计算基本分类器的误差率
我们假设共有
k=1,2,...,K
轮训练,用
Gk(x)
表示基于数据集
Dk
训练出来的基本分类器。则我们用
ek
来表示弱分类器
Gk(x)
的分类误差率:
代码实现为:
errArr = mat(ones((m, 1)))
errArr[predictedVals == labelMat] = 0 #将错误的预测标记为0
weightedError = D.T * errArr #这个就是误差率e_k
基本分类器的权重
经过K轮的训练就产生了多个基本分类器,我们如何为这些基本分类器分配系数呢?这里就看看它们各自在数据集上的表现,表现好的自然权重就大,表现不好就权重小些,甚至为 0 :
代码实现为:
alpha = float(0.5 * log((1.0 - error) / max(error, 1e-16)))
# 上面代码中的max(error, 1e-16) 是为了防止error为0的情况
通过该权值系数我们可以发现,当 ek=1/2 时, αk=0 也就是说该基本分类器比瞎蒙好,我们就给它分配一个大于零的系数。
更新样本的权重
我们在上面的为样本分配权重一小节中只提到了初始化各样本权重,也就是说首轮各样本的权重,那么下一轮的权重该如何分配呢?自然的考虑到要加大上一轮中被误分类的样本的权重,减小正确分类的样本的权重。
容易看到,分母只是一个归一化因子,我们看分子:
假设上一轮中第
i
个样本被正确分类,则在该轮被调整为:
假设上一轮中第 i 个样本被错误分类,则在该轮被调整为:
通过上面的对比可以发现,当在上一轮中第
i
个样本
被分类正确:则
被错误分类:则
wk+1,i>wki
,即增加了该样本在本轮中的权重
代码实现:
# 下面的classEst即为G_k(x),multiply为对应元素相乘
expon = multiply(-1 * alpha * mat(classLabels).T, classEst)
D = multiply(D, exp(expon))
D = D / D.sum()
组合 K 个基本分类器
全部分类器训练完毕之后,将它们按各自的系数加权求和即得到了最终的分类器:
代码实现:
for i in range(numIt):
...
aggClassEst += alpha * classEst
aggErrors = multiply(sign(aggClassEst) != mat(classLabels).T, ones((m, 1)))
errorRate = aggErrors.sum() / m #组合分类器的错误率
参考资料
[1] 《统计机器学习》 李航
[2] 《机器学习实战》Peter Harrington