Git Product home page Git Product logo

stacking's Introduction

集成学习Stacking方法详解

一. stacking方法介绍

stacking是用初始训练数据学习出若干个基学习器后,将这几个学习器的预测结果作为新的训练集,来学习一个新的学习器。具体过程如下:

1. 数据划分和基学习器

将数据集划分为训练集和测试集,这里采用三个基学习器,分别为XGBoost、RandomForest和KNN,基学习器在学习过程中,会采用k折交叉验证,这里以5折交叉验证为例(将训练集划分为5份)。第二步的融合模型常采用Logistic Regression模型。如图所示

image

2. stacking过程

stacking过程分为两步,第一步是基学习器训练数据集得到第二步的训练数据,第二步基于第一步的训练数据采用Logistic Regression模型学习训练,得到最终结果。具体如下:

(1) 基学习器得到训练集

以XGBoost为例说明,此处采用的是5折交叉验证,所以先将训练数据集Training Data划分为5份training1、training2、training3、training4和training5。之后将其中4折作为训练集,1折作为测试集,XGBoost模型基于4折数据训练,对1折数据进行预测,同时对整个测试集Testing Data做预测,这样的过程重复5次,会得到5份training的predict数据和Testing Data的predict数据,然后将5份training的predict数据纵向叠起来得到基学习器的Training Data learner,5份Testing Data的predict数据取平均值得到基学习器的Testing Data learner,如图所示:

image

随机森林和KNN同XGBoost,也进行上述过程。最后,将三个基学习器的Training Data learner横向拼接在一起,得到第二步的训练集Training Data learners,将三个基学习器的Testing Data learner横向拼接在一起,得到第二步的测试集Testing learners,如图所示:

image

(2) 融合训练和预测

基于(1)得到的训练集和测试集,采用Logistic Regression模型对训练集Training Data learners进行训练,然后对测试集Testing learners进行预测,得到预测结果。当对新的测试集进行预测时,测试集需要先经过所有基学习器预测,然后横向拼接得到测试集,最后再对测试集进行预测得到测试结果,如图所示:

image

二. Stacking实例

stacking的使用方法主要有以下三种,选取KNN,Random Forest和GaussianNB模型作为基学习器,lr模型作为融合模型,3折交叉验证对iris数据进行分类,具体如下:

1. 基学习器的特征输出作为融合模型的输入

stacking的基本使用方法,使用基学习器的特征输出作为融合模型的输入,代码如下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

################## load packages #####################
from sklearn import datasets
from sklearn import model_selection
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import GaussianNB 
from sklearn.ensemble import RandomForestClassifier
from mlxtend.classifier import StackingClassifier


################## load data #####################
iris = datasets.load_iris()
x, y = iris.data[:, 1:3], iris.target


################## define classifier #####################
clf1 = KNeighborsClassifier(n_neighbors = 1)

clf2 = RandomForestClassifier(random_state = 1)

clf3 = GaussianNB()

lr = LogisticRegression()

sclf = StackingClassifier(classifiers = [clf1, clf2, clf3], meta_classifier = lr)


################## class result #####################
for clf, label in zip([clf1, clf2, clf3, sclf],
                      ['KNN',
                       'Random Forest',
                       'Naive Bayes',
                       'StackingClassifier']):
    
    scores = model_selection.cross_val_score(clf, x, y, cv = 3, scoring='accuracy')
    
    print("Accuracy: %0.2f (+/- %0.2f) [%s]" 
          % (scores.mean(), scores.std(), label))

输出结果为:

3-fold cross validation:

Accuracy: 0.91 (+/- 0.01) [KNN]
Accuracy: 0.91 (+/- 0.06) [Random Forest]
Accuracy: 0.92 (+/- 0.03) [Naive Bayes]
Accuracy: 0.95 (+/- 0.03) [StackingClassifier]

查看具体分类结果和决策边界,代码如下:

