美文网首页
集成方法-Bagging

集成方法-Bagging

作者: Amica | 来源:发表于2017-12-01 18:38 被阅读264次

对于集成方法来说,其目标是组合多个基学习器的预测结果,从而来提高单个模型的泛化能力/鲁棒性。这里我们所谓的基学习器就是指的那些学习的准确率略高于随机猜测的学习算法。那么为什么这样的方法有效呢?下面我们来看一个例子。

  • 假设我们有25个基分类器
  • 每个分类器的分类错误率 ε=0.35
  • 假设各个分类器之间是相互独立的
  • 集成方法得到的模型将数据预测错误的可能性就为:
集成方法得到的模型预测错误的概率.png

我们可以看到这比起单个分类器预测的效果有了很好的提升。

集成方法通常包括如下两个类别:
  • 平均方法(averaging methods)
    该方法的原则是独立地构建多个学习器,然后将它们的预测结果进行平均。通常提供过组合之后的学习器要比单个的学习器性能更好,因为通过组合之后的模型降低了方差。
    该法方法的代表有:
    bagging(装袋)
    随机森林(是一种以决策树为基学习器的Bagging算法)
  • 提升方法(boosting methods)
    与上一个方法所不同的是,提升方法的学习器是依次构建的,该方法试图去降低学习器的偏差。
    该方法的代表有: AdaBoost(自适应增强)
    Gradient Tree Boosting(梯度提升树)

Bagging

                          集成方法-Bagging的思想介绍
  • 对于给定的训练样本S,每轮从训练样本S中采用有放回抽样(Booststraping)的方式抽取M个训练样本,共进行n轮,得到了n个样本集合,需要注意的是这里的n个训练集之间是相互独立的。
  • 在获取了样本集合之后,每次使用一个样本集合得到一个预测模型,对于n个样本集合来说,我们总共可以得到n个预测模型。
  • 如果我们需要解决的是分类问题,那么我们可以对前面得到的n个模型采用投票的方式得到分类的结果,对于回归问题来说,我们可以采用计算模型均值的方法来作为最终预测的结果。
    通过下面的图示我们可以更加直观地理解bagging的大致思想。


    bagging general ideal.png

    那么什么时候我们采用bagging集成方法呢?

  • 学习算法不稳定:
    if small changes to the training set cause large changes in the learned classifier.(也就是说如果训练集稍微有所改变就会导致分类器性能比较大大变化那么我们可以采用bagging这种集成方法)
    If the learning algorithm is unstable, then Bagging almost always improves performance.(当学习算法不稳定的时候,Bagging这种方法通常可以改善模型的性能)

scikit-learn中封装了bagging集成方法,对于分类问题我们可以采用baggingclassifier对于回归问题我们可以采用baggingregressor,通过设置参数max_samplesmax_features我们可以指定子集大小和用于训练的特征的比例。
下面我们来看一下官网上提供的一个例子:

>>> from sklearn.ensemble import BaggingClassifier
>>> from sklearn.neighbors import KNeighborsClassifier
>>> bagging = BaggingClassifier(KNeighborsClassifier(),
...                             max_samples=0.5, max_features=0.5)
这里采用了k近邻分类器作为基分类器,并指定了子集的规模大小。

为了加深印象,这里我运用UCI上的乳腺癌数据集作为训练样本,来对比运用单个决策树模型和bagging集成模型预测时模型的性能。

1、数据集概况:

该数据集是从UCI上下载下来的,包含了699个样本,其中有9个特征属性,1个类别标签,列名是自己添加的,由于原始数据集中存在缺失值。我通过数据预处理对缺失值进行了填充,且修改了类别标签。原始数据中用2表示良性肿瘤,4表示恶性肿瘤,预处理后的数据用1表示恶性肿瘤,0表示良性肿瘤。


乳腺癌数据集部分样本特征取值.png
乳腺癌数据集部分标签取值.png
# -*- coding: utf-8 -*-
"""
Created on Fri Dec  1 16:27:45 2017

@author: Amica
""" 
#实现功能:对比单个决策树模型和集成模型上的准确率、灵敏度、特异性
import numpy as np
import pandas as pd
#导入train_test_split用于拆分训练集和测试集
from sklearn.model_selection import train_test_split
#导入用于构建分类模型的DecisionTreeClassifier和 BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import BaggingClassifier
#导入评估模型预测性能所需的函数
from sklearn.metrics import accuracy_score
from sklearn.metrics import recall_score
#加载乳腺癌数据集
data=pd.read_csv("cancer.csv")
#这里我们只取花瓣长度和花瓣宽度两个特征维度
X=data.drop("诊断结果",axis=1)
y=data.诊断结果

