• 欢迎访问开心洋葱网站,在线教程,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入开心洋葱 QQ群
  • 为方便开心洋葱网用户,开心洋葱官网已经开启复制功能!
  • 欢迎访问开心洋葱网站,手机也能访问哦~欢迎加入开心洋葱多维思维学习平台 QQ群
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏开心洋葱吧~~~~~~~~~~~~~!
  • 由于近期流量激增,小站的ECS没能经的起亲们的访问,本站依然没有盈利,如果各位看如果觉着文字不错,还请看官给小站打个赏~~~~~~~~~~~~~!

多分类器集成学习:多数票机制、Bagging、Adaboost实例分析

人工智能 Charzous 2477次浏览 0个评论

目录 一、认识集成学习 二、基于多数票机制的集成分类器实现 1、多数票机制原理 2、构建多数票分类器 3、多数票分类器实际应用 4、模型评估 三、套袋法(Bagging) 1、葡萄酒数据集样本分类 2、决策区域结果 四、自适应增强法(Adaboost) 五、总结


一、认识集成学习

集成学习(Ensemble Learning),它在机器学习、深度学习中有重要的应用。所谓集成,就是把不同模型通过某些机制或设定标准进行融合,目标得到一个更加强大稳健的模型,使它有着更强的泛化能力,也避免了单个模型过拟合等问题。   下面将通过实例分析,循序渐进学习,详细介绍集成学习的几种技术,目标是组合不同的分类器模型,使得融合模型得到更好的效果。   包括:

  1. 多数票机制
  2. 套袋法
  3. Adaboost

二、基于多数票机制的集成分类器实现(MajorityVoted)

1、多数票机制原理

集成学习中最常见的集成方法就是多数票机制,顾名思义,通过投票选择,多者获胜的原理,把不同的分类器按适当的权重组合起来,建立一个更强大的超级分类器。   例如,在一个二分类问题p={0,1}中,基于分类概率的加权分类方法,得到3个分类器的预测结果。  

import numpy as np
ensemble=np.array([[0.9,0.1],[0.8,0.2],[0.6,0.4]])
p=np.average(ensemble,axis=0,weights=[0.2,0.2,0.6])
print(p) classp=np.argmax(p) print(classp)

  结果:[0.7 0.3]  0   因此,对预测结果综合,结果为类别0. 这里一个简单理解原理的例子,使用numpy的average和argmax函数,下面将自己构建一个多数票分类器。  

2、构建多数票分类器

导入相关第三方工具包和函数方法  

"""
encoding: utf-8
@author: Charzous
@license: Copyright © 2021 Charzous
@software: Pycharm
@file: MajorVoteClassifier.py
@time: 2021/1/31 18:06
"""


from sklearn.base import BaseEstimator, ClassifierMixin, clone
from sklearn.preprocessing import LabelEncoder
from sklearn.pipeline import _name_estimators
import six
import numpy as np

  实现类MajorityVoteClassifier各个方法:   (1)初始化方法  