import matplotlib.pyplot as plt
from mlxtend.plotting import plot_decision_regions
import matplotlib.gridspec as gridspec
import itertools

gs = gridspec.GridSpec(2, 2)

fig = plt.figure(figsize=(10,8))

for clf, lab, grd in zip([clf1, clf2, clf3, sclf], 
                         ['KNN', 
                          'Random Forest', 
                          'Naive Bayes',
                          'StackingClassifier'],
                          itertools.product([0, 1], repeat=2)):

    clf.fit(x, y)
    ax = plt.subplot(gs[grd[0], grd[1]])
    fig = plot_decision_regions(X=x, y=y, clf=clf)
    plt.title(lab)

image

2. 基学习器的类别概率值作为融合模型的输入

使用基学习器产生的类别概率作为融合模型的输入,这种情况下需要将StackingClassifier的参数设置为 use_probas=True。另外,需要注意一下 average_probas的设置,如果设置average_probas=True,那么这些基学习器对每一个类别产生的概率值会被平均,如果设置average_probas=False,那么这些基学习器对每一个类别产生的概率值会被拼接。

假设有两个基学习器产生的概率输出为:

classifier 1: [0.2, 0.5, 0.3]
classifier 2: [0.3, 0.3, 0.4]

average_probas=True
融合模型的训练数据: [0.25, 0.45, 0.35]

average_probas=False
融合模型的训练数据: [[0.2, 0.3, 0.3], [0.3, 0.4, 0.4]]

代码如下:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

################## load packages #####################
from sklearn import datasets
from sklearn import model_selection
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import GaussianNB 
from sklearn.ensemble import RandomForestClassifier
from mlxtend.classifier import StackingClassifier


################## load data #####################
iris = datasets.load_iris()
x, y = iris.data[:, 1:3], iris.target


################## define classifier #####################
clf1 = KNeighborsClassifier(n_neighbors = 1)

clf2 = RandomForestClassifier(random_state = 1)

clf3 = GaussianNB()

lr = LogisticRegression()

sclf = StackingClassifier(classifiers = [clf1, clf2, clf3], 
                          use_probas=True,
                          average_probas=False,
                          meta_classifier = lr)


################## class result #####################
for clf, label in zip([clf1, clf2, clf3, sclf],
                      ['KNN',
                       'Random Forest',
                       'Naive Bayes',
                       'StackingClassifier']):
    
    scores = model_selection.cross_val_score(clf, x, y, cv = 3, scoring='accuracy')
    
    print("Accuracy: %0.2f (+/- %0.2f) [%s]" 
          % (scores.mean(), scores.std(), label))

3. 分特征

对训练数据中的特征维度进行操作,这次不是给每一个基学习器全部的特征,而是给不同的基学习器分不同的特征,即比如基学习器1训练前半部分特征,基学习器2训练后半部分特征(可以通过sklearn 的pipelines 实现),最终通过StackingClassifier组合起来。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

################## load packages #####################
from sklearn import datasets
from sklearn.linear_model import LogisticRegression
from mlxtend.classifier import StackingClassifier
from mlxtend.feature_selection import ColumnSelector
from sklearn.pipeline import make_pipeline


################## load data #####################
iris = datasets.load_iris()
x, y = iris.data, iris.target


################## define classifier #####################

pipe1 = make_pipeline(ColumnSelector(cols=(0, 1)),
                      LogisticRegression())
pipe2 = make_pipeline(ColumnSelector(cols=(2, 3)),
                      LogisticRegression())

sclf = StackingClassifier(classifiers=[pipe1, pipe2], 
                          meta_classifier=LogisticRegression())

################## fit and predict #####################
sclf.fit(x, y)

print(sclf.predict(x))

########### predict class probability ###########
print(sclf.predict_proba(x))

参考链接

http://rasbt.github.io/mlxtend/user_guide/classifier/StackingClassifier/#example-3-stacked-classification-and-gridsearch.

stacking's People

Contributors

shaoqibnu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.