集成学习(Ensemble Learning)及代码分享

一. 集成学习(Ensemble Learning)

1.思想

集成学习的思想是将若干个学习器(分类器&回归器)组合之后产生一个新学习器。弱分类器(weak learner)指那些分类准确率只稍微好于随机猜测的分类器(error rate < 0.5);
集成算法的成功在于保证弱分类器的多样性(Diversity)。而且集成不稳定的算法也能够得到一个比较明显的性能提升。
常见思想:Bagging Boosting Stacking

2.Why need Ensemble Learning?

  1. 弱分类器间存在一定的差异性,这会导致分类的边界不同,也就是说可能存在错误。那么将多个弱分类器合并后,就可以得到更加合理的边界,减少整体的错误率,实现更好的效果;
  2. 对于数据集过大或者过小,可以分别进行划分和有放回的操作产生不同的数据子集,然后使用数据子集训练不同的分类器,最终再合并成为一个大的分类器;
  3. 如果数据的划分边界过于复杂,使用线性模型很难描述情况,那么可以训练多个模型,然后再进行模型的融合;
  4. 对于多个异构的特征集的时候,很难进行融合,那么可以考虑每个数据集构建一个分类模型,然后将多个模型融合。

3.Bagging方法

Bagging方法又叫做自举汇聚法(Bootstrap Aggregating),思想是:在原始数据集上通过有放回的抽样的方式,重新选择出S个新数据集来分别训练S个分类器的集成技术。
Bagging方法训练出来的模型在预测新样本分类/回归的时候,会使用多数投票或者求均值的方式来统计最终的分类/回归结果。
Bagging方法的弱学习器可以是基本的算法模型,eg: Linear、Ridge、Lasso、Logistic、Softmax、ID3、C4.5、CART、SVM、KNN等。
注意:Bagging方式是有放回的抽样,并且每个子集的样本数量必须和原始样本数量一致,所以抽取出来的子集中是存在重复数据的,模型训练的时候允许存在重复数据。
注意:差不多有1/3的样本数据是不在Bagging的每个子模型的训练数据中的。
在这里插入图片描述

3.1 Bagging方法_训练过程

训练

3.2 Bagging方法_预测过程

预测

4. Boosting方法

提升学习(Boosting)是一种机器学习技术,可以用于回归和分类的问题,它每一步产生弱预测模型(如决策树),并加权累加到总模型中;如果每一步的弱预测模型的生成都是依据损失函数的梯度方式的,那么就称为梯度提升(Gradient boosting);
提升技术的意义:如果一个问题存在弱预测模型,那么可以通过提升技术的办法得到一个强预测模型;
常见的模型有
Adaboost
Gradient Boosting(GBT/GBDT/GBRT)

4.1 boosting理解图

在这里插入图片描述

5. Stacking方法

Stacking是指训练一个模型用于组合(combine)其它模型(基模型/基学习器)的技术。即首先训练出多个不同的模型,然后再以之前训练的各个模型的输出(预测值)作为输入(特征属性)来新训练一个新的模型,从而得到一个最终的模型。一般情况下使用单层的Logistic回归作为组合模型。

二. 三种方法的一些算法举例

1.bagging之随机森林(Random Forest)

1.1 算法原理

在Bagging策略的基础上进行修改后的一种算法

  1. 从原始样本集(n个样本)中用Bootstrap采样(有放回重采样)选出n个样本;
  2. 使用抽取出来的子数据集(存在重复数据)来训练决策树;从所有属性中随机选择K个属性,从K个属性中选择出最佳分割属性作为当前节点的划分属性,按照这种方式来迭代的创建决策树。
  3. 重复以上两步m次,即建立m棵决策树;
  4. 这m个决策树形成随机森林,通过投票表决结果决定数据属于那一类

1.2 RF的推广算法