#划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y,
                                                    test_size=0.4,  random_state=1) 

#这里我们采用决策时模型作为基分类器,并采用熵作为指标对属性进行划分
tree = DecisionTreeClassifier(criterion='entropy', max_depth=None)

#通过装袋集成方法生成500个决策树
bag = BaggingClassifier(base_estimator=tree,n_estimators=500,
                        max_samples=1.0,max_features=1.0, bootstrap=True,
                        bootstrap_features=False, n_jobs=1, random_state=1)
# 1、评估单个决策树构建的模型性能

# 通过训练集训练单个决策树
tree = tree.fit(X_train, y_train)
#用单个决策树模型对训练集的类别进行预测
y_train_pred = tree.predict(X_train)
#用单个决策树模型对测试集的类别进行预测
y_test_pred = tree.predict(X_test)
#查看单个决策树模型在训练集上的准确率
tree_train_accuracy = accuracy_score(y_train, y_train_pred)
#查看单个决策时模型在测试集上的准确率
tree_test_accuracy  = accuracy_score(y_test, y_test_pred)
#打印出单个模型在训练集和测试集上的准确率

#查看单个决策树模型在训练集上的灵敏度
tree_train_sen = recall_score(y_train, y_train_pred,pos_label=1)
#查看单个决策时模型在测试集上的灵敏度
tree_test_sen  = recall_score(y_test, y_test_pred,pos_label=1)

#查看单个决策树模型在训练集上的特异性
tree_train_spe = recall_score(y_train, y_train_pred,pos_label=0)
#查看单个决策时模型在测试集上的特异性
tree_test_spe  = recall_score(y_test, y_test_pred,pos_label=0)

#打印出单个模型在训练集和测试集上的准确率、灵敏度、特异性
print('Decision tree train/test accuracies(准确率) %.3f/%.3f' % (tree_train_accuracy , tree_test_accuracy ))
print('Decision tree train/test sen(灵敏度) %.3f/%.3f' % (tree_train_sen, tree_test_sen ))
print('Decision tree train/test spe(特异性) %.3f/%.3f' % (tree_train_spe, tree_test_spe ))

# 2、评估通过bagging集成的分类器性能

#通过训练集训练多个决策树集成的模型
bag = bag.fit(X_train, y_train)
#运用bagging集成的模型预测训练集的类别
y_train_pred = bag.predict(X_train)
#运用bagging集成的模型预测测试集的类别
y_test_pred = bag.predict(X_test)

#评估集成模型的性能
#查看集成模型在训练集上的准确率
bag_train_accuracy = accuracy_score(y_train, y_train_pred)
#查看集成模型在测试集上的准确率
bag_test_accuracy = accuracy_score(y_test, y_test_pred)

#查看集成模型在训练集上的灵敏度
bag_train_sen = recall_score(y_train, y_train_pred,pos_label=1)
#查看集成模型在测试集上的灵敏度
bag_test_sen  = recall_score(y_test, y_test_pred,pos_label=1)

#查看集成模型在训练集上的特异性
bag_train_spe = recall_score(y_train, y_train_pred,pos_label=0)
#查看集成模型在测试集上的特异性
bag_test_spe  = recall_score(y_test, y_test_pred,pos_label=0)

#打印出集成模型在训练集和测试集上的准确率、灵敏度、特异性
print('Bagging train/test accuracies(准确率) %.3f/%.3f' % (bag_train_accuracy, bag_test_accuracy))
print('Bagging train/test sen(灵敏度) %.3f/%.3f' % (bag_train_sen, bag_test_sen ))
print('Bagging train/test spe(特异性) %.3f/%.3f' % (bag_train_spe, bag_test_spe ))

运行结果:

运行结果.png
通过观察运行结果我们可以看到无论是准确率、灵敏度还是特异性基于决策树的集成模型均比单个决策树模型的性能有了一定的提升。当然这里我们只是采用了默认参数,如果对参数进行调优那模型的性能可能比现在更好。
对于这种医疗数据来说我们拿到的数据集通常是不平衡的,那么我们不能仅仅以准确率来作为评估模型性能的指标。在上面的实例中我用到了灵敏度和特异性,这里的灵敏度其实就是指的真阳性率(真实数据中乳腺肿瘤为恶性的样本中,预测值也为恶性的比例),特异性就是真阴性率(真实数据中乳腺肿瘤为良性的样本中,预测值也为良性的比例)也就是说灵敏度越高那么就越不容易漏诊,特异性越高,也就越不容易误诊。
参考资料:sklearn-Ensemble methods

相关文章

网友评论

      本文标题:集成方法-Bagging

      本文链接:https://www.haomeiwen.com/subject/niuibxtx.html