【机器学习之模型融合】Stacking堆叠法

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

目录

1、Stacking的基本思想💍

2、思考💎

3、在sklearn中实现Stacking🎯

3.1、导入工具库和数据👕

3.2、定义交叉验证评估函数👗

3.3、个体学习器与元学习器的定义🍗

3.4、模型构建🍪

4、元学习器的特征矩阵🍒 

4.1、特征矩阵存在的问题🍓 

4.2、样本量太少的解决方案交叉验证🍌

4.3、特征太少的解决方案🍎

4.4、接口 transform 与属性 stack_method_🍅

5、Stacking融合的训练和测试流程🎪


1、Stacking的基本思想💍

  • 堆叠法Stacking是近年来模型融合领域最为热门的方法它不仅是竞赛冠军队最常采用的融合方法之一也是工业中实际落地人工智能时会考虑的方案之一。作为强学习器的融合方法Stacking集模型效果好、可解释性强、适用复杂数据三大优点于一身属于融合领域最为实用的先驱方法。
  • Stacking究竟是怎样一种算法呢它的核心思想其实非常简单——首先如下图所示Stacking结构中有两层算法串联第一层叫做level 0第二层叫做level 1level 0里面可能包含1个或多个强学习器而level 1只能包含一个学习器。在训练中数据会先被输入level 0进行训练训练完毕后level 0中的每个算法会输出相应的预测结果。我们将这些预测结果拼凑成新特征矩阵再输入level 1的算法进行训练。融合模型最终输出的预测结果就是level 1的学习器输出的结果。

在这个过程中level 0输出的预测结果一般如下排布 

  • 第一列就是学习器1在全部样本上输出的结果第二列就是学习器2在全部样本上输出的结果以此类推。
  • 同时level 0上训练的多个强学习器被称为基学习器(base-model)也叫做个体学习器。在level 1上训练的学习器叫元学习器meta-model。根据行业惯例level 0上的学习器是复杂度高、学习能力强的学习器例如集成算法、支持向量机而level 1上的学习器是可解释性强、较为简单的学习器如决策树、线性回归、逻辑回归等。有这样的要求是因为level 0上的算法们的职责是找出原始数据与标签的关系、即建立原始数据与标签之间的假设因此需要强大的学习能力。但level 1上的算法的职责是融合个体学习器做出的假设、并最终输出融合模型的结果相当于在寻找“最佳融合规则”而非直接建立原始数据与标签之间的假设。
  • 说到这里不知道你是否有注意到Stacking的本质是让算法找出融合规则。虽然大部分人可能从未接触过类似于Stacking算法的串联结构但事实上Stacking的流程与投票法、均值法完全一致

  • 在投票法中我们用投票方式融合强学习器的结果在均值法中我们用求均值方式融合强学习器的结果在Stacking堆叠法中我们用算法融合强学习器的结果。当level 1上的算法是线性回归时其实我们就是在求解所有强学习器结果的加权求和而训练线性回归的过程就是找加权求和的权重的过程。同样的当level 1上的算法是逻辑回归的时候其实我们就是在求解所有强学习器结果的加权求和再在求和基础上套上sigmoid函数。训练逻辑回归的过程也就是找加权求和的权重的过程。其他任意简单的算法同理。
  • 虽然对大多数算法来说我们难以找出类似“加权求和”这样一目了然的名字来概括算法找出的融合规则但本质上level 1的算法只是在学习如何将level 0上输出的结果更好地结合起来所以Stacking是通过训练学习器来融合学习器结果的方法。这一方法的根本优势在于我们可以让level 1上的元学习器向着损失函数最小化的方向训练而其他融合方法只能保证融合后的结果有一定的提升。因此Stacking是比Voting和Averaging更有效的方法。在实际应用时Stacking也常常表现出胜过投票或均值法的结果。