RF算法在实际应用中具有比较好的特性,应用也比较广泛,主要应用在:分类、回归、特征转换、异常点检测等。常见的RF变种算法如下:
Extra Tree
Totally Random Trees Embedding(TRTE)
Isolation Forest

1.2.1 Extra Tree

Extra Tree是RF的一个变种,原理基本和RF一样,区别如下:

  1. RF会随机重采样来作为子决策树的训练集,而Extra Tree每个子决策树采用原始数据集训练;
  2. RF在选择划分特征点的时候会和传统决策树一样,会基于信息增益、信息增益率、基尼系数、均方差等原则来选择最优特征值;而Extra Tree会随机的选择一个特征值来划分决策树。
    Extra Tree因为是随机选择特征值的划分点,这样会导致决策树的规模一般大于RF所生成的决策树。也就是说Extra Tree模型的方差相对于RF进一步减少。在某些情况下,Extra Tree的泛化能力比RF的强。
1.2.2 Totally Random Trees Embedding(TRTE)

TRTE是一种非监督的数据转化方式。将低维的数据集映射到高维,从而让映射到高维的数据更好的应用于分类回归模型。
TRTE算法的转换过程类似RF+KDTree算法的方法,建立T个决策树来拟合数据(是类似KD-Tree一样基于特征属性的方差选择划分特征)。当决策树构建完成后,数据集里的每个数据在T个决策树中叶子节点的位置就定下来了,将位置信息转换为向量就完成了特征转换操作。
案例:有3棵决策树,各个决策树的叶子节点数目分别为:5,5,4,某个数据x划分到第一个决策树的第3个叶子节点,第二个决策树的第一个叶子节点,第三个决策树的第四个叶子节点,那么最终的x映射特征编码为:(0,0,1,0,0, 1,0,0,0,0, 0,0,0,1)

1.2.3 Isolation Forest(IForest)

IForest是一种异常点检测算法,使用类似RF的方式来检测异常点;IForest算法和RF算法的区别在于:

  1. 在随机采样的过程中,一般只需要少量数据即可;
  2. 在进行决策树构建过程中,IForest算法会随机选择一个划分特征,并对划分特征随机选择一个划分阈值;
  3. IForest算法构建的决策树一般深度max_depth是比较大的。
    区别原因:目的是异常点检测,所以只要能够区分异常的即可,不需要大量数据;
    对于异常点的判断,则是将测试样本x拟合到m棵决策树上。计算在每棵树上该样本的叶子节点的深度ht(x)。从而计算出平均深度h(x);然后就可以使用下列公式计算样本点x的异常概率值,p(s,m)的取值范围为[0,1],越接近于1,则是异常点的概率越大。备注:如果落在的叶子节点为正常样本点,那么当前决策树不考虑,如果所有决策树上都是正常样本点,那么直接认为异常点概率为0
    在这里插入图片描述
    在这里插入图片描述

1.3 RF随机森林总结

RF的主要优点:

  1. 训练可以并行化,对于大规模样本的训练具有速度的优势;
  2. 由于进行随机选择决策树划分特征列表,这样在样本维度比较高的时候,仍然具有比较高的训练性能;
  3. 给以给出各个特征的重要性列表;
  4. 由于存在随机抽样,训练出来的模型方差小,泛化能力强,能够缓解过拟合的情况;
  5. RF实现简单;
  6. 对于部分特征的缺失不敏感。
    RF的主要缺点:
  7. 在某些噪音比较大的特征上(数据特别异常情况),RF模型容易陷入过拟合;
  8. 取值比较多的划分特征对RF的决策会产生更大的影响,从而有可能影响模型的效果。

1.4 随机森林算法案例

基于RF的鸢尾花分类

# -- encoding:utf-8 --
"""
"""

import pandas as pd
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report
from sklearn import metrics
from sklearn.preprocessing import LabelEncoder

mpl.rcParams['font.sans-serif'] = [u'simHei']

# np.random.seed(0)