class MajorityVoteClassifier(BaseEstimator, ClassifierMixin):
    def __init__(self, classifiers, vote='classlabel', weights=None):
        self.classifiers = classifiers
        self.named_classifiers = {key: value for key, value in _name_estimators(classifiers)}
        self.vote = vote
        self.weights = weights

  (2)适应集成分类器  

    def fit(self, X, y):
        self.lablenc_ = LabelEncoder()
        self.lablenc_.fit(y)
        self.classes_ = self.lablenc_.classes_
        self.classifiers_ = []
        for clf in self.classifiers:
            fitted_clf = clone(clf).fit(X, self.lablenc_.transform(y))
            self.classifiers_.append(fitted_clf)
        return self

  (3)预测分类标签方法  

    def predict(self, X):
        if self.vote == 'probability':
            maj_vote = np.argmax(self.predict_proba(X), axis=1)
        else:
            predictions = np.asarray([clf.predict(X) for clf in self.classifiers_]).T
            maj_vote = np.apply_along_axis(lambda x: np.argmax(np.bincount(x, weights=self.weights)), axis=1,
                                           arr=predictions)
        maj_vote = self.lablenc_.inverse_transform(maj_vote)
        return maj_vote

  (4)计算标签平均概率以及返回分类器参数  

    def predict(self, X):
        if self.vote == 'probability':
            maj_vote = np.argmax(self.predict_proba(X), axis=1)
        else:
            predictions = np.asarray([clf.predict(X) for clf in self.classifiers_]).T
            maj_vote = np.apply_along_axis(lambda x: np.argmax(np.bincount(x, weights=self.weights)), axis=1,
                                           arr=predictions)
        maj_vote = self.lablenc_.inverse_transform(maj_vote)
        return maj_vote

    def predict_proba(self, X):
        probas = np.asarray([clf.predict_proba(X) for clf in self.classifiers_])
        avg_proba = np.average(probas, axis=0, weights=self.weights)
        return avg_proba

    def get_params(self, deep=True):
        if not deep:
            return super(MajorityVoteClassifier, self).get_params(deep=False)
        else:
            out = self.named_classifiers.copy()
            for name, step in six.iteritems(self.named_classifiers):
                for key, value in six.iteritems(step.get_params(deep=True)):
                    out['%s__%s' % (name, key)] = value
            return out

  到此,多数票机制的类以及方法全部实现,接下来使用该类进行实际应用。  

3、多数票分类器实际应用

使用scikit-learn数据模块,加载鸢尾花数据集,选取其中2个特征:萼片宽度和花瓣长度,进行二分类问题的预测。  

"""
encoding: utf-8
@author: Charzous
@license: Copyright © 2021 Charzous
@software: Pycharm
@file: MajorVotePredict.py
@time: 2021/1/31 18:31
"""

from sklearn import datasets
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.pipeline import Pipeline
from sklearn.metrics import auc, roc_curve
import matplotlib.pyplot as plt
from itertools import product

iris = datasets.load_iris()
X, y = iris.data[50:, [1,2]], iris.target[50:]
le = LabelEncoder()
y = le.fit_transform(y)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=2021, stratify=y)

  使用3中分类器进行训练:逻辑回归、决策树、K-近邻。   使用5者交叉验证,7:3划分训练集和测试集,其中逻辑回归和KNN方法进行了管道归一化等处理,原理可以查看我写的上一篇:基于sklearn库的机器学习模型与调优实践详细步骤  

clf1 = LogisticRegression(penalty='l2', C=0.01, random_state=2021)
clf2 = DecisionTreeClassifier(max_depth=1, criterion='entropy', random_state=2021)
clf3 = KNeighborsClassifier(n_neighbors=1, p=2, metric='minkowski')
pipe1 = Pipeline([['sc', StandardScaler()], ['clf', clf1]])
pipe3 = Pipeline([['sc', StandardScaler()], ['clf', clf3]])
clf_labels = ['Logistic regression', 'Decision tree', 'KNN']
print('5 fold cross validation:\n')
for clf, label in zip([pipe1, clf2, pipe3], clf_labels):
    scores = cross_val_score(estimator=clf, X=X_train, y=y_train, cv=5, scoring='roc_auc')
    print("ROC AUC :%0.2f(+/-%0.2f) [%s]" % (scores.mean(), scores.std(), label))

  结果: 5 fold cross validation: ROC AUC :0.94(+/-0.04) [Logistic regression] ROC AUC :0.93(+/-0.08) [Decision tree] ROC AUC :0.93(+/-0.09) [KNN]   3个模型构建完成之后,开始使用多数票机制来集成一个分类器,也就是前面构建好的多数票分类器。  

mv_clf = MajorityVoteClassifier(classifiers=[pipe1, clf2, pipe3])
clf_labels += ['Majority Voting']
all_clf = [pipe1, clf2, pipe3, mv_clf]
for clf, label in zip(all_clf, clf_labels):
    scores = cross_val_score(estimator=clf, X=X_train, y=y_train, cv=5, scoring='roc_auc')
    print("ROC AUC :%0.2f(+/-%0.2f) [%s]" % (scores.mean(), scores.std(), label))

  结果有了显著提升,4个百分点左右。 ROC AUC :0.94(+/-0.04) [Logistic regression] ROC AUC :0.93(+/-0.08) [Decision tree] ROC AUC :0.93(+/-0.09) [KNN] ROC AUC :0.97(+/-0.04) [Majority Voting]