2、思考💎

  • 要不要对融合的算法进行精密的调参

    个体学习器粗调元学习器精调如果不过拟合的话可以两类学习器都精调。理论上来说算法输出结果越接近真实标签越好但个体学习器精调后再融合很容易过拟合。

  • 个体学习器算法要怎样选择才能最大化stacking的效果

    与投票、平均的状况一致控制过拟合、增加多样性、注意算法整体的运算时间。

  • 个体学习器可以是逻辑回归、决策树这种复杂度较低的算法吗元学习器可以是xgboost这种复杂度很高的算法吗

    都可以一切以模型效果为准。对level 0而言当增加弱学习器来增加模型多样性、且弱学习器的效果比较好时可以保留这些算法。对level 1而言只要不过拟合可以使用任何算法。个人推荐在分类的时候可以使用复杂度较高的算法对回归最好还是使用简单的算法

  • level 0和level 1的算法可不可以使用不同的损失函数

    可以因为不同的损失函数衡量的其实是类似的差异即真实值与预测值之间的差异。不过不同的损失对于差异的敏感性不同如果可能的话建议使用相似的损失函数。

  • level 0和level 1的算法可不可以使用不同的评估指标

    个人建议level 0与level 1上的算法必须使用相同的模型评估指标。虽然Stacking中串联了两组算法但这两组算法的训练却是完全分离的。在深度学习当中我们也有类似的强大算法串联弱小算法的结构例如卷积神经网络就是由强大的卷积层与弱小的线性层串联卷积层的主要职责是找出特征与标签之间的假设而线性层的主要职责是整合假设、进行输出。但在深度学习中一个网络上所有层的训练是同时进行的每次降低损失函数时需要更新整个网络上的权重。但在Stacking当中level 1上的算法在调整权重时完全不影响level 0的结果因此为了保证两组算法最终融合后能够得到我们想要的结果在训练时一定要以唯一评估指标为基准进行训练。

3、在sklearn中实现Stacking🎯

 显然StackingClassifier应用于分类问题StackingRegressor应用于回归问题。

在sklearn当中只要输入estimatorsfinal_estimator就可以执行stacking了。我们可以沿用在投票法中使用过的个体学习器组合并使用随机森林作为元学习器来完成stacking

3.1、导入工具库和数据👕

#常用工具库
import re
import numpy as np
import pandas as pd
import matplotlib as mlp
import matplotlib.pyplot as plt
import time

#算法辅助 & 数据
import sklearn
from sklearn.model_selection import KFold, cross_validate
from sklearn.datasets import load_digits #分类 - 手写数字数据集
from sklearn.datasets import load_iris
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split

#算法单一学习器
from sklearn.neighbors import KNeighborsClassifier as KNNC
from sklearn.neighbors import KNeighborsRegressor as KNNR
from sklearn.tree import DecisionTreeRegressor as DTR
from sklearn.tree import DecisionTreeClassifier as DTC
from sklearn.linear_model import LinearRegression as LR
from sklearn.linear_model import LogisticRegression as LogiR
from sklearn.ensemble import RandomForestRegressor as RFR
from sklearn.ensemble import RandomForestClassifier as RFC
from sklearn.ensemble import GradientBoostingRegressor as GBR
from sklearn.ensemble import GradientBoostingClassifier as GBC
from sklearn.naive_bayes import GaussianNB
import xgboost as xgb

#融合模型
from sklearn.ensemble import StackingClassifier

使用sklearn自带的手写数字数据集是一个10分类数据集。

data = load_digits()
X = data.data
y = data.target

# 划分数据集
Xtrain,Xtest,Ytrain,Ytest = train_test_split(X,y,test_size=0.2,random_state=1412)

3.2、定义交叉验证评估函数👗

def fusion_estimators(clf):
    """
    对融合模型做交叉验证对融合模型的表现进行评估
    """
    cv = KFold(n_splits=5,shuffle=True,random_state=1412)
    results = cross_validate(clf,Xtrain,Ytrain
                             ,cv = cv
                             ,scoring = "accuracy"
                             ,n_jobs = -1
                             ,return_train_score = True
                             ,verbose=False)
    test = clf.fit(Xtrain,Ytrain).score(Xtest,Ytest)
    print("train_score:{}".format(results["train_score"].mean())
          ,"\n cv_mean:{}".format(results["test_score"].mean())
          ,"\n test_score:{}".format(test)
         )



def individual_estimators(estimators):
    """
    对模型融合中每个评估器做交叉验证对单一评估器的表现进行评估
    """
    for estimator in estimators:
        cv = KFold(n_splits=5,shuffle=True,random_state=1412)
        results = cross_validate(estimator[1],Xtrain,Ytrain
                             ,cv = cv
                             ,scoring = "accuracy"
                             ,n_jobs = -1
                             ,return_train_score = True
                             ,verbose=False)
        test = estimator[1].fit(Xtrain,Ytrain).score(Xtest,Ytest)
        print(estimator[0]
          ,"\n train_score:{}".format(results["train_score"].mean())
          ,"\n cv_mean:{}".format(results["test_score"].mean())
          ,"\n test_score:{}".format(test)
          ,"\n")