# 1. 加载数据(数据一般存在于磁盘或者数据库)
path = '../datas/iris.data'
names = ['A', 'B', 'C', 'D', 'cla']
df = pd.read_csv(path, header=None, names=names)

# 2. 数据清洗

# # 3. 根据需求获取最原始的特征属性矩阵X和目标属性Y
X = df[names[0:-1]]
Y = df[names[-1]]
# print(Y)
label_encoder = LabelEncoder()
label_encoder.fit(Y)
Y = label_encoder.transform(Y)
# 这里得到的序号其实就是classes_这个集合中对应数据的下标
# print(label_encoder.classes_)
# true_label = label_encoder.inverse_transform([0, 1, 2, 0])
# print(true_label)
# print(Y)

# 4. 数据分割
# train_size: 给定划分之后的训练数据的占比是多少,默认0.75
# random_state:给定在数据划分过程中,使用到的随机数种子,默认为None,使用当前的时间戳;给定非None的值,可以保证多次运行的结果是一致的。
x_train, x_test, y_train, y_test = train_test_split(X, Y, train_size=0.8, random_state=28)
print("训练数据X的格式:{}, 以及类型:{}".format(x_train.shape, type(x_train)))
print("测试数据X的格式:{}".format(x_test.shape))
print("训练数据Y的类型:{}".format(type(y_train)))

# 5. 特征工程的操作
# NOTE: 不做特征工程

# 6. 模型对象的构建
"""
n_estimators=10, 最终训练的子模型的数量
criterion="gini", 随机森林底层的决策树使用什么指标衡量数据的纯度,默认gini系数,可选gini和entropy
max_depth=None, 底层决策树允许的最大深度,默认不限制
min_samples_split=2, 底层决策树分裂的时候,要求数据集中至少的样本数
min_samples_leaf=1, 底层决策树分类的时候,每个叶子节点中样本数至少要求的样本数
max_features="auto", 底层决策树构建过程中,选择特征属性的时候,选择最优特征是从多少个原始特征
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个使用集成学习实现手写体识别的Python代码,其中包含了多个不同的模型和集成方法: ```python import numpy as np import pandas as pd from sklearn.datasets import load_digits from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score from sklearn.tree import DecisionTreeClassifier from sklearn.svm import SVC from sklearn.ensemble import RandomForestClassifier, VotingClassifier, BaggingClassifier, AdaBoostClassifier # 加载手写体数字数据集 digits = load_digits() # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(digits.data, digits.target, test_size=0.2, random_state=42) # 定义多个不同的模型 models = [('dt', DecisionTreeClassifier(max_depth=10)), ('svm', SVC(kernel='rbf', C=10, gamma=0.1, probability=True)), ('rf', RandomForestClassifier(n_estimators=100, max_depth=10))] # 定义多种集成方法 ensembles = [('voting', VotingClassifier(models, voting='hard')), ('bagging', BaggingClassifier(DecisionTreeClassifier(max_depth=10), n_estimators=100)), ('adaboost', AdaBoostClassifier(DecisionTreeClassifier(max_depth=10), n_estimators=100, learning_rate=0.1))] # 依次训练和测试每个集成模型 for name, ensemble in ensembles: ensemble.fit(X_train, y_train) y_pred = ensemble.predict(X_test) acc = accuracy_score(y_test, y_pred) print(f'{name} accuracy: {acc:.2f}') ``` 在这个代码中,我们首先使用`load_digits`函数加载手写体数字数据集,然后使用`train_test_split`函数将数据集划分为训练集和测试集。接下来,我们定义了三个不同的模型,分别是决策树、支持向量机和随机森林,并将它们存储在一个列表中。然后,我们又定义了三种集成方法,分别是投票集成、Bagging和AdaBoost,并将它们存储在另一个列表中。最后,我们使用一个循环依次训练和测试每个集成模型,并输出它们的准确率。 这个代码可以作为集成学习的一个入门示例,你可以根据自己的需求和数据集选择不同的模型和集成方法来进行实验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值