集成学习:通过构建并结合多个学习器来完成学习任务,有时也被称为多分类器系统、基于委员会的学习等。(集成学习不是只有同质学习器的集成,还有异质学习器的集成)
模型融合:通过多个模型共同决策提升任务的效果,是一种基本可以稳定提升任务效果的方法。
融合原则:挑选效果尽可能好,而差异尽可能大的模型进行融合
常见方法:投票、求均值、stacking、blending
①voting(投票)法:
适用于分类任务, 对多个学习器的预测结果进行投票,即少数服从多数。
投票方法有两种:普通投票&加权投票法。加权的权重可以人工主观设置或者根据模型评估分数来设置权重。投票法需要3个及3个以上的模型,同时要保证模型的多样性。
Voting
可通过VotingClassifier
和VotingRegressor
使用。可以将基本模型列表作为参数,列表中的每个模型都必须是具有名称和模型的元组
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.ensemble import VotingClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.linear_model import LogisticRegression
# 创建数据集
X, y = make_classification(random_state=1)
# 模型列表
models = [('lr', LogisticRegression()), ('nb', GaussianNB())]
# 创建voting模型
model = VotingClassifier(models, voting='soft')
# 设置验证集数据划分方式
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# 验证模型精度
n_scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
# 打印模型的精度
print('Mean Accuracy: %.3f (%.3f)' % (mean(n_scores), std(n_scores)))
②平均法:适用于回归、分类(针对概率)任务,对多个学习器的预测结果进行平均,平均法的好处在于平滑结果,从而减少过拟合,常见的平均法有三种:算数平均法、几何平均法和加权平均法。
假设有n个模型的预测结果,则三类平均计算方式如下:
(1)算术平均法:
(2)几何平均法:
(3)加权平均法
几何平均法受极端的影响较算术平均法小,另外,关于加权平均法的权重,也可以人工主观或根据模型分数来设置,同时也建议尽量平均差异性小的模型们。
③排序法:如果模型评估标准是与排序或者阈值相关(如AUC),简单使用平均法并不见得都能取得较好的结果。
排序法的具体步骤:
(1)对预测结果进行排序
(2)对排序序号进行平均
(3)对平均排序序号进行归一化
③stacking:
思路:基于原始数据,训练多个基学习器,然后将基学习器的预测结果组合成新的数据集,去训练一个新的学习器。
stacking主要分为以下三类:
单层stacking
单层stacking是指在基学习器上只堆叠一层元学习器
基学习器可以是同质或异质的模型,而元学习器在传统做法中是选用逻辑回归模型,也能使用非线性模型作为元学习器,例如GBDT、KNN、NN、RF等
多层stacking
其他技术与stacking的结合
stacking也可以与无监督学习方法结合。
希望使用一个模型去融合模型,但是如果使用相同的数据去训练用于融合的模型,存在数据泄露的问题,导致过拟合,所以stacking采用交叉验证的方法缓解该问题。
步骤:
①n个模型把数据分成n分(可以任意划分,只要训练模型和融合模型分开)
②每次取其中的(n-1)份数据用于训练模型,用剩下的1份数据训练融合模型
③测试模型,所有的训练模型预测测试集,得到output求均值,然后传入融合模型,得 到最终的结果。
Stacking
需要和交叉验证搭配使用,也可以通过StackingClassifier
和StackingRegressor
使用,可以将基本模型作为模型的参数提供。
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.ensemble import StackingClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression
# 创建数据集
X, y = make_classification(random_state=1)
# 模型列表
models = [('knn', KNeighborsClassifier()), ('tree', DecisionTreeClassifier())]
# 设置验证集数据划分方式
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# 验证模型精度
n_scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
# 打印模型的精度
print('Mean Accuracy: %.3f (%.3f)' % (mean(n_scores), std(n_scores)))
④blending(交叉融合法):基学习器和元学习器本质上都是用同一训练集训练的,这样就会造成信息泄露,从而导致元学习器过拟合数据集,blending的提出,对原先的数据集先划分出一个较小的留出集,比如10%训练集被当做留出集,那么blending用90%的数据做基学习器的训练,而10%留出集用作训练元学习器,这样基学习器和元学习器是用不同的数据集来训练的,解决数据泄露的问题。
步骤:
①将训练集划分为训练集和验证集
②blending不同模型的训练集是一样的(模型的精度高和模型间的差异性大都可以提升模型效果,所以可以采用一些采样方法和数据增强方法增加样本多样性)
③用训练集训练多个模型,用验证集训练融合模型,这里有两种方式训练融合模型,可以直接用均值,也可以采用带权重内的均值。
⑤boosting:在迭代过程中尝试纠先前模型所产生的错误,迭代次数越多集成产生的错误就越少,至少在数据支持的限制范围内并且在过渡拟合训练数据集之前。
Boosting
想法最初是作为一种理论思想发展起来的,AdaBoost
算法是第一个成功实现基于Boosting
的集成算法的方法。
AdaBoost
在加权训练数据集的版本上拟合决策树,以便树更多地关注先前成员出错的示例。AdaBoost
不是完整的决策树,而是使用非常简单的树,在做出预测之前对一个输入变量做出单一决策。这些短树被称为决策树桩。
AdaBoost
可通过AdaBoostClassifier
和AdaBoostRegressor
使用,它们默认使用决策树(决策树桩)作为基本模型,可以通过n_estimators
参数指定要创建的树的数量。
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.ensemble import AdaBoostClassifier
# 创建样例数据集
X, y = make_classification(random_state=1)
# 创建adaboost模型
model = AdaBoostClassifier(n_estimators=50)
# 设置验证集数据划分方式
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# 验证模型精度
n_scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
# 打印模型的精度
print('Mean Accuracy: %.3f (%.3f)' % (mean(n_scores), std(n_scores)))
gradient boosting
Gradient Boosting
是一个用于提升集成算法的框架,是对AdaBoosting
的扩展。Gradient Boosting
定义为统计框架下的加法模型,并允许使用任意损失函数以使其更加灵活,并允许使用损失惩罚(收缩)来减少过度拟合。
Gradient Boosting
引入了Bagging
的操作,例如训练数据集行和列的采样,称为随机梯度提升。
对于结构化或表格数据来说,Gradient Boosting
一种非常成功的集成技术,尽管由于模型是按顺序添加的,因此拟合模型可能会很慢。已经开发了更有效的实现,如XGBoost、LightGBM。
Gradient Boosting
在可以通过GradientBoostingClassifier
和GradientBoostingRegressor
使用,默认使用决策树作为基础模型。您可以通过n_estimators
参数指定要创建的树的数量,通过learning_rate
参数控制每棵树的贡献的学习率。
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.ensemble import GradientBoostingClassifier
# 创建样例数据集
X, y = make_classification(random_state=1)
# 创建GradientBoosting模型
model = GradientBoostingClassifier(n_estimators=50)
# 设置验证集数据划分方式
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# 验证模型精度
n_scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
# 打印模型的精度
print('Mean Accuracy: %.3f (%.3f)' % (mean(n_scores), std(n_scores)))
⑥bagging:通过采样训练数据集的样本,训练得到多样的模型,进而得到多样的预测结果,在结合模型的预测结果时,可以对单个模型预测结果进行投票或平均。
bagging的关键是对数据集的采样方法,常见的方式可以从行(样本)维度进行采样,这里是有放回采样
Bagging
可通过BaggingClassifier
和BaggingRegressor
使用,默认情况下它们使用决策树作为基本模型,可以通过n_estimators
参数指定要创建的树的数量。
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.ensemble import BaggingClassifier
# 创建样例数据集
X, y = make_classification(random_state=1)
# 创建bagging模型
model = BaggingClassifier(n_estimators=50)
# 设置验证集数据划分方式
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# 验证模型精度
n_scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
# 打印模型的精度
print('Mean Accuracy: %.3f (%.3f)' % (mean(n_scores), std(n_scores)))
random forest随机森林是bagging与树模型的结合:
随机森林集成训练数据集的不同引导样本上拟合决策树
随机森林还将对每个数据集的特征(列)进行采样
在构建每个决策树时,随机森林不是在选择分割点时考虑所有的特征,而是将特征限制为特征的随机子集。
随机森林集成可通过RandomForestClassifier
和RandomForestRegressor
类在 scikit-learn 中获得。您可以通过n_estimators
参数指定要创建的树的数量,并通过max_features
参数指定要在每个分割点考虑的随机选择的特征的数量。
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.ensemble import RandomForestClassifier
# 创建样例数据集
X, y = make_classification(random_state=1)
# 创建随机森林模型
model = RandomForestClassifier(n_estimators=50)
# 设置验证集数据划分方式
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# 验证模型精度
n_scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
# 打印模型的精度
print('Mean Accuracy: %.3f (%.3f)' % (mean(n_scores), std(n_scores)))