3.3、个体学习器与元学习器的定义🍗

#逻辑回归没有增加多样性的选项
clf1 = LogiR(max_iter = 3000, C=0.1, random_state=1412,n_jobs=8)
#增加特征多样性与样本多样性
clf2 = RFC(n_estimators= 100,max_features="sqrt",max_samples=0.9, random_state=1412,n_jobs=8)
#特征多样性稍微上调特征数量
clf3 = GBC(n_estimators= 100,max_features=16,random_state=1412) 

#增加算法多样性新增决策树与KNN
clf4 = DTC(max_depth=8,random_state=1412)
clf5 = KNNC(n_neighbors=10,n_jobs=8)
clf6 = GaussianNB()

#新增随机多样性相同的算法更换随机数种子
clf7 = RFC(n_estimators= 100,max_features="sqrt",max_samples=0.9, random_state=4869,n_jobs=8)
clf8 = GBC(n_estimators= 100,max_features=16,random_state=4869)

estimators = [("Logistic Regression",clf1), ("RandomForest", clf2)
              , ("GBDT",clf3), ("Decision Tree", clf4), ("KNN",clf5) 
              #, ("Bayes",clf6)
              , ("RandomForest2", clf7), ("GBDT2", clf8)
             ]

3.4、模型构建🍪

#选择单个评估器中分数最高的随机森林作为元学习器
#也可以尝试其他更简单的学习器
final_estimator = RFC(n_estimators=100
                      , min_impurity_decrease=0.0025
                      , random_state= 420, n_jobs=8)
clf = StackingClassifier(estimators=estimators #level0的7个体学习器
                         ,final_estimator=final_estimator #level 1的元学习器
                         ,n_jobs=8)

这里的精调过拟合的操作就是增加了参数min_impurity_decrease=0.0025

可以看到stacking在测试集上的分数与投票法Voting持平但在5折交叉验证分数上却没有投票法高。这可能是由于现在我们训练的数据较为简单但数据学习难度较大时stacking的优势就会慢慢显现出来。当然我们现在使用的元学习器几乎是默认参数我们可以针对元学习器使用贝叶斯优化进行精妙的调参然后再进行对比堆叠法的效果可能超越投票法。

4、元学习器的特征矩阵🍒 

4.1、特征矩阵存在的问题🍓 

在Stacking过程中个体学习器会原始数据上训练、预测再把预测结果排布成新特征矩阵放入元学习器进行学习。其中个体学习器的预测结果、即元学习器需要训练的矩阵一般如下排布

根据我们对机器学习以及模型融合的理解不难发现以下两个问题

  • 首先元学习器的特征矩阵中的特征一定很少

1个个体学习器只能输出1组预测结果我们对这些预测结果进行排列新特征矩阵中的特征数就等于个体学习器的个数。一般融合模型中个体学习器最多有20-30个也就是说元学习器的特征矩阵中最多也就20-30个特征。这个特征量对于工业、竞赛中的机器学习算法来说是远远不够的。

  • 其次元学习器的特征矩阵中样本量也不太多

个体学习器的职责是找到原始数据与标签之间的假设为了验证这个假设是否准确我们需要查看的是个体学习器的泛化能力。只有当个体学习器的泛化能力较强时我们才能安心的将个体学习器输出的预测结果放入元学习器中进行融合。

然而。在我们训练stacking模型时我们一定是将原始数据集分为训练集、验证集和测试集三部分

其中测试集是用于检测整个融合模型的效果的因此在训练过程中不能使用。

训练集用于训练个体学习器属于已经完全透露给个体学习器的内容如果在训练集上进行预测那预测结果是“偏高”的、无法代表个体学习器的泛化能力。

因此最后剩下能够用来预测、还能代表个体学习器真实学习水平的就只剩下很小的验证集了。一般验证集最多只占整个数据集的30%-40%这意味着元学习器所使用的特征矩阵里的样本量最多也就是原始数据的40%。


无论在行业惯例当中元学习器需要是一个复杂度较低的算法因为元学习器的特征矩阵在特征量、样本量上都远远小于工业机器学习所要求的标准。为了解决这两个问题在Stacking方法当中存在多种解决方案而这些解决方案可以通过sklearn中的stacking类实现。  