4、模型评估可视化

 

# 评估集成分类器
colors = ['black', 'orange', 'blue', 'green']
linestyles = [':', '-.', '--', '-']
for clf, label, clr, ls in zip(all_clf, clf_labels, colors, linestyles):
    y_pred = clf.fit(X_train, y_train).predict_proba(X_test)[:, 1]
    fpr, tpr, thresholds = roc_curve(y_true=y_test, y_score=y_pred)
    roc_auc = auc(x=fpr, y=tpr)
    plt.plot(fpr, tpr, color=clr, linestyle=ls, label='%s (auc = %0.2f) ' % (label, roc_auc))

plt.legend(loc='lower right')
plt.plot([0, 1], [0, 1], linestyle='--', color='gray', linewidth=2)
plt.xlim([-0.1, 1.1])
plt.ylim([-0.1, 1.1])
plt.grid(alpha=0.5)  # 网格
plt.xlabel('FP rate')
plt.ylabel('TP rate')
plt.show()

  可视化图:  
多分类器集成学习:多数票机制、Bagging、Adaboost实例分析   很明显,在ROC结果图中,多数票集成分类器表现最好,而逻辑回归也不错,主要是因为数据集规模和特征选取,在更复杂的任务中,多数票会显得更有优势。 所以,我进一步探索,选取另外几个特征进行实验:  

X, y = iris.data[50:, [2, 3]], iris.target[50:]

  得到一些可视化结果显示:  

# 按[0,3],[2,3]两个特征划分,决策区域的区别较明显,[0,2]划分ROC-AUC曲线较明显,[0,1]划分结果最差,[1,2],[1,3]决策区域差别不大

  [1,2]特征的决策区域:不明显  
多分类器集成学习:多数票机制、Bagging、Adaboost实例分析   [2,3]特征的决策区域:差别显著  
多分类器集成学习:多数票机制、Bagging、Adaboost实例分析   获取分类器参数则用:  

# 获取分类器参数
print(mv_clf.get_params())

  返回的模型详细参数:  
多分类器集成学习:多数票机制、Bagging、Adaboost实例分析

三、套袋法(Bagging)

  从原始样本集中使用Bootstrap方法随机抽取n个训练样本,共进行k轮抽取,得到k个训练集。(k个训练集之间相互独立,元素可以有重复) 对于k个训练集,训练k个模型(k个模型可以选择决策树,knn等),每个分类器拟合引导样本时,采用多数票机制进行组合预测。  

1、葡萄酒数据集样本分类

 

"""
encoding: utf-8
@author: Charzous
@license: Copyright © 2021 Charzous
@software: Pycharm
@file: baggingAdaboost.py
@time: 2021/2/1 11:25
"""
import pandas as pd
import numpy as np
from sklearn.preprocessing import LabelEncoder,StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import BaggingClassifier, AdaBoostClassifier
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt

  加载葡萄酒数据集,选取其中两个特征  

# load data

df_wine = pd.read_csv('..\\wine_data\\wine.data', header=None)  # 本地加载

# df_wine=pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data',header=None)#服务器加载

df_wine.columns = ['class label', 'alcohol', '苹果酸', '灰', '灰的碱度', '镁', '总酚', '黄酮类化合物', '非黄烷类酚类', '原花青素', '色彩亮度',

                   '色调', '稀释酒', '脯氨酸']

df_wine = df_wine[df_wine['class label'] != 1]

y = df_wine['class label'].values

X = df_wine[['alcohol','稀释酒']].values#'脯氨酸'

le = LabelEncoder()

y = le.fit_transform(y)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=2021, stratify=y)

  构建决策数模型,以及Bagging模型  

tree = DecisionTreeClassifier(max_depth=None, criterion='entropy', random_state=2021)
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=2021)

  决策树分类器性能  

