集成学习
1. 集成学习概念
集成学习是解决有监督机器学习任务的一类方法,它的思路是基于多个学习算法的集成来提升预测结果,它通过多个模型的组合形成一个精度更高的模型,参与组合的模型成为弱学习器(基学习器)。训练时,使用训练集依次训练出这些弱学习器,对未知的样本进行预测时,使用这些弱学习器联合进行预测。
集成学习通过建立几个模型来解决单一预测问题。它的工作原理是 生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后结合成组合预测,因此优于任何一个单分类的做出预测。
2. 集成学习分类的串行和并行学习算法
集成学习算法一般分为:
bagging(同质基学习器并行)----降低方差
boosting(同质基学习器串行)— 降低偏差
Stacking(相当于异质基学习器叠加)
Bagging 与 Boosting的对比
区别一:数据方面
- Bagging:有放回采样
- Boosting:全部数据集, 重点关注前一个弱学习器不足
区别二:投票方面
- Bagging:平权投票
- Boosting:加权投票
区别三:学习顺序
- Bagging的学习是并行的,每个学习器没有依赖关系
- Boosting学习是串行,学习有先后顺序
集成学习分两种:
(1)利用相同的训练数据同时搭建多个独立的分类模型,然后通过投票的方式,以少数服从多数的原则做出最终的分类决策。随机森林就是这种方式,即在相同训练数据上同时随机选取特征搭建多颗决策树。
(2)按一定的次序搭建多个分类模型。这些模型之间彼此存在依赖关系。一般后一个模型的加入都需要对现有的集成模型有一定贡献,进而不断提高更新过后的集成模型性能,并借助多个弱分类器搭建出强分类器。代表有Bossting(AdaBoost)算法。该算法与第一种的随机森林主要区别在于每一颗决策树在生成的过程中都会尽可能降低模型在训练集上的拟合或训练误差。
3. 集成学习关键要素
集成算法(Ensemble Learning)思想:通过构建并结合多个学习器来完成学习任务,有时候我们也叫作“多分类器系统”。如下图C1,C2都是某一种个体的分类器,我们采用某种策略将他们组合起来。
个体的分类器由一个现有的学习算法从训练数据产生,例如:C4.5决策树算法,我们一般把个体分类器全部为同种的分类器称为“同质的”,如全部为决策树模型。
同质的集成学习中的个体学习器称为“基学习器(base learner)”,相应的算法称为基学习算法。
反之,集成中包含不同种的学习器,我们称之为“异质”的,异质集成中的个体学习器包含不同的学习算法组成的,这种情况下的学习器称为**“组合学习器”**。
集成学习通过将多个学习器组合,常获得比单一学习器显著优越的泛化性能。这对弱学习器特别明显,这里的弱学习器我们一般会使用决策树,BP神经网络和逻辑回归,有时候SVM也可以作为个体学习器。
4. 集成学习器性能评估
考虑一个例子:二分类问题中,假定三个分类器在三个测试样本上表现,如下图所示。打对勾的表示正确分类,打叉号的表示分类错误。集成学习的结果通过投票法voting产生。即少数服从多数。
第一个图中每个分类器有66.6%的精度,但集成学习却达到了100%。第二个图中三个分类器没有差别,但是集成之后性能却没有什么提高。第三幅图中每个分类器的精度都只有33.3%,集成学习的结果更糟糕。
这个例子我们可以总结出:要获得好的集成,个体学习器应有一定的 准确性 ,即学习器不能太坏,并且要有“多样性”,即学习器之间具有 差异 。
1. 基础学习器之间要存在差异性。
2. 基础学习器的能力不需要很强,只需要比随机猜测 0.5 高一点就行。
5. 集成算法多样性
集成学习中,个体学习器多样性越大越好。通常为了增大个体学习器的多样性,在学习过程中引入随机性。常用的方法包括:对数据样本进行扰动、对输入属性进行扰动、对算法参数进行扰动。
5.1 数据样本扰动
给定数据集,可以使用采样法从中产生出不同的数据子集。然后在利用不同的数据子集训练出不同的个体学习器。
该方法简单有效,使用广泛。
(1)数据样本扰动对于**“不稳定学习器”很有效**。“不稳定学习器”是这样一类学习器:训练样本稍加变化就会导致学习器有显著的变动,如决策树和神经网络等。
(2)数据样本扰动对于“稳定学习器”无效。“稳定学习器”是这样一类学习器:学习器对于数据样本的扰动不敏感,如线性学习器、支持向量机、朴素贝叶斯、K近邻学习器等。
如Bagging算法就是利用Bootstrip抽样完成对数据样本的自助采样。
5.2 输入属性的扰动
训练样本通常由一组属性描述,可以基于这些属性的不同组合产生不同的数据子集,然后在利用这些数据子集训练出不同的个体学习器。
(1)若数据包含了大量冗余的属性,则输入属性扰动效果较好。此时不仅训练出了多样性大的个体,还会因为属性数量的减少而大幅节省时间开销。同时由于冗余属性多,即使减少一些属性,训练个体学习器也不会很差。
(2)若数据值包含少量属性,则不宜采用输入属性扰动法。
5.3 算法参数的扰动
通常可以通过随机设置不用的参数,比如对模型参数加入小范围的随机扰动,从而产生差别较大的个体学习器。
在使用交叉验证法(GridSearch网格搜索)来确定基学习器的参数时,实际上就是用不同的参数训练出来了多个学习器,然后从中挑选出效果最好的学习器。集成学习相当于将所有这些学习器利用起来了。
随机森林学习器就结合了数据样本的扰动及输入属性的扰动。
Bagging 和随机森林
1. Bagging 框架
1.1 算法引入
Baggging 框架通过有放回的抽样产生不同的训练集,从而训练具有差异性的弱学习器,然后通过平权投票、多数表决的方式决定预测结果。
Bagging 使用 bootstrap 采样, 会存在大约 1/3 左右的数据未被选中用于训练弱学习,这部分未被选中的数据被称为 oob(out of bag), 即:包外估计数据集。
OOB 数据集可以作为验证集,用来辅助树的剪枝、或者评估树泛化能力。
1.2 算法总结
Bagging基本流程:通过上述自助采样,采出T个含m个训练样本的采样集,然后基于每个采样集训练出一个基学习器,在将这些基学习器进行组合。
在对预测输出进行结合的时候,Bagging通常对分类任务使用简单投票法,对回归任务进行简单的平均法。但是如果投票个数一致,则最简单的做法是随机选择一个类别,当然也可以进一步考察学习器投票的置信度来确定最终的分类。
- 分类任务采用简单投票法:即每个基学习器一票
- 回归问题使用简单平均法:即每个基学习器的预测值取平均值
基本分类器可以是决策树,逻辑回归等基分类器。
对于稳定性不好的分类器很实用,通过多数投票,减小了泛化误差,而对于稳定的分类器,集成效果并不明显。
1.3 Bagging性能
(1)Bagging是一个很高效的集成学习算法
(2)Bagging与AdaBoost只适用于二分类不同,它能不经修改地用于多分类、回归任务。
(3)自助bootstrap采样过程还给Bagging带来了另一个优点:由于每个基学习器只使用了初始训练集中约63.2%的样本,剩下的约36.8%样本可用作验证集来泛化性能进行“包外样本评估(即:不同于训练数据的样本)”。
(4)从偏差-方差分解角度看,Bagging主要关注降低方差,因此他在不剪枝决策树、神经网络等易受样本扰动的学习器上效果更为明显。
2. 随机森林
2.1 随机森林 介绍
随机森林是基于 Bagging 思想实现的一种集成学习算法,它采用决策树模型作为每一个基学习器。其构造过程:
- 训练:
- 有放回的产生训练样本
- 随机挑选 n 个特征(n 小于总特征数量)
- 预测:平权投票,多数表决输出预测结果
- 说明:
(1)随机森林的方法即对训练样本进行了采样,又对特征进行了采样,充分保证了所构建的每个树之间的独立性,使得投票结果更准确。
(2)随机森林的随机性体现在每棵树的训练样本是随机的,树中每个节点的分裂属性也是随机选择的。有了这2个随机因素,即使每棵决策树没有进行剪枝,随机森林也不会产生过拟合的现象。 - 随机森林中有两个可控制参数:
- 森林中树的数量(一般选取值较大)
- 抽取的属性值m的大小。
思考
- 为什么要随机抽样训练集?
如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样。
- 为什么要有放回地抽样?
如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是“有偏的”,都是绝对“片面的”(当然这样说可能不对),也就是说每棵树训练出来都是有很大的差异的;而随机森林最后分类取决于多棵树(弱分类器)的投票表决。
2.2 随机深林 API
ensemble里面都是集成学习的相关算法
sklearn.ensemble.RandomForestClassifier()
- n_estimators:决策树数量,(default = 10)
- Criterion:决策树划分依据,entropy、或者 gini, (default = gini)
- max_depth:指定树的最大深度,(default = None 表示树会尽可能的生长)
- max_features="auto”, 决策树构建时使用的最大特征数量
- If “auto”, then
max_features=sqrt(n_features)
. - If "sqrt", then
max_features=sqrt(n_features)
(same as “auto”). - If “log2”, then
max_features=log2(n_features)
. - If None, then
max_features=n_features
.
- If “auto”, then
- bootstrap:是否采用有放回抽样,如果为 False 将会使用全部训练样本,(default = True)
- min_samples_split: 结点分裂所需最小样本数,(default = 2)
- 如果节点样本数少于min_samples_split,则不会再进行划分.
- 如果样本量不大,不需要设置这个值.
- 如果样本量数量级非常大,则推荐增大这个值.
- min_samples_leaf: 叶子节点的最小样本数,(default = 1)
- 如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝.
- 较小的叶子结点样本数量使模型更容易捕捉训练数据中的噪声.
- min_impurity_split: 节点划分最小不纯度
- 如果某节点的不纯度(基尼系数,均方差)小于这个阈值,则该节点不再生成子节点,并变为叶子节点.
- 一般不推荐改动默认值1e-7。
上面决策树参数中最重要的包括
- 最大特征数 max_features,
- 最大深度 max_depth,
- 节点最少样本数 min_samples_split
- 叶子节点最少样本数: min_samples_leaf。
2.3 随机森林的Sklearn实战
这里使用泰坦尼克号案例实战:
#1.数据导入
#1.1导入数据
import pandas as pd
#1.2.利用pandas的read.csv模块从互联网中收集泰坦尼克号数据集
titanic=pd.read_csv("data/泰坦尼克号.csv")
titanic.info() #查看信息
#2人工选择特征pclass,age,sex
X=titanic[['Pclass','Age','Sex']]
y=titanic['Survived']
#3.特征工程
#数据的填补
X['Age'].fillna(X['Age'].mean(),inplace=True)
X = pd.get_dummies(X)
#数据的切分
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test =train_test_split(X,y,test_size=0.25,random_state=22)
#4.使用单一的决策树进行模型的训练及预测分析
from sklearn.tree import DecisionTreeClassifier
dtc=DecisionTreeClassifier()
dtc.fit(X_train,y_train)
dtc_y_pred=dtc.predict(X_test)
dtc.score(X_test,y_test)
#5.随机森林进行模型的训练和预测分析
from sklearn.ensemble import RandomForestClassifier
rfc=RandomForestClassifier(max_depth=6,random_state=9)
rfc.fit(X_train,y_train)
rfc_y_pred=rfc.predict(X_test)
rfc.score(X_test,y_test)
#6.性能评估
from sklearn.metrics import classification_report
print("dtc_report:",classification_report(dtc_y_pred,y_test))
print("rfc_report:",classification_report(rfc_y_pred,y_test))
超参数选择代码:
# 随机森林去进行预测
# 1 实例化随机森林
rf = RandomForestClassifier()
# 2 定义超参数的选择列表
param={
"n_estimators":[80,100,200], "max_depth": [2,4,6,8,10,12],"random_state":[9]}
# 超参数调优
# 3 使用GridSearchCV进行网格搜索
from sklearn.model_selection import GridSearchCV
gc = GridSearchCV(rf, param_grid=param, cv=2)
gc.fit(X_train, y_train)
print("随机森林预测的准确率为:", gc.score(X_test, y_test))
Boosting 和 AdaBoost
1. Boosting
Boosting 体现了提升思想,每一个训练器重点关注前一个训练器不足的地方进行训练,通过加权投票的方式,得出预测结果。
1.1 算法机制
Boosting是一组可将弱学习器升为强学习器算法。这类算法的工作机制类似:
1.先从初始训练集训练出一个基学习器
2.在根据基学习器的表现对训练样本分布进行调整,使得先前基学习器做错的训练样本在后续得到最大的关注。
3.然后基于调整后的样本分布来训练下一个基学习器;
4.如此重复进行,直至基学习器数目达到实现指定的值T为止。
5.再将这T个基学习器进行加权结合得到集成学习器。
简而言之:每新加入一个弱学习器,整体能力就会得到提升
Boosting算法的著名代表就是Adaboost算法。
因此,对于Boosting算法,存在两个问题:
-
在每一轮中如何调整训练集,使训练的弱分类器得以进行;(调整样本权值)
-
如何将各个弱分类器联合起来形成强分类器。 (调整模型权值)
1.2 提升的概念强化
提升Boosting是一个机器学习技术,可以用于回归和分类问题,它每一步产生一个弱预测模型(如决策树)并加权累加到总模型中;如果每一步的弱预测模型生成都是依据损失函数的梯度方向,则称之为梯度提升(GradientBoosting)。
梯度提升算法首先给定一个目标损失函数,它的定义域是所有可行的弱函数集合(基函数);提升算法通过迭代的选择一个负梯度方向上的基函数来逐渐逼近局部极小值。这种在函数域的梯度提升观点对机器学习有很大影响。
提升的理论意义:如果一个问题存在弱分类器,则可以通过提升的办法得到强分类器。
1.3 Boosting实现过程
如下过程演示:
2. AdaBoost
AdaBoost (Adaptive Boosting, 自适应提升)是 Boosting 算法的一种实现,是一种用于分类问题的算法,它用弱分类器的线性组合来构造强分类器。弱分类器的性能比随机猜测强就行,即可构造出一个非常准确的强分类器。
其特点是:训练时,样本具有权重,并且在训练过程中动态调整。被分错的样本的样本会加大权重,算法更加关注难分的样本。
2.1 AdaBoost简介
AdaBoost自适应提升学习算法和Boosting考虑的点一样
(1)不同的训练集—>调整样本权重
(2)“关注”—>增加错分样本权重
(3)“器重”—>好的分类器权重大
(4) 样本权重间接影响分类器权重
AdaBoost算法的两个核心步骤:
权值调整: AdaBoost算法提高那些被前一轮基分类器错误分类样本的权值,而降低那些被正确分类样本的权值。从而使得那些没有得到正确分类的样本,由于权值的加大而受到后一轮基分类器的更大关注。
基分类器组合: AdaBoost采用加权多数表决的方法。
- 分类误差率较小的弱分类器的权值大,在表决中起较大作用。
- 分类误差率较大的弱分类器的权值小,在表决中起较小作用。
2.2 AdaBoost特点
AdaBoost把多个不同的弱分类算法,用一种非随机的方式组合起来,表现出惊人的性能。
1,可以使用各种方法构建子分类器,Adaboost算法提供的是框架;
2,子分类器容易构造;
3,速度快,且基本不用调参数;
4,泛化错误率低。
2.3 AdaBoost步骤
Adaboost迭代算法有3步:
1.初始化训练数据的权值分布:假设有N个样本,每个样本赋予相同权值1/N。
2.训练弱分类器:本轮训练中,若某样本分错,则提高它的权值,相反分类正确的样本被降低权值。然后,权值更新过的全体样本被用于训练下一个分类器,使得下一个分类器更关注权重大的难分样本。多次迭代,训练多个弱分类器。
3.加权组合弱分类器:加大分类误差率小的弱分类器的权重,使其在最终表决中起较大作用,而降低分类误差率大的弱分类器的权重,使其在最终表决中起较小作用。
2.4 AdaBoost算法推导
AdaBoost 模型公式中
- α 为模型的权重
- m 为弱学习器数量
- hi(x) 表示弱学习器
- H(x) 输出结果大于 0 则归为正类,小于 0 则归为负类。
AdaBoost 权重更新公式:
εt 表示第 t 个弱学习器的错误率
AdaBoost 样本权重更新公式:
- Zt 为归一化值(所有样本权重的总和)
- Dt(x) 为样本权重
- αt 为模型权重。
3. AdaBoost 构建过程
下面为训练数数据,假设弱分类器由 x 产生,其阈值 v 使该分类器在训练数据集上的分类误差率最低,试用 Adaboost 算法学习一个强分类器。
3.1 构建第一个弱学习器
- 初始化工作:初始化 10 个样本的权重,每个样本的权重为:0.1
- 构建第一个基学习器:
- 寻找最优分裂点
- 对特征值 x 进行排序,确定分裂点为:0.5、1.5、2.5、3.5、4.5、5.5、6.5、7.5、8.5
- 当以 0.5 为分裂点时,有 5 个样本分类错误
- 当以 1.5 为分裂点时,有 4 个样本分类错误
- 当以 2.5 为分裂点时,有 3 个样本分类错误
- 当以 3.5 为分裂点时,有 4 个样本分类错误
- 当以 4.5 为分裂点时,有 5 个样本分类错误
- 当以 5.5 为分裂点时,有 4 个样本分类错误
- 当以 6.5 为分裂点时,有 5 个样本分类错误
- 当以 7.5 为分裂点时,有 4 个样本分类错误
- 当以 8.5 为分裂点时,有 3 个样本分类错误
- 最终,选择以 2.5 作为分裂点,计算得出基学习器错误率为:3/10=0.3
- 对特征值 x 进行排序,确定分裂点为:0.5、1.5、2.5、3.5、4.5、5.5、6.5、7.5、8.5
- 计算模型权重:
1/2 * ln((1-0.3)/0.3)=0.4236
- 更新样本权重:
- 分类正确样本为:1、2、3、4、5、6、10 共 7 个,其计算公式为:e-αt,则正确样本权重变化系数为:e-0.4236 = 0.6547
- 样本 1、2、3、4、5、6、10 权重值为:
0.06547
- 样本 1、2、3、4、5、6、10 权重值为:
- 分类错误样本为:7、8、9 共 3 个,其计算公式为:eαt,则错误样本权重变化系数为:e0.4236 = 1.5275
- 样本 7、8、9 的样本权重值为:
0.15275
- 样本 7、8、9 的样本权重值为:
- 归一化 Zt 值为:
0.06547 * 7 + 0.15275 * 3 = 0.9165
- 样本 1、2、3、4、5、6、10 最终权重值为:
0.07143
- 样本 7、8、9 的样本权重值为:
0.1667
- 分类正确样本为:1、2、3、4、5、6、10 共 7 个,其计算公式为:e-αt,则正确样本权重变化系数为:e-0.4236 = 0.6547
- 此时得到:
3.2 构建第二个弱学习器
- 寻找最优分裂点:
- 对特征值 x 进行排序,确定分裂点为:0.5、1.5、2.5、3.5、4.5、5.5、6.5、7.5、8.5
- 当以 0.5 为分裂点时,有 5 个样本分类错误,错误率为:0.07143 * 5 = 0.35715
- 当以 1.5 为分裂点时,有 4 个样本分类错误,错误率为:0.07143 * 1 + 0.16667 * 3 = 0.57144
- 当以 2.5 为分裂点时,有 3 个样本分类错误,错误率为:0.16667 * 3 = 0.57144
。。。 。。。 - 当以 8.5 为分裂点时,有 3 个样本分类错误,错误率为:0.07143 * 3 = 0.21429
- 最终,选择以 8.5 作为分裂点,计算得出基学习器错误率为:0.21429
- 计算模型权重:
1/2 * ln(1-0.21429)/0.21429)=0.64963
- 对特征值 x 进行排序,确定分裂点为:0.5、1.5、2.5、3.5、4.5、5.5、6.5、7.5、8.5
- 分类正确的样本:1、2、3、7、8、9、10,其权重调整系数为:e-0.6496 =0.5222
- 分类错误的样本:4、5、6,其权重调整系数为:1.9148
- 分类正确样本权重值:
- 样本 1、2、3、9 为:0.01734*0.5222=0.0373
- 样本 6、7、8 为:0.087
- 分类错误样本权重值:0.1368
- 归一化 Zt 值为ÿ