Bagging套袋法
随机森林就采用的套袋法,在Bagging中,通过对训练样本重新采样的方法得到不同的训练样本集,在这些新的训练样本集上分别训练学习器,学习器之间是独立的,最终合并每一个学习器的结果,作为最终的学习结果,Bagging方法的具体过程如下图所示:
在Bagging方法中,b个学习器之间彼此是相互独立的,这样的特点使得Bagging方法更容易并行。每个学习器权重都为1/b。
Bossting提升树
梯度提升树就采用的Boosting算法,与Bagging方法不同,在Boosting算法中,学习器之间是存在先后顺序的,同时,每一个样本是有权重的,初始时,每一个样本的权重是相等的。首先,第1个学习器对训练样本进行学习,当学习完成后,增大错误样本的权重,同时减小正确样本的权重,再利用第2个学习器对其进行学习,依次进行下去,最终得到b个学习器,最终,合并这b个学习器的结果,同时,与Bagging中不同的是,每一个学习器的权重也是不一样的。Boosting方法的具体过程如下图所示:
在Boosting方法中,最重要的方法包括:AdaBoost和GBDT。
AdBoosting
AdaBoost算法与Boosting算法不同,它是使用整个训练集来训练弱学习器,其中训练样本在每次迭代的过程中都会重新被赋予一个权重,在上一个弱学习器错误的基础上进行学习来构建一个更加强大的分类器。下面通过一个图来了解AdaBoost算法的工作过程。
adaboost相关例子代码实现
AdaBoost算法学习一个强分类器
导包
import numpy as np
from sklearn.ensemble import AdaBoostClassifier
from sklearn import tree
import matplotlib.pyplot as plt
%matplotlib inline
数据
X = np.arange(10).reshape(-1,1)
y = np.array([1,1,1,-1,-1,-1,1,1,1,-1])
display(X,y)
算法
ada = AdaBoostClassifier(n_estimators=3)
ada.fit(X,y)
ada.estimators_
画出第一棵树
plt.figure(figsize=(9,6))
_ = tree.plot_tree(ada[0])
y_ = ada[0].predict(X)
y_
真实值
误差率
# 误差率
e1 = np.round(0.1*(y != y_).sum(),4)
e1
计算第一颗树权重,权重越大,说明就越重要
# 计算第一颗树权重,权重越大,说明就越重要
# 随机森林中每棵树的权重一样的
# adaboost提升树中每棵树的权重不同
a1 = np.round(1/2*np.log((1-e1)/e1),4)
a1
更新权重
# 样本预测准确:更新的权重
w2 = 0.1*np.e**(-a1*y*y_)
w2 = w2/w2.sum()#归一化权重,让权重之和等于1
w2 = w2.round(4)
w2
由此可以看出,被误分类的数据的权重从之前的0.1增大到了0.1667
分类函数f1(x)= a1*G1(x) = 0.4236G1(x),G1(x)就是上图w1。
第二轮迭代
画第二棵树
plt.figure(figsize=(9,6))
_ = tree.plot_tree(ada[1])
此轮结果将3个数据划分错了。相应的权重都是0.0715。
计算误差率
# 计算误差率
e2 = 0.0715*3
e2
计算G系数
a2 = np.round(1/2*np.log((1 - e2)/e2),4)
a2
更新权重
y_ = ada[1].predict(X)
w3 = w2*np.e**(-a2*y*y_)
w3 = w3/w3.sum()
w3 = w3.round(4)
w3
依次类推,第3棵树
plt.figure(figsize=(9,6))
_ = tree.plot_tree(ada[2])
y_ = ada[2].predict(X)
y_
实际数值
误差率
e3 = (w3*(y_ != y)).sum()
e3
求树的权重
a3 = 1/2*np.log((1 - e3)/e3)
a3
三棵树的权重
display(a1,a2,a3)
弱分类器合并成强分类器
# 综上,将上面计算得到的a1、a2、a3各值代入G(x)中,
# G(x) = sign[f3(x)] = sign[ a1 * G1(x) + a2 * G2(x) + a3 * G3(x) ],
# 得到最终的分类器为:
# sign意思负号函数,大于等于0变成1,小于0变成-1
#G1,G2,G3代表树的预测值
G(x) = sign[f3(x)] = sign[ 0.4236G1(x) + 0.6496G2(x)+0.7514G3(x) ]。
y_predict = a1*ada[0].predict(X) + a2*ada[1].predict(X) + a3*ada[2].predict(X)
y_predict
np.sign(y_predict).astype(np.int)
# 使用模型
ada.predict(X)
由此可看,自己推的过程准确。