4.2、样本量太少的解决方案交叉验证🍌

  • 参数cv在stacking中执行交叉验证
  1. 在stacking方法被提出的原始论文当中原作者自然也意识到了元学习器的特征矩阵样本量太少这个问题因此提出了在stacking流程内部使用交叉验证来扩充元学习器特征矩阵的想法即在内部对每个个体学习器做交叉验证但并不用这个交叉验证的结果来验证泛化能力而是直接把交叉验证当成了生产数据的工具。
  2. 具体的来看在stacking过程中我们是这样执行交叉验证的对任意个体学习器来说假设我们执行5折交叉验证我们会将训练数据分成5份并按照4份训练、1份验证的方式总共建立5个模型训练5次

  • 在交叉验证过程中每次验证集中的数据都是没有被放入模型进行训练的因此这些验证集上的预测结果都可以衡量模型的泛化能力。
  • 一般来说交叉验证的最终输出是5个验证集上的分数但计算分数之前我们一定是在5个验证集上分别进行预测并输出了结果。所以我们可以在交叉验证中建立5个模型轮流得到5个模型输出的预测结果而这5个预测结果刚好对应全数据集中分割的5个子集这是说我们完成交叉验证的同时也对原始数据中全部的数据完成了预测。现在只要将5个子集的预测结果纵向堆叠就可以得到一个和原始数据中的样本一一对应的预测结果。这种纵向堆叠正像我们在海滩上堆石子(stacking)一样这也是“堆叠法”这个名字的由来。 

用这样的方法来进行预测可以让任意个体学习器输出的预测值数量 = 样本量如此元学习器的特征矩阵的行数也就等于原始数据的样本量了

在stacking过程中这个交叉验证流程是一定会发生的不属于我们可以人为干涉的范畴。不过我们可以使用参数cv来决定具体要使用怎样的交叉验证包括具体使用几折验证是否考虑分类标签的分布等等。具体来说参数cv中可以输入

输入None默认使用5折交叉验证

输入sklearn中任意交叉验证对象

输入任意整数表示在Stratified K折验证中的折数。Stratified K折验证是会考虑标签中每个类别占比的交叉验证如果选择Stratified K折交叉验证那每次训练时交叉验证会保证原始标签中的类别比例 = 训练标签的类别比例 = 验证标签的类别比例

现在你知道Stacking是如何处理元学习器的特征矩阵样本太少的问题了。需要再次强调的是内部交叉验证的并不是在验证泛化能力而是一个生产数据的工具因此交叉验证本身没有太多可以调整的地方。唯一值得一提的是当交叉验证的折数较大时模型的抗体过拟合能力会上升、同时学习能力会略有下降。当交叉验证的折数很小时模型更容易过拟合。但如果数据量足够大那使用过多的交叉验证折数并不会带来好处反而只会让训练时间增加而已。

estimators = [("Logistic Regression",clf1), ("RandomForest", clf2)
              , ("GBDT",clf3), ("Decision Tree", clf4), ("KNN",clf5) 
              #, ("Bayes",clf6)
              , ("RandomForest2", clf7), ("GBDT2", clf8)
             ]
final_estimator = RFC(n_estimators=100
                      , min_impurity_decrease=0.0025
                      , random_state= 420, n_jobs=8)
def cvtest(cv):
    clf = StackingClassifier(estimators=estimators
                         ,final_estimator=final_estimator
                         , cv = cv
                         , n_jobs=8)
    start = time.time()
    clf.fit(Xtrain,Ytrain)
    print((time.time() - start)) #消耗时间
    print(clf.score(Xtrain,Ytrain)) #训练集上的结果
    print(clf.score(Xtest,Ytest)) #测试集上的结果

可以看到随着cv中折数的上升训练时间一定会上升但是模型的表现却不一定。因此选择5~10折交叉验证即可。同时由于stacking当中自带交叉验证又有元学习器这个算法因此堆叠法的运行速度是比投票法、均值法缓慢很多的这是stacking堆叠法不太人性化的地方。

4.3、特征太少的解决方案🍎

  • 参数stack_method更换个体学习器输出的结果类型
  1. 对于分类stacking来说如果特征量太少我们可以更换个体学习器输出的结果类型。具体来说如果个体学习器输出的是具体类别如[0,1,2]那1个个体学习器的确只能输出一列预测结果。但如果把输出的结果类型更换成概率值、置信度等内容输出结果的结构一下就可以从一列拓展到多列。
  2. 如果这个行为由参数stack_method控制这是只有StackingClassifier才拥有的参数它控制个体分类器具体的输出。stack_method里面可以输入四种字符串"auto", "predict_proba", "decision_function", "predict"除了"auto"之外其他三个都是sklearn常见的接口。
