集成方法-Bagging

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

  • 假设我们有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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容