集成学习分类
boosting
特点
串行,各个基分类器之间有依赖
作用
boosting:提升,作用是每一次训练的时候都对上一次的训练进行改进提升,在训练的过程中,这K个“专家”之间是有依赖性的,当引入第K个专家(第K个分类器)的时候,实际上是对前K-1个专家的优化。
基本思路
将基分类器层层叠加,每一层在训练的时候,对前一层基分类器分错的样本,给予更高的权重。测试时,根据各层分类器的结果的加权得到最终结果。
bagging
特点
各个基分类器之间无强依赖,并行,集体决策。为了让基分类器之间相互独立,将训练集分为若干子集(当训练样本数量较少时,子集之间可能有交叠)。
作用
在做投票选举的时候可以并行计算,也就是K个专家在做判断的时互相独立,不存在依赖性。
基本思路
集体决策,每个个体都进行单独学习,学习的内容可以相同,也可以不同,也可以部分重叠。但由于个体之间存在差异性,最终做出的判断不回完全一致。在最终做决策时,每个个体单独做出判断,再通过投票的方式做出最后的集体决策。
偏差与方差
监督学习中,泛化误差来源于偏差和方差
偏差:
由所有采样得到的大小为m的训练数据集训练出的所有模型的输出的平均值和真实模型输出之间的偏差。
通常是由于我们对学习算法做了错误的假设所导致的,如真实模型是某个二次函数,但我们假设的模型是一次函数。
由偏差带来的误差通常在训练误差上就能体现出来
方差
由所有采样得到的大小为m的训练数据集训练出的所有模型的输出的方差。
方差通常是由于模型的复杂度相对于训练样本数m过高导致的
由方差带来的误差通常体现在测试误差相对于训练误差的增量上
集成学习与偏差和方差的关系
基分类器(弱分类器)的错误是偏差和方差两种错误之和。
偏差:由于分类器的表达能力有限导致的系统性错误,表现在训练误差不收敛。
方差:由于分类器对于样本分布过于敏感,导致在训练样本数较少时,产生过拟合。
Boosting–偏差
通过逐步聚焦于基分类器分错的样本,减少集成分类器的偏差。
在训练好一个弱分类器之后,我们需要计算弱分类器的错误或者残差,作为下一个分类器的输入。这个过程本身就是在不断减小损失函数,来使模型不断逼近”靶心“,使得模型偏差不断降低。但Boosting的过程不会显著降低方差,因为训练过程使得各弱分类器之间是强相关的,缺乏独立性。
Bagging–方差
采取分而治之的策略,通过对训练样本多次采样,并分别训练出多个不同模型,然后做综合,减少集成分类器的方差。假设所有基分类器出错的概率是独立的,在某个测试样本上,用简单多数投票方法来集成结果,超过半数基分类器出错的概率会随着基分类器的数量增加而下降。
Bagging是再抽样,然后在每个样本上训练出来的模型取平均。
- 假设有n个随机变量,方差记为
。在随机变量完全独立的情况下,n个随机变量的方差为
也即方差减小到了原来的1/n。
- 由于模型不能完全独立,为了追求模型的独立性,随机森林每次选取节点分裂属性时,会随机抽取一个属性子集,而不是从所有属性中选取最优属性,这就是为了避免弱分类器之间过强的相关性。通过训练集的重采样也能带来弱分类器之间的一定独立性。
集成学习的步骤和例子
3个步骤
- 找到误差互相独立的基分类器
- 训练基分类器
- 合并基分类器的结果
基分类器的选择
任何分类模型都可以作为基分类器,但树形模型由于结构简单且较易产生随机性所以比较常用。
最常用的基分类器是决策树,原因:
(1)决策树可以较为方便地将样本的权重整合到训练过程中,而不需要使用过采样得方法来调整样本权重。
(2)决策树的表达能力和泛化能力,可以通过调节树的层数来做折中。
(3)(a)数据样本的扰动对于决策树的影响较大,因此不同子样本集合成的决策树基分类器随机性较大,这样的”不稳定学习器“更适合作为基分类器。(b)在决策树结点分裂的时候,随机地选择一个特征子集,从中找出最优分裂属性,很好地引入了随机性。
除了决策树,神经网络也适合,主要原因:不稳定和随机性
可否将随机森林中的基分类器由决策树替换为线性分类器或者Knn
Bagging主要的好处就是集成后的分类器的方差,比基分类器的小。
Bagging所采用的基分类器最好是对样本分布较为敏感的(即所谓不稳定的分类器)。线性分类器或者KNN都是较为稳定的分类器,本身方差就不大,所以以它们为基分类器使用Bagging并不能在原有基分类器的基础上获得更好的表现,甚至可能因为Bagging的采样,使得他们在训练中更难收敛,从而增大了集成分类器的偏差
合并基分类器的方法:voting和stacking
voting:投票,将获得最多选票的结果作为最终的结果
stacking:串行,把前一个基分类器的结果输出到下一个分类器,将所有基分类器的输出结果相加作为最终的输出。
boosting例子:Adaboost和梯度提升决策树
AdaBoost
- 确定基分类器:ID3决策树作为基分类器。
- 训练基分类器:假设训练集为{xi,yi},i=1,2,…,N,其中
并且有T个基分类器,可以按照如下过程训练基分类器。
1)初始化采样分布。
关于采样分布,
2)令t=1,2,…,T循环:
(1)从训练集中,按照Dt分布,采样出子集
(2)用St训练出基分类器ht;
(3)计算ht的错误率,其中I[]为判别函数
(4)计算基分类器ht的权重(错误率越小,权重越大)
(5)设置下一次采样
并将它归一化为一个概率分布函数
- 合并基分类器:给定一个未知样本z,输出分类结果为加权投票的结果
符号函数,当x>0,函数值为1;x<0,函数值为-1;x==0,函数值为0
体现出的Boosting思想
对分类正确的样本降低了权重,对分类错误的样本升高或者保持不变。在最后模型融合的过程中,也根据错误率对基分类器进行加权融合。错误率低的分类器拥有更大的话语权。
代码
'''
在sklearn中使用AdaBoost
from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import AdaBoostRegressor
AdaBoostClassifier(base_estimator=None, n_estimators=50, learning_rate=1.0, algorithm=’SAMME.R’, random_state=None)
base_estimator:代表弱分类器,默认决策树
n_estimators:算法的最大迭代次数,也是分类器的个数,每一次迭代都会引入一个新的弱分类器来增加原有的分类器的组合能力。默认是 50。
random_state:代表随机数种子的设置,默认是 None。随机种子是用来控制随机模式的,当随机种子取了一个值,也就确定了一种随机规则,其他人取这个值可以得到同样的结果。如果不设置随机种子,每次得到的随机数也就不同。
AdaBoostRegressor(base_estimator=None, n_estimators=50, learning_rate=1.0, loss=‘linear’, random_state=None)
回归和分类的参数基本是一致的,不同点在于回归算法里没有 algorithm 这个参数,但多了一个 loss 参数。
loss 代表损失函数的设置,一共有 3 种选择,分别为 linear、square 和 exponential,它们的含义分别是线性、平方和指数。默认是线性。一般采用线性就可以得到不错的效果。
'''
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.datasets import load_boston
from sklearn.ensemble import AdaBoostRegressor
# 加载数据
data=load_boston()
# 分割数据
train_x, test_x, train_y, test_y = train_test_split(data.data, data.target, test_size=0.25, random_state=33)
# 使用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))
# 使用决策树回归模型
dec_regressor=DecisionTreeRegressor()
dec_regressor.fit(train_x,train_y)
pred_y = dec_regressor.predict(test_x)
mse = mean_squared_error(test_y, pred_y)
print("决策树均方误差 = ",round(mse,2))
# 使用KNN回归模型
knn_regressor=KNeighborsRegressor()
knn_regressor.fit(train_x,train_y)
pred_y = knn_regressor.predict(test_x)
mse = mean_squared_error(test_y, pred_y)
print("KNN均方误差 = ",round(mse,2))
n_estimtosrs = 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_dump = DecisionTreeClassifier(max_depth=1, min_samples_leaf=1)
dt_dump = dt_dump.fit(train_x, train_y)
dt_dump_err = 1.0 - dt_dump.score(test_x, test_y)
dt = DecisionTreeClassifier()
dt = dt.fit(train_x, train_y)
dt_err = 1.0 - dt.score(test_x, test_y)
ada = AdaBoostClassifier(base_estimator=dt_dump, n_estimators=n_estimtosrs)
ada = ada.fit(train_x, train_y)
print("弱决策树",dt_dump_err)
print("决策树",dt_err)
梯度提升决策树GDBT
核心思想
从错误中学习,以决策树(CART)为基学习器,每一棵树学的是之前所有树结论和的残差,这个残差就是一个加预测值后能得真实值得累加量。是迭代树而不是分类树。
基本思想
根据当前模型损失函数的负梯度信息来训练新加入的弱分类器,然后将训练好的弱分类器以累加的形式结合到现有模型中。
梯度提升基本流程:在每一轮迭代中,首先计算出当前模型在所有样本上的负梯度,然后以该值作为目标训练一个新的弱分类器进行拟合并计算出该弱分类器的权重,最终实现对模型的更新。
由于GDBT是利用残差训练的,在预测的过程中,需要把所有树的预测值加起来,得到最终的预测结果。
GDBT使用梯度提升作为训练方法,而逻辑回归中使用梯度下降,两者的区别
两者都是在每一轮迭代中,使用损失函数相对于模型的负梯度方向的信息来对当前模型进行更新。
不同的是:
在梯度下降中,模型是以参数化形式表示,从而模型的更新等价于参数的更新
在梯度上升中,模型并不需要进行参数化表示,而是直接定义在函数空间中,从而大大扩展了可以使用的模型种类。
GDBT的优缺点
优点:
- 预测阶段的计算速度快,树与树之间可并行化计算
- 在分布稠密的数据集上,泛化能力和表达能力都很好
- 采用决策树作为弱分类器使得GBDT模型具有较好的解释性和鲁棒性,能够自动发现特征间的高阶关系,并且也不需要对数据进行特殊的预处理如归一化等
缺点:
- 在高维稀疏的数据集上,表现不如支持向量机或者神经网络
- GBDT在处理文本分类特征问题上,相对其他模型的优势不如他在处理数值特征时明显
- 训练过程需要串行训练,只能在决策树内部采用一些局部并行的手段提高训练速度
Bagging例子:随机森林
组合分类器
- 将多个分类器的结果进行多票表决或取平均值,以此作为最终的结果。
- 构建组合分类器的好处:
(1)提升模型精度:整合各个模型的分类结果,得到更合理的决策边界,减少整体错误率,实现更好的分类效果;
(2)处理过大或过小的数据集:数据集较大,可将数据集划分成多个子集,对子集构建分类器;当数据集较小时,通过自主采样从原始数据集采样产生多组不同的数据集,构建分类器;
(3)若决策边界过于复杂,则线性模型不能很好的描述真实情况。因此,对于特定区域的数据集,训练多个线性分类器,再将它们集成;
(4)比较适合处理多源异构数据
随机森林
随机主要体现在数据选取的随机性和特征选取的随机性
数据的随机选取
(1)从原始数据集中采取有放回的抽样(bootstrap),构造子数据集,子数据集扥数量和原始数据集的数量一样。不同的子数据集的元素可以重复,同一个子数据集中的元素也可以重复。
(2)利用子数据集构建子决策树,将这个数据放到每个子决策树中,每个子决策树输出一个结果。最后,如果有了新的数据需要通过随机森林得到分类结果,就可以通过子决策树的判断结果来投票,得到随机森林的输出结果。
待选特征的随机选取
类似于数据集的随机选取,随即森林中的子树的每一个分裂过程并未用到所有的待选特征,而是从所有的待选特征中随机选取一定的特征,之后再在随机选取的特征中选择最优的特征。这样能使随机森林中的决策树能不同,提升系统的多样性,从而提升分类性能。
优点:
随机森林对Bagging做了小改动,Bagging中基学习器的”多样性“仅通过样本扰动(对初始训练集采样)而来不同,随机森林中基学习器的多样性不仅来自样本扰动,还来自属性扰动,这就使得最终集成的泛化性能可通过个体学习器之间差异度的增加而进一步提升。