clf = LogiR(max_iter=3000, random_state=1412)

clf = clf.fit(Xtrain,Ytrain)

#predict_proba输出概率值
clf.predict_proba(Xtrain)

#decision_function每个样本点到分类超平面的距离可以衡量置信度
#对于无法输出概率的算法如SVM我们通常使用decision_function来输出置信度
clf.decision_function(Xtrain)

#predict输出具体的预测标签
clf.predict(Xtrain)

对参数stack_method

输入"auto"sklearn会在每个个体学习器上按照"predict_proba", "decision_function", "predict"的顺序分别尝试学习器可以使用哪个接口进行输出。即如果一个算法可以使用predict_proba接口那就不再尝试后面两个接口如果无法使用predict_proba就尝试能否使用decision_function。

输入三大接口中的任意一个接口名则默认全部个体学习器都按照这一接口进行输出。然而如果遇见某个算法无法按照选定的接口进行输出stacking就会报错。

因此我们一般都默认让stack_method保持为"auto"。从上面的我们在逻辑回归上尝试的三个接口结果来看很明显当我们把输出的结果类型更换成概率值、置信度等内容输出结果的结构一下就可以从一列拓展到多列。

  • predict_proba

    对二分类输出样本的真实标签1的概率一列
    对n分类输出样本的真实标签为[0,1,2,3...n]的概率一共n列

  • decision_function

    对二分类输出样本的真实标签为1的置信度一列
    对n分类输出样本的真实标签为[0,1,2,3...n]的置信度一共n列

  • predict

    对任意分类形式输出算法在样本上的预测标签一列

在实践当中我们会发现输出概率/置信度的效果比直接输出预测标签的效果好很多既可以向元学习器提供更多的特征、还可以向元学习器提供个体学习器的置信度。我们在投票法中发现使用概率的“软投票”比使用标签类被的“硬投票”更有效也是因为考虑了置信度。

  • 参数passthrough将原始特征矩阵加入新特征矩阵

对于分类算法我们可以使用stack_method但是对于回归类算法我们没有这么多可以选择的接口。回归类算法的输出永远就只有一列连续值因而我们可以考虑将原始特征矩阵加入个体学习器的预测值构成新特征矩阵。这样的话元学习器所使用的特征也不会过于少了。当然这个操作有较高的过拟合风险因此当特征过于少、且stacking算法的效果的确不太好的时候我们才会考虑这个方案。

控制是否将原始数据加入特征矩阵的参数是passthrough我们可以在该参数中输入布尔值。当设置为False时表示不将原始特征矩阵加入个体学习器的预测值设置为True时则将原始特征矩阵加入个体学习器的预测值、构成大特征矩阵。

  • 接口transform与属性stack_method_

4.4、接口 transform 与属性 stack_method_🍅

estimators = [("Logistic Regression",clf1), ("RandomForest", clf2)
              , ("GBDT",clf3), ("Decision Tree", clf4), ("KNN",clf5) 
              #, ("Bayes",clf6)
              , ("RandomForest2", clf7), ("GBDT2", clf8)
             ]
final_estimator = RFC(n_estimators=100
                      , min_impurity_decrease=0.0025
                      , random_state= 420, n_jobs=8)
clf = StackingClassifier(estimators=estimators
                         ,final_estimator=final_estimator
                         ,stack_method = "auto"
                         ,n_jobs=8)

clf = clf.fit(Xtrain,Ytrain)

 当我们训练完毕stacking算法后可以使用接口transform来查看当前元学习器所使用的训练特征矩阵的结构

如之前所说这个特征矩阵的行数就等于训练的样本量

因为我们有7个个体学习器而现在数据是10分类的数据因此每个个体学习器都输出了类别[0,1,2,3,4,5,6,7,8,9]所对应的概率因此总共产出了70列数据。如果加入参数passthrough特征矩阵的特征量会变得更大。

clf = StackingClassifier(estimators=estimators
                         ,final_estimator=final_estimator
                         ,stack_method = "auto"
                         ,passthrough = True
                         ,n_jobs=8)


clf = clf.fit(Xtrain,Ytrain)

使用属性stack_method_我们可以查看现在每个个体学习器都使用了什么接口做为预测输出

不难发现7个个体学习器都使用了predict_proba的概率接口进行输出这与我们选择的算法都是可以输出概率的算法有很大的关系。 

5、Stacking融合的训练和测试流程🎪

