目录
集成学习、个体学习器的概念
(1)集成学习(ensemble learning)是通过构建并结合多个学习器(个体学习器或弱学习器)来完成任务(分类,回归等),集成学习通常可以获得比单一学习器显著优越的泛化性能。这里的个体学习器(individual learner)通常由一个现有的学习算法从训练数据中产生,例如C4.5决策树算法、BP神经网络算法。
图1.集成学习示意图
(2)根据个体学习器的类型,集成学习既有同质集成也有异质集成;同质集成是集成学习中的个体学习器相同,例如“决策树集成”中全是决策树,“神经网络集成”中全是神经网络,同质集成中的个体学习器称为“基学习器”,相应的算法称为“基学习算法”。异质集成中的个体学习器是由不同的学习算法生成,例如同时包含决策树和神经网络。
(3)集成学习在各个规模的数据集上都有很好的策略。
数据集大:划分成多个小数据集,学习多个模型进行组合
数据集小:利用Bootstrap方法进行抽样,得到多个数据集,分别训练多个模型再进行组合
- 根据个体学习器的生成方式,目前的集成学习方法大致分为两大类,Boosting和Bagging
Boosting bagging
Boosting
(1)是指个体学习器间存在强依赖关系、必须串行生成的序列化方法
(2)基本思想是刚开始训练时对每一个训练例赋相等的权重,从初始训练集训练出一个基学习器,再根据基学习器的表现对训练样本分步进行调整,使得先前基学习器做错的训练样本赋以较大的权重,也就是让学习算法在每次学习以后更注意学错的样本,从而得到多个预测函数,然后基于调整后的样本分布来训练下一个基学习器,如此重复进行,直至基学习器数目达到事先指定的值T,最终将这T个学习器进行加权结合。
图2 Boosting算法示意图
Bagging
- 是指个体学习器间不存在强依赖关系、可同时生成的并行化方法
- 首先介绍Bootstraping,即自助法:它是一种有放回的抽样方法(可能抽到重复的样本)
- Bagging即套袋法,其算法过程如下:
A)从原始样本集中抽取训练集.每轮从原始样本集中使用Bootstraping的方法抽取n个训练样本(在训练集中,有些样本可能被多次抽取到,而有些样本可能一次都没有被抽中).共进行k轮抽取,得到k个训练集.(k个训练集相互独立)
B)每次使用一个训练集得到一个模型,k个训练集共得到k个模型.
C)对分类问题:将上步得到的k个模型采用投票的方式得到分类结果;对回归问题,计算上述模型的均值作为最后的结果。
图3. Bagging算法示意图
Bagging,Boosting二者之间的区别
1)样本选择上:
Bagging:训练集是在原始集中有放回选取的,从原始集中选出的各轮训练集之间是独立的.
Boosting:每一轮的训练集不变,只是训练集中每个样例在分类器中的权重发生变化.而权值是根据上一轮的分类结果进行调整.
2)样例权重:
Bagging:使用均匀取样,每个样例的权重相等
Boosting:根据错误率不断调整样例的权值,错误率越大则权重越大.
3)预测函数:
Bagging:所有预测函数的权重相等.
Boosting:每个弱分类器都有相应的权重,对于分类误差小的分类器会有更大的权重.
4)并行计算:
Bagging:各个预测函数可以并行生成
Boosting:各个预测函数只能顺序生成,因为后一个模型参数需要前一轮模型的结果.
结合策略
学习器结合可能会从三个方面带来好处:
(1)从统计的方面来看,由于学习任务的假设空间往往很大,可能有多个假设在训练集上达到同等性能,此时若使用单学习器可能因误选而导致泛化性能不佳,结合多个学习器则会减小这一风险;
(2)从计算方面来看,学习算法往往会陷入局部极小,有点局部极小点所对应的泛化性能不佳,而通过多次运行之后进行结合,可降低糟糕局部极小点的风险;
(3)从表示的方面来看,某些学习任务的真实假设可能不在当前学习算法所考虑的假设空间中,此时若使用单学习器则肯定无效,而通过结合多个学习器,由于相应的假设空间有所扩大,有可能学得更好的近似。
图4 学习器结合可能从三个方面带来好处
假定集成包含T个基学习器,其中hi在示例x上的输出为
- 平均法
简单平均法
加权平均法
是个体学习器的权重,通常要求
- 投票法
对分类任务来说,学习器hi将从类别标记集合中预测出一个标记,在样本上的预测输出表示为一个维向量,其中是在类别标记上的输出。
绝对多数投票法
相对多数投票法
加权投票法
- 学习法
当训练数据很多时,一种更为强大的结合策略是使用“学习法”,即通过另一个学习器来进行结合。Stacking是学习法的典型代表。我们把个体学习器称为初级学习器,用于结合的学习器称为次级学习器或元学习器。Stacking算法本身是一种著名的集成学习方法,且有不少集成学习算法可视为其变体或特例,它也可以看做是一种结合策略。
Stacking先从初始训练集训练出初级学习器,然后“生成”一个新数据集用于训练次级学习器。在这个新数据集中,初级学习器的输出被当作样例输入特征,而初始样本的标记仍被当作样例标记。Stacking的算法描述如下图所示,这里我们假定初级集成是异质的。
图5. Stacking算法
stacking的过程有一张图非常经典,如下:
上半部分是用一个基础模型进行5折交叉验证。Taining Data中的Learn表示训练集,Predict表示验证集,Test Data为测试集;
每一次的交叉验证包含两个过程,
1. 基于training data训练模型;
2. 基于training data训练生成的模型对testing data进行预测。
在整个交叉验证的第一次完成之后我们将会得到关于当前验证集的预测值,记为a1。在这部分操作完成后,我们还要对数据集的整个testing set进行预测,这部分预测值将会作为下一层模型testing data的一部分,记为b1。因为我们进行的是5折交叉验证,所以以上提及的过程将会进行五次,最终生成数据a1,a2,a3,a4,a5,对testing set的预测数据b1,b2,b3,b4,b5。
我们可以发现a1,a2,a3,a4,a5其实就是对原来整个training set的预测值,将他们拼凑起来,记为A1。而对于b1,b2,b3,b4,b5这部分数据,我们将各部分相加取平均值,记为B1。
stacking中同一层通常包含多个模型,假设还有Model2,Model3,Model4,Model5,对于这四个模型,我们可以重复以上的步骤,在整个流程结束之后,我们可以得到新的A2,A3,A4,A5,B2,B3,B4,B5矩阵。之后,我们把A1,A2,A3,A4,A5并列合并得到一个的矩阵作为training data,B1,B2,B3,B4,B5并列合并得到的矩阵作为testing data。作为下一层模型的输入数据。
通俗的将,就是将上一个模型的输出作为下一个模型的输入。
随机森林思想
随机森林是Bagging的一个扩展变体,除了样本集是有放回的采样外,属性集合也引入了随机属性选择。具体来说,传统决策树在选择划分属性时是在当前结点的属性集合中选择一个最优属性;而在RF中,对基决策树的每个结点,先从该结点的属性集合中随机选择一个包含k个属性的子集,然后再从这个子集中选择一个最优属性用于划分。这里的参数k控制了随机性的引入程度:若令k=d,则基决策时的构建与传统决策树相同;若令k=1,则是随机选择一个属性进行划分;一般情况下,k=log2d [Breiman,2001a]。
随机森林推广
extra trees
extra trees是RF的一个变种, 原理几乎和RF一模一样,仅有区别有:
1) 对于每个决策树的训练集,RF采用的是随机采样bootstrap来选择采样集作为每个决策树的训练集,而extra trees一般不采用随机采样,即每个决策树采用原始训练集。
2) 在选定了划分特征后,RF的决策树会基于基尼系数,均方差之类的原则,选择一个最优的特征值划分点,这和传统的决策树相同。但是extra trees比较的激进,他会随机的选择一个特征值来划分决策树。
由于随机选择了特征值的划分点位,而不是最优点位,这样会导致生成的决策树的规模一般会大于RF所生成的决策树。即模型的方差相对于RF进一步减少,但是偏倚相对于RF进一步增大。在某些时候,extra trees的泛化能力比RF更好。
随机森林的优缺点
RF的主要优点有:
1)简单、容易实现、计算开销小,在许多现实任务中有很好的性能
2) 由于可以随机选择决策树节点划分特征,这样在样本特征维度很高的时候,仍然能高效的训练模型。
3) 由于采用了随机采样,训练出的模型的方差小,泛化能力强。
RF的主要缺点有:
1)在某些噪音比较大的样本集上,RF模型容易陷入过拟合。
2) 取值划分比较多的特征容易对RF的决策产生更大的影响,从而影响拟合的模型的效果
Sklearn中随机森林参数
这里只是简要的介绍下,在sklearn中采用随机森林进行分类的时候需要以下代码,具体细节先不在此处列出。随机森林进行回归类似。
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier(n_estimators=10, max_depth=None, min_samples_split=2, random_state=0)
现在对RandomForestClassifier()中的参数进行介绍,主要的参数就是n_estimators和max_features
n_estimators | 随机森林中树的个数,即学习器的个数 |
max_features | 划分叶子节点,选择的最大特征数目 |
n_features | 在寻找最佳分裂特征时要考虑的特征数量 |
max_depth | 树的最大深度,如果选择default=None,树就一直扩展,直到所有的叶子节点都是同一类样本,或者达到最小样本划分的数目。 |
min_samples_split | 最小样本划分的数目,就是样本的数目少于等于这个值,就不能继续划分当前节点了 |
min_samples_leaf | 叶子节点最少样本数,如果某叶子节点数目小于这个值,就会和兄弟节点一起被剪枝 |
min_weight_fraction_leaf | 叶子节点最小的样本权重和 |
max_leaf_nodes | 最大叶子节点数,默认是”None”,即不限制最大的叶子节点数 |
min_impurity_split | 节点划分的最小不纯度,是结束树增长的一个阈值,如果不纯度超过这个阈值,那么该节点就会继续划分,否则不划分,成为一个叶子节点 |
min_impurity_decrease | 最小不纯度减少的阈值,如果对该节点进行划分,使得不纯度的减少大于等于这个值,那么该节点就会划分,否则,不划分 |
bootstrap | 自助采样,又放回的采样,采样的结果就是初始样本的63.2%作为训练集,默认选择自助采样法。 |
out-of-bag estimate | 包外估计;是否选用包外样本(即bootstrap采样剩下的36.8%的样本)作为验证集,对训练结果进行验证,默认不采用。 |
n_jobs | 并行使用的进程数,默认1个,如果设置为-1,该值为总的核数。 |
random_state | 随机状态,默认由np.numpy生成 |
verbose | 显示输出的一些参数,默认不输出 |
分类sklearn代码实现
import pandas as pd
import numpy as np
from sklearn.model_selection import StratifiedKFold
from sklearn.ensemble import RandomForestClassifier
data = pd.read_csv("data.csv")data中最后一列是分类的label
data_fea = data.iloc[:,:-1]
data_cat = data.iloc[:,-1]
skf = StratifiedKFold(n_splits=10)#10折交叉
ac_train_rf = []
ac_test_rf = []
for train_index, test_index in skf.split(data_fea,data_cat):
x_train, x_test = data_fea.iloc[train_index,:], data_fea.iloc[test_index,:]
y_train, y_test = data_cat.iloc[train_index],data_cat.iloc[test_index]
forest = RandomForestClassifier(n_estimators=100, random_state=0, n_jobs=-1)
forest.fit(x_train, y_train) #training
pre_rf = forest.predict(x_test)
ac_train = forest.score(x_train,y_train)
ac_train_rf.append(ac_train)
ac = forest.score(x_test,y_test)#testing
ac_test_rf.append(ac)
print("training error: ", np.mean(ac_train_rf))
print("test error: ", np.mean(ac_test_rf))
应用场景
数据维度相对低(几十维),同时对准确性有较高要求时。
参考
《机器学习》周志华
https://blog.csdn.net/wstcjf/article/details/77989963
https://scikit-learn.org/stable/modules/ensemble.html#forests-of-randomized-trees