集成学习
一、集成学习简介
1、概念
通过构建并结合多个学习器来完成学习任务,即合并多个模型来提升机器学习性能
个体学习器:由一个现有的学习算法从训练数据产生,亦称基学习器。
2、集成学习方法
- 串行集成方法:串行集成的基本动机是利用基础模型之间的依赖,通过给错分样本一个较大的权重来提升性能。
- 并行集成方法:并行集成的基本动机是利用基础模型的独立性,通过平均能够较大地降低误差。
3、分类
- 用于减少方差的bagging
- 用于减少偏差的boosting
- 用于提升预测结果的stacking
4、示意图
二、Boosting
1、弱学习器 ==> 强学习器
原理:
1)从训练集用初始权重训练出一个弱学习器1,根据弱学习的学习误差率表现来更新训练样本的权重,使得之前弱学习器1学习误差率高的训练样本点的权重变高,使得这些误差率高的点在后面的弱学习器2中得到更多的重视。
2)基于调整权重后的训练集来训练弱学习器2.,如此重复进行,直到弱学习器数达到事先指定的数目T,最终将这T个弱学习器通过集合策略进行整合,得到最终的强学习器。
Boosting系列算法里最著名算法主要有提升方法AdaBoost算法和提升树(boosting tree)系列算法
2、AdaBoost推导
两个问题:
1)每一轮如何改变训练数据的权值和概率分布?
2)如何将弱分类器提升为强分类器?
AdaBoost对于其两个问题的解决办法:
1)提高被前一轮弱分类器错误分类样本的权值,降低正确分类权值
2)加权多数表决方法,即加大分类错误率小的弱分类器权重,使其再表决中起较大作用,减小分类错误率大的弱分类器权值,使其再表决中起较小作用。
AdaBoost算法梳理
三、Bagging
1、对于个体学习器的不相互独立问题解决:
bagging的个体弱学习器的训练集是通过随机采样得到的。通过T次的随机采样,我们就可以得到T个采样集,对于这T个采样集,我们可以分别独立的训练出T个弱学习器,再对这T个弱学习器通过集合策略来得到最终的强学习器。
2、bagging是并行集成学习方法的代表:
采用自助采样法(Bootstrap sampling),即对于m个样本的原始训练集,我们每次先随机采集一个样本放入采样集,接着把该样本放回,也就是说下次采样时该样本仍有可能被采集到,这样采集m次,最终可以得到m个样本的采样集,由于是随机采样,这样每次的采样集是和原始训练集不同的,和其他采样集也是不同的,这样得到多个不同的弱学习器。初始训练集中约有63.2%的样本出现在采样集中
- 自助采样法的优点:每个基学习器只使用了初始训练集中约63.2%的样本,剩下约36.8%样本可用作验证集来对泛化性能进行“包外估计”
3、Bagging算法过程:
四、随机森林
- Random Forest(RF)在以决策树为基学习器构建Bagging集成的基础上,进一步在决策树的训练过程中引入随机属性选择。随机森林建立了多个决策树,并将它们合并在一起以获得更准确和稳定的预测
过程:
1)bootstrap方法生成m个训练集
2)对于每个训练集,构造一颗决策树
3)在节点找特征进行分裂的时候,并不是对所有特征找到能使得指标(如信息增益)最大的,而是在特征中随机抽取一部分特征,在抽到的特征中间找到最优解,应用于节点,进行分裂 - 随机森林的思想:
随机森林就是通过集成学习的思想将多棵树集成的一种算法,它的基本单元是决策树。每棵决策树都是一个分类器(假设现在针对的是分类问题),那么对于一个输入样本,N棵树会有N个分类结果。而随机森林集成了所有的分类投票结果,将投票次数最多的类别指定为最终的输出,这就是一种最简单的 Bagging 思想。 - 优缺点分析:
优点:
1)可以用于回归和分类任务
2)容易查看模型的输入特征的相对重要性
3)使用默认的超参数通常会产生一个很好的预测结果
缺点:
1)过拟合,但只要森林中有足够多的树,分类器就不会过度拟合模型
2)使用大量树时会很慢且无法做到实时预测 - 特点
1)在当前所有算法中,具有极好的准确率
2)能够有效地运行在大数据集上
3)能够处理具有高维特征的输入样本,而且不需要降维
4)能够评估各个特征在分类问题上的重要性
5)在生成过程中,能够获取到内部生成误差的一种无偏估计
6)对于缺省值问题也能够获得很好得结果 - 随机森林的推广(Extra Trees)
extra trees是RF的一个变种, 原理几乎和RF一模一样,仅有区别有:
1) 对于每个决策树的训练集,RF采用的是随机采样bootstrap来选择采样集作为每个决策树的训练集,而extra trees一般不采用随机采样,即每个决策树采用原始训练集。
2) 在选定了划分特征后,RF的决策树会基于信息增益,基尼系数,均方差之类的原则,选择一个最优的特征值划分点,这和传统的决策树相同。但是extra trees比较的激进,他会随机的选择一个特征值来划分决策树。
五、结合策略
- 优点
1)提高泛化性能
2)降低进入局部最小点的风险
3)扩大假设空间 - 平均法:简单平均、加权平均
适用范围:
规模大的集成,学习的权重较多,加权平均法易导致过拟合
个体学习器性能相差较大时宜使用加权平均法,相近用简单平均法。 - 投票法
1)绝对多数投票法:某标记超过半数;
2)相对多数投票法:预测为得票最多的标记,若同时有多个标记的票最高,则从中随机选取一个。
3)加权投票法:提供了预测结果,与加权平均法类似。
- 学习法
Stacking描述:先从初始数据集中训练出初级学习器,然后“生成”一个新数据集用于训练次级学习器。在新数据集中,初级学习器的输出被当做样例输入特征,初始样本的标记仍被当做样例标记。
- 通过交叉验证产生次级学习器的训练样本;
- 将初级学习器的输出类概率作为次级学习器的输入属性,用多响应线性回归作为次基学习算法效果较好;
六、sklearn实现Adaboost
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import make_gaussian_quantiles
分类随机数据生成
# 生成2维正态分布,生成的数据按分位数分为两类,500个样本,2个样本特征,协方差系数为2
X1, y1 = make_gaussian_quantiles(cov=2.0,n_samples=500, n_features=2,n_classes=2, random_state=1)
# 生成2维正态分布,生成的数据按分位数分为两类,400个样本,2个样本特征均值都为3,协方差系数为2
X2, y2 = make_gaussian_quantiles(mean=(3, 3), cov=1.5,n_samples=400, n_features=2, n_classes=2, random_state=1)
#讲两组数据合成一组数据
X = np.concatenate((X1, X2))
y = np.concatenate((y1, - y2 + 1))
plt.scatter(X[:, 0], X[:, 1], marker='o', c=y)
用基于决策树的AdaBoost来做分类拟合
# 选择SAMME算法,最多200个弱分类器,步长0.8
bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=2, min_samples_split=20, min_samples_leaf=5),
algorithm="SAMME",
n_estimators=200, learning_rate=0.8)
bdt.fit(X, y)
AdaBoostClassifier(algorithm='SAMME',
base_estimator=DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=2,
max_features=None, max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=5, min_samples_split=20,
min_weight_fraction_leaf=0.0, presort=False, random_state=None,
splitter='best'),
learning_rate=0.8, n_estimators=200, random_state=None)
输出拟合结果
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02),
np.arange(y_min, y_max, 0.02))
Z = bdt.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
cs = plt.contourf(xx, yy, Z, cmap=plt.cm.Paired)
plt.scatter(X[:, 0], X[:, 1], marker='o', c=y)
plt.show()
# 拟合分数
print("Score:", bdt.score(X,y))
Score: 0.9133333333333333
bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=2, min_samples_split=20, min_samples_leaf=5),
algorithm="SAMME",
n_estimators=300, learning_rate=0.8)
bdt.fit(X, y)
print("Score:", bdt.score(X,y))
Score: 0.9622222222222222
弱分离器个数越多,则拟合程度越好,当然也越容易过拟合
现在降低步长,将步长从上面的0.8减少到0.5,再来看看拟合分数
bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=2, min_samples_split=20, min_samples_leaf=5),
algorithm="SAMME",
n_estimators=300, learning_rate=0.5)
bdt.fit(X, y)
print("Score:", bdt.score(X,y))
Score: 0.8944444444444445
在同样的弱分类器的个数情况下,如果减少步长,拟合效果会下降。
最后我们看看当弱分类器个数为700,步长为0.7时候的情况:
bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=2, min_samples_split=20, min_samples_leaf=5),
algorithm="SAMME",
n_estimators=700, learning_rate=0.5)
bdt.fit(X, y)
print("Score:", bdt.score(X,y))
Score: 0.9211111111111111
拟合分数和最初的300弱分类器,0.8步长的拟合程度相当
也就是说,在我们这个例子中,如果步长从0.8降到0.7,则弱分类器个数要从300增加到700才能达到类似的拟合效果
七、应用场景
数据维度相对低(几十维),同时对准确性有较高要求时。
因为不需要很多参数调整就可以达到不错的效果,基本上不知道用什么方法的时候都可以先试一下随机森林。