tree = tree.fit(X_train, y_train)
y_train_pred = tree.predict(X_train)
y_test_pred = tree.predict(X_test)
tree_train = accuracy_score(y_train, y_train_pred)
tree_test = accuracy_score(y_test, y_test_pred)
print('Decision tree train/test ACC %.3f/%.3f' % (tree_train, tree_test))

  套袋分类器性能  

bag=bag.fit(X_train,y_train)
y_train_pred = bag.predict(X_train)
y_test_pred = bag.predict(X_test)
bag_train = accuracy_score(y_train, y_train_pred)
bag_test = accuracy_score(y_test, y_test_pred)
print('Bagging train/test ACC %.3f/%.3f' % (bag_train, bag_test))

  结果正确率对比:可见Bagging之后模型表现提升 Decision tree train/test ACC 1.000/0.833 Bagging train/test ACC 1.000/0.875

2、决策区域结果

# 分类器决策区域可视化  

x_min = X_train[:, 0].min() - 1
x_max = X_train[:, 0].max() + 1
y_min = X_train[:, 1].min() - 1
y_max = X_train[:, 1].min() + 1

plt.rcParams['font.sans-serif'] = ['SimHei']

xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.1), np.arange(y_min, y_max, 0.1))
f, axarr = plt.subplots(nrows=1, ncols=2, sharex='col', sharey='row', figsize=(8, 3))

for idx, clf, tt in zip([0, 1], [tree,bag,ada], ['DecisionTree','Bagging','AdaBoost']):
    clf.fit(X_train, y_train)
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    axarr[idx].contourf(xx, yy, Z, alpha=0.3)
    axarr[idx].scatter(X_train[y_train == 0, 0], X_train[y_train == 0, 1], c='blue', marker='^',s=50)
    axarr[idx].scatter(X_train[y_train == 1, 0], X_train[y_train == 1, 1], c='green', marker='o',  s=50)
    axarr[idx].set_title(tt)

axarr[0].set_ylabel('酒精',fontsize=12)
axarr[0].set_xlabel('稀释酒',fontsize=12)

plt.show()

  可视化直观看出,Bagging之后的决策区域明显更加准确。  
多分类器集成学习:多数票机制、Bagging、Adaboost实例分析

四、自适应增强法(Adaboost)

这里简单了解一下Adaboost算法,它是集成学习中一种自适应增强方法,与套袋Bagging相比,Adaboost从训练集无替换抽取样本子集来训练模型,得到多个弱学习分类器,特点是从错误中学习,由此建立强大的分类器。   继续使用上面的数据集,使用sklearn实现Adaboost,在前面基础上增加模型,具体如下:  


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=2021)
# AdaBoost分类器性能
ada=ada.fit(X_train,y_train)
y_train_pred = ada.predict(X_train)
y_test_pred = ada.predict(X_test)
ada_train = accuracy_score(y_train, y_train_pred)
ada_test = accuracy_score(y_test, y_test_pred)
print('AdaBoost train/test ACC %.3f/%.3f' % (ada_train,ada_test))

 
多分类器集成学习:多数票机制、Bagging、Adaboost实例分析  

五、总结

  这篇记录集成学习的重要知识,在实际案例中更好地掌握的集成学习的基本原理机制和方法。集成学习(Ensemble Learning),它在机器学习、深度学习中有重要的应用。所谓集成,就是把不同模型通过某些机制或设定标准进行融合,目标得到一个更加强大稳健的模型,使它有着更强的泛化能力,也避免了单个模型过拟合等问题。   下面将通过实例分析,循序渐进学习,详细介绍集成学习的几种技术。 包括:多数票机制、套袋法、Adaboost。 多数票机制原理是整个的基本,所以进行了具体地分析和学习,由此引申更深入的集成方法! 如果觉得不错欢迎三连哦,点赞收藏关注,一起加油进步!原创作者:Charzous.


开心洋葱 , 版权所有丨如未注明 , 均为原创丨未经授权请勿修改 , 转载请注明多分类器集成学习:多数票机制、Bagging、Adaboost实例分析
喜欢 (0)

您必须 登录 才能发表评论!

加载中……