对于决策树的构建主要分为两类方法,即深度优先(损失更小,与广度优先相比,在leaf数目相同时树根深,因此容易造成过拟合,但是构建过程更加灵活且容易在大规模数据集上使用)和广度优先(树的构建更加平衡,但是精度较差),决策树通过“分而治之”的思想将样本进行分类。在决策树构建的过程中最困难且最耗时的就是结点的分裂,这里不同的分裂策略即对应了不同版本的决策树,如根据信息增益构建ID3,根据信息增益率构建C4.5,根据Gini index构建CART等,split策略的不同也将带来decision tree的不同偏好。然而单一的决策树其性能有限,且容易造成过拟合,而通过剪枝或限制树深等手段虽然能在一定程度上缓解overfitting,但是其精度也将受到损失。因此,研究人员便以决策树为基学习器,通过集成的思想来提升模型的性能。
集成学习(Ensemble Learning)是指:在机器学习中,模型单独运行时可能表现不佳,但将多个模型组合起来时就会变得更强大,基于这种组合思想来提高模型精度的方法被称为集成学习。俗话说“三个臭皮匠,赛过诸葛亮”,这句话就完美阐述了集成学习的潜在思想——通过构建并结合多个学习器来完成学习任务,通过将多个模型结合在一起来提高整体的泛化能力。
集成学习方法概述
集成学习,并不是一个单独的机器学习算法,而是通过构建并结合多个机器学习器(基学习器)来完成学习任务。集成学习往往被视为一种元算法(meta-algorithm)。
集成学习可以用于分类问题集成,回归问题集成,特征选取集成,异常点检测集成等等,可以说所有的机器学习领域都可以看到集成学习的身影。
对于训练集数据,我们通过训练若干个个体弱学习器,通过一定的结合策略,就可以最终形成一个强学习器,以达到博采众长的目的。
学习器
强学习器:Strong learner,相对于弱学习器而言的概念,强学习器指的是可以预测相当准确结果的学习算法。
弱学习器:Weak learner,相对于强学习器而言,通常这些弱学习器预测的结果只比随机结果稍好一些。
基学习器:Base Learner,集成学习中的个体学习器,基学习器经常是弱学习器,但是并非必须是弱学习器。
基学习算法:Base Learning Algorithm,基学习器所基于的算法,基学习器基于基学习算法生成,比如通过不同的训练集,经过训练之后,生成的不同参数的机器学习模型。
同质基学习器:Homogeneous Base Learner,指使用同样的基学习算法生成的基学习器
异质基学习器:Heterogeneous Base Learner,指使用不同的基学习算法生成的基学习器。
两类集成学习的构建方法
并行方法:
构建多个独立的学习器,取他们的预测结果的平均
个体学习器之间不存在强依赖关系,一系列个体学习器可以并行生成
通常是同质的弱学习器
代表算法是Bagging和随机森林系列算法。
顺序化方法:
多个学习器是依次构建的
个体学习器之间存在强依赖关系,因为一系列个体学习器需要串行生成
通常是异质的学习器
代表算法是Boosting系列算法,比如AdaBoost,梯度提升树等
集成学习的算法策略
集成学习的算法策略有许多种,主要有三个比较有代表性的:Boosting(提升算法)、Bagging(装袋算法)、Stacking(堆叠法)。
为了说明这三种方法,定义一个二元分类任务:
Bagging(装袋算法)
模型越容易过拟合,则越适用于Bagging集成学习方法。
从训练集中进行子抽样组成每个基模型所需要的子训练集,对所有基模型预测的结果进行综合产
生最终的预测结果:
Bagging方法更像是一个集体决策的过程,每个个体都进行单独学习,学习的内容可以相同,也可以不同,也可以部分重叠。但由于个体之间存在差异性,最终作出的判断不会完全一致。在最终决策时,每个个体单独作出判断,再通过投票的方式作出最后的集体决策。每个基学习器都会对训练集进行有放回抽样得到子训练集。每个基学习器基于不同子训练集进行训练, 并综合所有基学习器的预测值得到最终的预测结果。
由于Bagging的策略是取所有基模型的“平均”值作为最终模型的输出结果,所以Bagging集成方法能够很好的降低模型高方差(过拟合)的情况。因此通常来说,在使用Bagging集成方法的时候,可以尽量使得每个基模型都出现过拟合的现象。 。
Bagging常用的综合方法是投票法,票数最多的类别为预测类别。基学习器之间没有依赖关系,并行。代表算法: 随机森林
Boosting(提升算法)
模型越容易欠拟合,则越适用于Boosting集成学习方法。
Boosting算法的工作机制是首先从训练集用初始权重训练出一个弱学习器1,根据弱学习的学习误差率表现来更新训练样本的权重,使得之前弱学习器1学习误差率高的训练样本点的权重变高,使得这些误差率高的点在后面的弱学习器2中得到更多的重视。然后基于调整权重后的训练集来训练弱学习器2.,如此重复进行,直到弱学习器数达到事先指定的数目T,最终将这T个弱学习器通过集合策略进行整合,最终将这T个基学习器进行加权结合,得到最终的强学习器。
Boosting族的算法有:Adaboost, GBDT, XGboost, Lightgbm
Stacking(堆叠法)
将训练好的所有基模型对训练集进行预测,第j个基模型对第i个训练样本的预测值将作为新的训
练集中第i个样本的第j个特征值,最后基于新的训练集进行训练。同理,预测的过程也要先经过
所有基模型的预测形成新的测试集,最后再对测试集进行预测。
Stacking步骤
使用多个基础模型(KNN、朴素贝叶斯、决策树、SVM、逻辑回归等),独立在训练集上学习各模型。
将各个基础模型预测的结果构建一个新的数据集。将构建好的新数据集,进行最终的模型学习(最终的一个模型,可以为任何模型)。
集成学习步骤
1. 找到误差互相独立的基分类器。• 一般常用决策树作为基分类器。• 事实上, 任何分类模型都可以作为基分类器,但树形模型由于结构简单且较易产生随机性所以比较常用。2. 训练基分类器。• bagging并行训练。• boosting串行训练。3. 合并基分类器的结果。合并基分类器的方法有voting和stacking两种。前者是用投票的方式, 将获得最多选票的结果作为最终的结果。后者是用串行的方式, 把前一个基分类器的结果输出到下一个分类器,将所有基分类器的输出结果相加(或者用更复杂的算法融合,比如把各基分类器的输出作为特征,使用逻辑回归作为融合模型进行最后的结果预测)作为最终的输出。
偏差与方差
我们常说集成学习中的基模型是弱模型,通常来说弱模型是偏差高(在训练集上准确度低)方差小(防止过拟合能力强)的模型,但并不是所有集成学习框架中的基模型都是弱模型。
Bagging 和 Stacking 中的基模型为强模型(偏差低,方差高)。
而Boosting中的基模型为弱模型(偏差高,方差低)。
Bagging方法则采用分而治之的策略,通过对训练样本多次采样,并分别训练处多个不同模型,然后做综合,来减小集成分类器的方差。
在训练好一个弱分类器后,我们需要计算弱分类器的错误或残差,作为下一个分类器的输入。这个过程本身就是再不断减小损失函数,来使得模型不断逼近"靶心",使得模型偏差不断降低。但Boosting的过程不会显著降低方差。这是因为Boosting的训练过程使得各弱分类器之间时强相关的,缺乏独立性,所有并不会对降低方差有作用。
假设所有基分类器出错的概率时独立的,在某个测试样本上,用简单多数投票方法来集成结果,超过半数基分类器出错的概率会随着基分类器的数量增加而下降(降低过拟合)
随机森林
基本概念
具有良好深度的决策树就是 低偏差 和 高方差 的模型;因此用决策树做基础模型的Bagging(装袋算法),也称随机森林。随机森林算法由很多决策树组成,每一棵决策树之间没有关联。建立完森林后,当有新样本进入时,每棵决策树都会分别进行判断,然后基于投票法给出分类结果。
优点
1. 在数据集上表现良好,相对于其他算法有较大的优势;
2. 易于并行化,在大数据集上有很大的优势; 3. 能够处理高维度数据,不用做特征选择。
Random Forest(随机森林)是 Bagging 的扩展变体,它在以决策树为基学习器构建 Bagging 集成的基础上,进一步在决策树的训练过程中引入了随机特征选择,因此可以概括随机森林包括四个部分:1. 随机选择样本(放回抽样);2. 随机选择特征;3. 构建决策树;4. 随机森林投票(平均)。
随机选择样本和 Bagging 相同,采用的是Bootstraping 自助采样法;随机选择特征是指在每个节点在分裂过程中都是随机选择特征的(区别与每棵树随机选择一批特征)。
这种随机性导致随机森林的偏差会有稍微的增加(相比于单棵不随机树),但是由于随机森林的“平均”特性,会使得它的方差减小,而且方差的减小补偿了偏差的增大,因此总体而言是更好的模型。
同一个样本在不同树中所归属的叶子节点也不尽相同,甚至连类别也可能不同。这充分体现了Bagging集成模型的优点,通过“平均”来提高模型的泛化能力。
基本流程
基本步骤
RF 的主要缺点有:• 在某些噪声比较大的样本集上,RF 模型容易陷入过拟合。• 取值划分比较多的特征容易对RF的决策产生更大的影响,从而影响拟合的模型的效果。
# 集成分类模型综合考量多个分类器的预测结果,从而做出决策。
# 综合考量分两种:
# a.利用相同的训练数据同时搭建多个独立的分类模型,然后以投票的方式,按照少数服从多数的原则做出决策(如:随机森林分类器)
# b.按照一定次序搭建多个分类模型,一般来说,每一个后续模型的加入都需要对现有的集成模型的综合性能有所贡献(如:梯度提升决策树)
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
# 导入特征转换器
from sklearn.feature_extraction import DictVectorizer
from sklearn.metrics import classification_report
from sklearn.ensemble import RandomForestClassifier
titanic=pd.read_csv(r'2.基础篇\监督学习\分类\titanic.txt')
X=titanic[['pclass','age','sex']]
y=titanic['survived']
print(X.info())
# age的数据缺失、需要补充,使用平均数或者中位数都是对模型偏离造成最小影响的策略
X_age=X[['age']].copy()
X_age.fillna(X_age.mean(),inplace=True)
X=X.copy()
X.loc[:,['age']]=X_age
# print(X.info())
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.25,random_state=33)
vec=DictVectorizer(sparse=False)
# 特征转换后,类别类的特征都单独剥离出来,独成一列特征,数值型的不变
X_train=vec.fit_transform(X_train.to_dict(orient='records'))
X_test=vec.transform(X_test.to_dict(orient='records'))
rfc=RandomForestClassifier()
rfc.fit(X_train,y_train)
rfc_y_pred=rfc.predict(X_test)
print("The Accuracy of RandomForestClassifier is",rfc.score(X_test,y_test))
print(classification_report(rfc_y_pred,y_test))