现在我们已经知道了stacking算法中所有关于训练的信息我们可以梳理出如下训练流程

  • stacking的训练
    1. 将数据分割为训练集、测试集其中训练集上的样本为𝑀𝑡𝑟𝑎𝑖𝑛测试集上的样本量为𝑀𝑡𝑒𝑠𝑡
       
    2. 将训练集输入level 0的个体学习器分别在每个个体学习器上进行交叉验证。在每个个体学习器上将所有交叉验证的验证结果纵向堆叠形成预测结果。假设预测结果为概率值当融合模型执行回归或二分类任务时该预测结果的结构为(𝑀𝑡𝑟𝑎𝑖𝑛,1)当融合模型执行K分类任务时(K>2)该预测结果的结构为(𝑀𝑡𝑟𝑎𝑖𝑛,𝐾)
       
    3. 将所有个体学习器的预测结果横向拼接形成新特征矩阵。假设共有N个个体学习器当融合模型执行回归或二分类任务时则新特征矩阵的结构为(𝑀𝑡𝑟𝑎𝑖𝑛,𝑁)。如果是输出多分类的概率那最终得出的新特征矩阵的结构为(𝑀𝑡𝑟𝑎𝑖𝑛,𝑁∗𝐾)
    4. 将新特征矩阵放入元学习器进行训练。

不难发现虽然训练的流程看起来比较流畅但是测试却不知道从何做起因为

  • 最终输出预测结果的是元学习器因此直觉上来说测试数据集或许应该被输入到元学习器当中。然而元学习器是使用新特征矩阵进行预测的新特征矩阵的结构与规律都与原始数据不同所以元学习器根本不可能接受从原始数据中分割出来的测试数据。因此正确的做法应该是让测试集输入level 0的个体学习器

  • 然而这又存在问题了level 0的个体学习器们在训练过程中做的是交叉验证而交叉验证只会输出验证结果不会留下被训练的模型。因此在level 0中没有可以用于预测的、已经训练完毕的模型。

为了解决这个矛盾在我们的训练流程中存在着隐藏的步骤

  • stacking的训练

    1. 将数据分割为训练集、测试集其中训练集上的样本为𝑀𝑡𝑟𝑎𝑖𝑛测试集上的样本量为𝑀𝑡𝑒𝑠𝑡
       
    2. 将训练集输入level 0的个体学习器分别在每个个体学习器上进行交叉验证。在每个个体学习器上将所有交叉验证的验证结果纵向堆叠形成预测结果。假设预测结果为概率值当融合模型执行回归或二分类任务时该预测结果的结构为(𝑀𝑡𝑟𝑎𝑖𝑛,1)当融合模型执行K分类任务时(K>2)该预测结果的结构为(𝑀𝑡𝑟𝑎𝑖𝑛,𝐾)
       
    3. 隐藏步骤使用全部训练数据对所有个体学习器进行训练为测试做好准备。
       
    4. 将所有个体学习器的预测结果横向拼接形成新特征矩阵。假设共有N个个体学习器则新特征矩阵的结构为(𝑀𝑡𝑟𝑎𝑖𝑛,𝑁)如果是输出多分类的概率那最终得出的新特征矩阵的结构为(𝑀𝑡𝑟𝑎𝑖𝑛,𝑁∗𝐾)
    5. 将新特征矩阵放入元学习器进行训练。
  • stacking的测试

    1. 将测试集输入level 0的个体学习器分别在每个个体学习器上预测出相应结果。假设测试结果为概率值当融合模型执行回归或二分类任务时该测试结果的结构为(𝑀𝑡𝑒𝑠𝑡,1)当融合模型执行K分类任务时(K>2)该测试结果的结构为(𝑀𝑡𝑒𝑠𝑡,𝐾)
       
    2. 将所有个体学习器的预测结果横向拼接为新特征矩阵。假设共有N个个体学习器则新特征矩阵的结构为(𝑀𝑡𝑒𝑠𝑡,𝑁)如果是输出多分类的概率那最终得出的新特征矩阵的结构为(𝑀𝑡𝑟𝑎𝑖𝑛,𝑁∗𝐾)
    3. 将新特征矩阵放入元学习器进行预测。

因此在stacking中不仅要对个体学习器完成全部交叉验证还需要在交叉验证结束后重新使用训练数据来训练所有的模型。无怪Stacking融合的复杂度较高、并且运行缓慢了

至此我们学习完投票法和堆叠法了。

 

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: 机器学习