集成学习(Ensemble Learning) 指的是一种学习方法,它的思想在于通过采用投票的方式综合多个分类回归模型的结果以提高分类回归的准确率。集成学习这种方法与我们平时通过听取许多他人意见来决策的过程是一致的,综合更多的有效信息往往才能更好的对事物进行判断。
1、scikit-learn 下的集成学习接口(Voting Classifier)
集成学习根据统计投票结果的时候,根据是否考虑投票权重分成两类:
- hard voting, 每个分类器都为产生一个预测结果,最终新样例的预测结果为得票数最高的类别。
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.ensemble import VotingClassifier
voting_clf = VotingClassifier(estimators= [
('logistic_clf',LogisticRegression()),
('DT_clf',DecisionTreeClassifier()),
('svm_clf',SVC())
],voting= 'hard')
### Usage
from sklearn import datasets
X = datasets.load_iris().data[:,2:]
y = datasets.load_iris().target
voting_clf.fit(X,y)
- soft voting , 软投票分类器根据不同模型给出的所有预测的概率对输入数据进行分类,这个预测概率值对应的就是每个分类器给每个类别票权,最终预测结果为得票权最高的类别。这种基于概率做出的集成投票结果相比硬投票的结果准确率上会高一些。但使用 soft voting 时前提要求每个预测模型都能够估计预测结果的概率。
from sklearn.ensemble import VotingClassifier
voting_clf = VotingClassifier(estimators= [
('logistic_clf',LogisticRegression()),
('DT_clf',DecisionTreeClassifier(random_state=666)),
('svm_clf',SVC(probability=True)) ### SVM 模型默认不支持计算概率结果,开启概率计算会增加运算开销
],voting= 'soft')
voting_clf.fit(X,y)
voting_clf.score(X,y)
2、集成学习的子决策模型
统计中的 大数定律 提出在随机试验中,尽管每次的结果是不一样的,但进行大量的重复试验后,所有随机试验结果的平均值总会接近于一个确定的值。也就是在 偶然事件的大量重复出现背后,往往呈现的是几乎必然的规律。大量的重复试验实则在捕获这个必然。
所以在集成学习的投票决策中,要想最终投票的结果足够可靠,根据大数定律的理论只有从足够多(上百上千上万)的投票基础上选出的最终结果才具有足够高的可信度。但从算法类型数量的有限程度上来说,投票者的数量远远不够用来捕捉 必然。所以为了尽可能 增加集成学习的投票者数量,一个可行的方案是创建更多的 子模型 来集成更多子模型的意见。
2.2 创建子模型方法
集成学习中参与决策的子模型必须是具有差异性的(否则不满足随机试验的原则),为了使创建的子模型具有这种随机性(任意两子模型是不同的),可以通过只让每个子模型只看样本集的一部分数据来训练得到。根据大数定律,尽管由片面数据训练得到的单个子模型预测准确率较低,但只要子模型的准确率基本能高于随机概率,随着子模型数量的增加,最终集成学习的整体准确率就会逐渐提高:
假设每个子模型的准确率平均约为 $51\%$,这个概率略高于随机决策概率($50\%$)
集成学习只有1个子模型,整体准确率: $C^{1}_{1} 0.51^1 = 0.51$
集成学习只有3个子模型,整体准确率: $C^3_3 (0.51)^3 + C^2_3(0.51)^2*(0.49) = 0.515$
【根据少数服从多数原则,3个子模型决策下至少2个模型预测正确才正确】
集成学习含有500个子模型,整体准确率: $\sum_{i=251}^{500} C^{i}_{500}(0.51)^{i}(0.49)^{500-i} = 0.656$
2.3 用于训练子模型的样本集抽样方式
- Pasting :不放回抽样;
- Bagging :有放回抽样,有放回抽样相比无放回抽样能产生非常多的随机组合数据$C_{m}^{k}$。有放回式抽样方法在统计学中称为 bootstrap 。
2.3.1 scikit-learn Bagging抽样生成子模型
from sklearn.tree import DecisionTreeClassifier ### 决策树对样本分布非常敏感,非常适合用于创建集成学习模型
from sklearn.ensemble import BaggingClassifier
bagging_clf = BaggingClassifier(DecisionTreeClassifier(),n_estimators= 1000 , max_samples=100,bootstrap= True) ## n_estimators:子模型个数,max_samples:用于训练子模型样本数;bootstrap:开启又放回抽样
bagging_clf.fit(X,y)
bagging_clf.score(X,y)
2.3.2 OOB(Out-of-Bag) 处理
Out-of-Bag 指的是 有限次的 Bagging 抽样很可能导致一部分样本没有被取到(测试表明平均约有$\frac {1}{3}$ 的样本无法被取到,这部分样本被称为 Out-of-Bag)。为了充分利用这部分样本, Bagging 抽样其实可以完全从全数据集里进行抽样,最后使用这部分没有每取到的Out-of-Bag samples 来作为 测试/验证数据集。
scikit-learn 中封装了
oob_score
参数,开启该选项将返回使用 Out-of-Bag samples 作为测试集的预测准确度。
from sklearn.tree import DecisionTreeClassifier ### 决策树对样本分布非常敏感,非常适合用于创建集成学习模型
from sklearn.ensemble import BaggingClassifier
bagging_clf = BaggingClassifier(DecisionTreeClassifier(),n_estimators= 1000 , max_samples=100,bootstrap= True,oob_score= True,n_jobs= -1) ## n_estimators:子模型个数,max_samples:用于训练子模型样本数;bootstrap:开启又放回抽样;n_jobs:开启并行抽样。
bagging_clf.fit(X,y)
bagging_clf.oob_score_
- Random Subspace :特征进行抽样,每次抽取少量特征集来训练子模型,相当于每次都从数据集的一个子空间来看样本分布。
from sklearn.tree import DecisionTreeClassifier ### 决策树对样本分布非常敏感,非常适合用于创建集成学习模型
from sklearn.ensemble import BaggingClassifier
bagging_clf = BaggingClassifier(DecisionTreeClassifier(),n_estimators= 1000 ,
max_samples=150,bootstrap= False, ### 不对样本进行抽子集,即每次取全部样本训练子模型
max_features=2,bootstrap_features= True, ### 对特征进行抽样
n_jobs= -1) ## n_estimators:子模型个数,max_samples:用于训练子模型样本数;bootstrap:开启又放回抽样;
bagging_clf.fit(X,y)
- Random Patches :补丁抽样,同时对数据集的样本和特征进行抽样用于训练子模型。基于该子模型的生成方式需要集成更大的子模型结果才更可靠。
from sklearn.tree import DecisionTreeClassifier ### 决策树对样本分布非常敏感,非常适合用于创建集成学习模型
from sklearn.ensemble import BaggingClassifier
bagging_clf = BaggingClassifier(DecisionTreeClassifier(),n_estimators= 10000 ,
max_samples=100,bootstrap= True, ### 开启样本抽样
max_features=2,bootstrap_features= True, ### 开启特征抽样
oob_score= True,n_jobs= -1) ## n_estimators:子模型个数,max_samples:用于训练子模型样本数;bootstrap:开启又放回抽样;
bagging_clf.fit(X,y)
bagging_clf.oob_score_
3、 随机森林
通过 Bagging 的方式创建 $n$ 多棵互相差异的 决策树 来集成决策的方法称为 -- 随机森林。sklearn
封装的随机森林默认基于 决策树算法 生成的每个子模型。随机森林会在 一个特征子集 上寻找最优决策节点构建每棵决策树,因此 随机森林 相比决策树具有更高的随机性。
scikit-learn 封装的 RandomForest 调用
from sklearn.ensemble import RandomForestClassifier
### 随机森林 分类器同时集成了决策树和Bagging 抽样,可以指定创建的没棵决策树的复杂度(剪枝)
rf_clf = BaggingClassifier(n_estimators= 500 , random_state=666, oob_score= True,max_depth = 3 ,n_jobs= -1)
rf_clf.fit(X,y)
rf_clf.oob_score_
3.2 极端随机树 Extra-Trees
在构建子决策树的策略上,除了基于经典的搜索方式(信息熵/基尼系数)来寻找划分节点之外。极端随机树(Extra-Trees) 提出使用随机特征和随机阈值的方式来为每棵树创建划分节点,从而极端随机树决策模型能提供更高的随机性,能够有效抑制过拟合,但同时也增大了Bias。【该方法日常应用频率较低】
from sklearn.ensemble import ExtraTreesClassifier
rf_clf = ExtraTreesClassifier(n_estimators= 500 , random_state=666,max_depth = 3, bootstrap=True, oob_score= True,n_jobs= -1)
rf_clf.fit(X,y)
rf_clf.oob_score_
4、集成学习处理回归问题
集成回归的处理逻辑与集成分类的逻辑基本一致,只需 sklearn 下调用相应的 Regressor 方法。
from sklearn.ensemble import BaggingClassifier
from sklearn.ensemble import RandomForestRegressor
from sklearn.ensemble import ExtraTreesRegressor
5、增强集成学习-Boosting
不同于 Bagging 抽样生成互相差异的子决策模型的集成学习策略。Boosting 方法集成的子决策模型彼此间属于一种相互增强的关系,也就是每生成一个子决策模型都在尝试弥补前者的弱点(稳定提高子模型的准确率),依次生成系列子决策模型,最后基于投票的思路完成集成决策,从而使得整体准确率提高。
5.1 自适应提升集成学习 (Ada Boosting )
Ada Boosting(Adaptive Boosting) 的处理策略在于每当生成一个子决策模型,就为当前模型下拟合失败的样本提高下次被拟合上的权重,这样下一个子模型的训练的时候就优先拟合上一个模型未拟合上的样本,从而依次生成系列子决策模型用于集成决策。
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
ada_clf = AdaBoostClassifier(DecisionTreeClassifier(max_depth= 2),n_estimators= 500)
ada_clf.fit(X,y)
ada_clf.score(X,y)
5.2 梯度增强集成学习 (Gradien Boosting)
Gradien Boosting 也是一种持续迭代子决策模型的集成学习过程,与 Ada Boosting 提高未拟合样本权重的策略不同,Gradien Boosting 每次迭代在于针对上一个子模型预测结果与真实值的误差(如回归的MSE)进行拟合生成下一个子模型,每次生成的子模型都是对前者错误($err$)的一个补偿,这样 通过持续补偿前一个模型的错误生成的系列子模型,最后全部子模型的结果之和整体反映了更小的模型误差,从而提高了集成学习的准确率。
from sklearn.ensemble import GradientBoostingClassifier
gd_clf = GradientBoostingClassifier(max_depth = 3,n_estimators= 500) ### 梯度增强集成学习指定使用决策树算法生成子模型
gd_clf.fit(X,y)
gd_clf.score(X,y)
6、堆叠集成学习-Stacking
Stacking 堆叠集成学习方案,它的策略在于将多个预测模型的输出值作为训练集输入到另一个预测模型并将该模型的输入结果作为最后的集成学习输出。
训练一个二层的 Stacking 集成学习分类器,只需将从原始数据拆出两个训练集,第一个训练集用来训练第一层预测模型,第二个训练集将分别传入第一层的每个分类器后产生的预测结果用于训练第二层预测模型:
6.2 Stacking 集成学习 与 神经网络
基于 Stacking 策略,叠加多层的分类器将使得模型的复杂度急剧增加,因此 Stacking 集成学习模型也变得非常容易过拟合。
神经网络 的组建策略也是这种 Stacking套娃的形式。对于神经网络,它的每个处理节点(神经元)只对应一种函数处理,而不是 Stacking集成学习里一个复杂的算法模型。与Stacking 集成学习一样,神经网络也容易随着层数增加从而快速提升复杂度从而 引发过拟合问题,这些神经网络的过拟合问题主要在 深度学习 领域被探讨。