数据竞赛入门-金融风控(贷款违约预测)五、模型融合

前言

本次活动为datawhale与天池联合举办,为金融风控之贷款违约预测挑战赛(入门)
比赛地址:https://tianchi.aliyun.com/competition/entrance/531830/introduction

为什么要进行模型融合

这里得谈到集成学习
集成学习可以分为两类,一种是把强分类器进行强强联合,使得融合后的模型效果更强,称为模型融合。另一种是将弱分类器通过学习算法集成起来变为很强的分类器,称为机器学习元算法。

这里我们把用来进行融合的学习器称为个体学习器。

模型融合的代表有:投票法(Voting)、线性混合(Linear Blending)、Stacking。

而机器学习元算法又可以根据个体学习器之间是否存在依赖关系分为两类,称为Bagging和Boosting:

  • Bagging: 个体学习器不存在依赖关系,可同时对样本随机采样并行化生成个体学习器。代表作为随机森林(Random Forest)
  • Boosting: 个体学习器存在依赖关系,基于前面模型的训练结果误差生成新的模型,必须串行化生成。代表的算法有:Adaboost、GBDT、XGBoost

模型融合

在进行模型融合的时候,也不是说随意的融合就能达到好的效果。进行融合时,所需的集成个体(就是用来集成的模型)应该好而不同。好指的是个体学习器的性能要好,不同指的是个体模型的类别不同。

在这里举个西瓜书的例子,在介绍例子之前,首先提前介绍简单投票法,以分类问题为例,就是每个分类器对样例进行投票,哪个类别得到的票数最多的就是融合后模型的结果。
在这里插入图片描述
在上面的例子中,采用的就是简单的投票法。中间的图b各个模型输出都一样,因此没有什么效果。第三个图c每个分类器的精度只有33%,融合后反而更糟。也就是说,想要模型融合有效果,个体学习器要有一定的准确率,并且要有多样性,学习器之间具有差异,即”好而不同“。

如何做到好而不同呢?可以由下面几个方面:

  • 针对输入数据:使用采样的方法得到不同的样本(比如bagging方法采用自助法进行抽样)
  • 针对特征:对特征进行抽样
  • 针对算法本身:
    • 个体学习器 h t h_{t} ht来自不同的模型集合
    • 个体学习器 h t h_{t} ht来自于同一个模型集合的不同超参数,例如学习率η不同
    • 算法本身具有随机性,例如用不同的随机种子来得到不同的模型
  • 针对输出:对输出表示进行操纵以增强多样性
    • 如将多分类转化为多个二分类任务来训练单模型
    • 将分类输出转化为回归输出等

那么进行模型融合为什么比较好呢?虽然有俗话说:三个臭皮匠赛过诸葛亮,但是我们还是想知道,究竟是如何“赛过诸葛亮”的。这里摘录西瓜书如下:

学习器的结合可能会从三个方面带来好处:

  • 首先,从统计的方面来看,由于学习任务的假设空间往往很大,可能有多个假设在训练集上达到相同的性能,此时若使用单学习器,可能因误选而导致泛化性能不佳,结合多个学习器则会减少这一风险;

  • 第二,从计算的方面来看,学习算法往往会陷入局部极小,有的局部极小点所对应的泛化性能可能很糟糕,而通过多次运行之后进行结合,可降低陷入糟糕局部极小点的风险;

  • 第三,从表示的方面来看,某些学习任务的真实假设可能不在当前学习算法所考虑的假设空间中,此时若使用单学习器则肯定无效,而通过结合多个学习器,由于相应的假设空间有所扩大,有可能学得更好的近似。

在这里插入图片描述

模型融合方法:

回归任务-平均

简单平均法

∙ \bullet 简单平均: H ( x ) = 1 T ∑ i = 1 T h i ( x ) H(\mathbf{x})=\frac{1}{T} \sum_{i=1}^{T} h_{i}(\mathbf{x}) H(x)=T1i=1Thi(x)

  • 简单加权平均,结果直接融合 求多个预测结果的平均值。pre1-pren分别是n组模型预测出来的结果,将其进行加权融

      pre = (pre1 + pre2 + pre3 +...+pren )/n
    

加权平均法
∙ \bullet 加权平均: H ( x ) = 1 T ∑ i = 1 T α i ⋅ h i ( x ) ; α i ≥ 0 ; ∑ i = 1 T α i = 1 H(\mathbf{x})=\frac{1}{T} \sum_{i=1}^{T} \alpha_{i} \cdot h_{i}(\mathbf{x}) ; \quad \alpha_{i} \geq 0 ; \quad \sum_{i=1}^{T} \alpha_{i}=1 H(x)=T1i=1Tαihi(x);αi0;i=1Tαi=1

  • 加权平均法 一般根据之前预测模型的准确率,进行加权融合,将准确性高的模型赋予更高的权重。

      pre = 0.3pre1 + 0.3pre2 + 0.4pre3 
    
#生成一些简单的样本数据, test_prei代表第i个模型的预测值
test_pre1 = [1.2, 3.2, 2.1, 6.2]
test_pre2 = [0.9, 3.1, 2.0, 5.9]
test_pre3 = [1.1, 2.9, 2.2, 6.0]

# y_test_true 代表模型的真实值
y_test_true = [1, 3, 2, 6]

# 可以先看一下各个模型的预测结果
print('Pred1 MAE:',mean_absolute_error(y_test_true, test_pre1)) 
print('Pred2 MAE:',mean_absolute_error(y_test_true, test_pre2)) 
print('Pred3 MAE:',mean_absolute_error(y_test_true, test_pre3))

'''
Pred1 MAE: 0.1750000000000001
Pred2 MAE: 0.07499999999999993
Pred3 MAE: 0.10000000000000009
'''
## 定义结果的mean平均函数
# 下面我们进行加权融合
def Weighted_method(test_pre1, test_pre2, test_pre3, w=[1/3, 1/3, 1/3]):
    Weighted_result = w[0] * pd.Series(test_pre1) + w[1] * pd.Series(test_pre2) + w[2] * pd.Series(test_pre3)
    return Weighted_result

# 根据上面的MAE,我们计算每个模型的权重, 计算方式就是: wi = mae(i) / sum(mae)
w = [0.3, 0.4, 0.3]
Weighted_pre = Weighted_method(test_pre1,test_pre2,test_pre3,w) 
print('Weighted_pre MAE:',mean_absolute_error(y_test_true, Weighted_pre))   # 会发现这个效果会提高一些

#Weighted_pre MAE: 0.05750000000000027

分类任务-投票

简单投票

∙ \bullet 简单投票法: H ( x ) = c a r g m a x ∑ i = 1 T h i j ( x ) H(\mathbf{x})=c_{\mathrm{argmax}} \sum_{i=1}^{T} h_{i}^{j}(\mathbf{x}) H(x)=cargmaxi=1Thij(x)

即各个分类器输出其预测的类别,取最高票对应的类别作为结果。若有多个类别都是最高票,那么随机选取一个。

from xgboost import XGBClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier, VotingClassifier
clf1 = LogisticRegression(random_state=1)
clf2 = RandomForestClassifier(random_state=1)
clf3 = XGBClassifier(learning_rate=0.1, n_estimators=150, max_depth=4, min_child_weight=2, subsample=0.7,objective='binary:logistic')
 
vclf = VotingClassifier(estimators=[('lr', clf1), ('rf', clf2), ('xgb', clf3)])
vclf = vclf .fit(x_train,y_train)
print(vclf .predict(x_test))

加权投票
∙ \bullet 加权投票法: H ( x ) = c a r g m a x ∑ i = 1 T α i ⋅ h i j ( x ) H(\mathbf{x})=c_{\mathrm{argmax}} \sum_{i=1}^{T} \alpha_{i} \cdot h_{i}^{j}(\mathbf{x}) H(x)=cargmaxi=1Tαihij(x)

和上面的简单投票法类似, 不过多了权重 α i , \alpha_{i}, αi, 这样可以区分分类器的重要程度, 通常 α i ≥ 0 ; ∑ i = 1 T α i = 1 \alpha_{i} \geq 0 ; \sum_{i=1}^{T} \alpha_{i}=1 αi0;i=1Tαi=1

#在VotingClassifier中加入参数 voting='soft', weights=[2, 1, 1],weights用于调节基模型的权重
from xgboost import XGBClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier, VotingClassifier
clf1 = LogisticRegression(random_state=1)
clf2 = RandomForestClassifier(random_state=1)
clf3 = XGBClassifier(learning_rate=0.1, n_estimators=150, max_depth=4, min_child_weight=2, subsample=0.7,objective='binary:logistic')
 
vclf = VotingClassifier(estimators=[('lr', clf1), ('rf', clf2), ('xgb', clf3)], voting='soft', weights=[2, 1, 1])
vclf = vclf .fit(x_train,y_train)
print(vclf .predict(x_test))

此外, 个体学习器可能产生不同的 h i j ( x ) h_{i}^{j}(\mathbf{x}) hij(x) 的值, 比如类标记和类概率。

  • 类标记 h i j ( x ) ∈ { 0 , 1 } , h_{i}^{j}(\mathbf{x}) \in\{0,1\}, hij(x){0,1}, h i h_{i} hi 将样本x预测为类别 c j c_{j} cj 取值为1,否则为0。使用类标记的投票亦称 “硬投票” 。(其实就是多分类的输出),使用 类标记的称为硬投票
  • 类概率 h i j ( x ) ∈ [ 0 , 1 ] , h_{i}^{j}(\mathbf{x}) \in[0,1], hij(x)[0,1], 即输出类别为 c j c_{j} cj 的概率。使用类概率的投票称为软投票。对应sklearn中的VotingClassifier中voting参数设为soft。

PS:使用类概率进行结合往往比直接基于类标记的效果好,即使分类器估计出的概率值一般都不太准确。

线性混合 Linear Blending

前面提到过加权平均法, 每个个体学习器的权重不再相等,看起来就像是对每个个体学习器做一个线性组合,这也是线性混合法名字的由来。那么最优的权重是什么呢? 一个直接的想法就是最好的 α i \alpha_{i} αi 使得error最小,即对应了优化问题:
min ⁡ α t ≥ 0 1 M ∑ i = 1 M ( y i − ∑ t = 1 T α t h t ( x i ) ) 2 \min _{\alpha_{t} \geq 0} \frac{1}{M} \sum_{i=1}^{M}\left(y_{i}-\sum_{t=1}^{T} \alpha_{t} h_{t}\left(\mathbf{x}_{i}\right)\right)^{2} αt0minM1i=1M(yit=1Tαtht(xi))2

这里有T个个体学习器,每个学习器用 h t h_{t} ht 表示, 而 α t \alpha_{t} αt 就是对应的权重。

这里我们首先用训练数据训练出所有的h,然后再做线性回归求出 α t \alpha_{t} αt. 注意到这里要求 α t ≥ 0 , \alpha_{t} \geq 0, αt0, 来个拉格朗日函数? 其实不用, 通常我们可以忽略这个条件。以二分类为例如果 α i \alpha_{i} αi 小于0,相当于把模型反过来用。(假如 给你个错误率99%的模型,你反过来用正确率不就99%了么! 这个大家仔细思考)

如何得到 h t h_{t} ht呢? 这里我们将个体学习器称为初级学习器,用于结合的学习器称为次级学习器。首先从数据集中训练出初级学习器,然后" 生成 “一模型则在所有的数据上进行训练(数据量多可能使得模型效果更好)

步骤如下:(理解上面原理再结合步骤看)

  1. 丛训练集 D train D_{\text {train}} Dtrain 中训练得到 h 1 − , h 2 − , ⋯   , h t − , h_{1}^{-}, h_{2}^{-}, \cdots, h_{t}^{-}, h1,h2,,ht, 并对验证集 D v a l D_{v a l} Dval 中的数据 ( x i , y i ) \left(\mathbf{x}_{\mathbf{i}}, y_{i}\right) (xi,yi) 做转换为新的数据集 ( Φ − ( x i ) , y i ) , \left(\Phi^{-}\left(\mathbf{x}_{\mathbf{i}}\right), y_{i}\right), (Φ(xi),yi), 其中 Φ − ( x i ) = ( h 1 − ( x i ) , h 2 − ( x i ) , ⋯   , h t − ( x i ) ) \Phi^{-}\left(\mathbf{x}_{\mathbf{i}}\right)=\left(h_{1}^{-}\left(\mathbf{x}_{\mathbf{i}}\right), h_{2}^{-}\left(\mathbf{x}_{\mathbf{i}}\right), \cdots, h_{t}^{-}\left(\mathbf{x}_{\mathbf{i}}\right)\right) Φ(xi)=(h1(xi),h2(xi),,ht(xi))

  2. 用线性回归求解 α = Lin ⁡ ( { ( z i , y i ) } ) \alpha=\operatorname{Lin}\left(\left\{\left(z_{i}, y_{i}\right)\right\}\right) α=Lin({(zi,yi)})

  3. 最后,用所有的数据D求解得到 h 1 , h 2 , ⋯   , h t , h_{1}, h_{2}, \cdots, h_{t}, h1,h2,,ht, 组成特征变换向量 Φ ( x ) = ( h 1 ( x ) , h 2 ( x ) , ⋯   , h t ( x ) ) \Phi(\mathbf{x})=\left(h_{1}(\mathbf{x}), h_{2}(\mathbf{x}), \cdots, h_{t}(\mathbf{x})\right) Φ(x)=(h1(x),h2(x),,ht(x))

  4. 对于新数据 x , f ( x ) = 1 T ∑ t = 1 T α t h t ( x ) \mathrm{x}, f(\mathbf{x})=\frac{1}{T} \sum_{t=1}^{T} \alpha_{t} h_{t}(\mathbf{x}) x,f(x)=T1t=1Tαtht(x)

boosting/bagging

这两个都是从样本集的角度考虑把多个弱模型集成起来的一种方式, 只不过两者在集成的时候还是有些区别的。这两个其实不是那么神秘了,我们使用的xgb,lgb就属于Boosting方法,而随机森林就是Bagging方式.
1. boosting
图源:刘建平老师图源:刘建平老师

从图中可以看出,Boosting算法的工作机制是首先从训练集用初始权重训练出一个弱学习器1,根据弱学习的学习误差率表现来更新训练样本的权重,使得之前弱学习器1学习误差率高的训练样本点的权重变高,使得这些误差率高的点在后面的弱学习器2中得到更多的重视。

然后基于调整权重后的训练集来训练弱学习器2.,如此重复进行,直到弱学习器数达到事先指定的数目T,最终将这T个弱学习器通过集合策略进行整合,得到最终的强学习器。

推荐阅读:一文弄懂AdaBoost、提升树、残差树、GDBT

2. bagging
图源:刘建平老师图源:刘建平老师

从上图可以看出,Bagging的弱学习器之间的确没有boosting那样的联系。它的特点在“随机采样”。那么什么是随机采样?

随机采样(bootsrap)就是从我们的训练集里面采集固定个数的样本,但是每采集一个样本后,都将样本放回。也就是说,之前采集到的样本在放回后有可能继续被采集到。对于我们的Bagging算法,一般会随机采集和训练集样本数m一样个数的样本。这样得到的采样集和训练集样本的个数相同,但是样本内容不同。如果我们对有m个样本训练集做T次的随机采样,,则由于随机性,T个采样集各不相同。

注意到这和GBDT的子采样是不同的。GBDT的子采样是无放回采样,而Bagging的子采样是放回采样。

对于一个样本, 它在某一次含m个样本的训练集的随机采样中, 每次被采集到的概率是 1 m \frac{1}{m} m1 。不被采集到的概率为1 − 1 m -\frac{1}{m} m1 。如果m次采样都没有被采集中 的概率是 ( 1 − 1 m ) m \left(1-\frac{1}{m}\right)^{m} (1m1)m 。当 m → ∞ m \rightarrow \infty m 时, ( 1 − 1 m ) m → 1 e ≃ 0.36 8 ∘ \left(1-\frac{1}{m}\right)^{m} \rightarrow \frac{1}{e} \simeq 0.368_{\circ} (1m1)me10.368 也就是说, 在bagging的每轮随机采样中, 训练集中大约有36.8%的数据没有被采样集采 集中。

对于这部分大约36.8%的没有被采样到的数据,我们常常称之为袋外数据(Out Of Bag, 简称OOB)。这些数据没有参与训练集模型的拟合,因此可以用来检测模型的泛化能力。

bagging对于弱学习器没有限制,这和Adaboost一样。但是最常用的一般也是决策树和神经网络。

bagging的集合策略也比较简单,对于分类问题,通常使用简单投票法,得到最多票数的类别或者类别之一为最终的模型输出。对于回归问题,通常使用简单平均法,对T个弱学习器得到的回归结果进行算术平均得到最终的模型输出。

由于Bagging算法每次都进行采样来训练模型,因此泛化能力很强,对于降低模型的方差很有作用。当然对于训练集的拟合程度就会差一些,也就是模型的偏倚会大一些。

假设有t个学习器,则我们可以描述Bagging的算法如下:

  • t = 1 , 2 , … , T t=1,2, \ldots, T t=1,2,,T
    通过bootstrap算法抽样得到一个大小为m的采样集D’ ,在该采样集D’ 上训练得到 h t h_{t} ht

最后得到TT h t , h_{t}, ht, 用均匀混合法得到最后的模型。

从方差和偏差的角度看,Bagging主要降低的是方差,如果基算法对随机性比较敏感,那么bagging的结果会比较好。如不剪枝的决策树、神经网络。

了解过决策树算法同学应该知道,决策树算法对数据比较敏感,方差比较大,而刚提过的Bagging算法想让方差较大,最后用投票或平均值来减少最后模型的方差。

如果把决策树和Bagging结合起来呢?这就得到了随机森林。关于随机森林大伙另外可以查资料阅读~

stacking:

推荐阅读:模型融合方法学习总结
Stacking相比Linear Blending来说,更加强大,然而也更容易过拟合。

Stacking做法和Linear Blending类似,首先从数据集中训练出初级学习器,然后”生成“一个新的数据集用于训练次级学习器。为了防止过拟合,采用K折交叉验证法求解。

其图像可以表示为:
在这里插入图片描述
Stacking模型的本质是一种分层的结构,用了大量的基分类器,将其预测的结果作为下一层输入的特征,这样的结构使得它比相互独立训练模型能够获得更多的特征。

下面以一种易于理解但不会实际使用的两层的stacking方法为例,简要说明其结构和工作原理:

假设我们有三个基模型M1,M2,M3,用训练集对其进行训练后,分别用来预测训练集和测试集的结果,得到P1,T1,P2,T2,P3,T3
  在这里插入图片描述
我们将P1,P2,P3合并,作为下一层的训练集,用新的训练集训练模型M4。然后用M4来预测新的测试集(T1,T2,T3合并)得到最终的预测结果。

这种方法的问题在于,模型M1/2/3是我们用整个训练集训练出来的,我们又用这些模型来预测整个训练集的结果,毫无疑问过拟合将会非常严重。因此在实际应用中往往采用交叉验证的方法来解决过拟合问题。

如下图,我们着眼于Stacking方法的第一层,以5折交叉验证为例说明其工作原理:
在这里插入图片描述
Stacking方法的整体结构如下图所示:
在这里插入图片描述示例:

import warnings
warnings.filterwarnings('ignore')
import itertools
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
from sklearn import datasets
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
from sklearn.model_selection import cross_val_score, train_test_split
from mlxtend.plotting import plot_learning_curves
from mlxtend.plotting import plot_decision_regions


# 以python自带的鸢尾花数据集为例
iris = datasets.load_iris()
X, y = iris.data[:, 1:3], iris.target


clf1 = KNeighborsClassifier(n_neighbors=1)
clf2 = RandomForestClassifier(random_state=1)
clf3 = GaussianNB()
lr = LogisticRegression()
sclf = StackingClassifier(classifiers=[clf1, clf2, clf3], 
                          meta_classifier=lr)


label = ['KNN', 'Random Forest', 'Naive Bayes', 'Stacking Classifier']
clf_list = [clf1, clf2, clf3, sclf]
    
fig = plt.figure(figsize=(10,8))
gs = gridspec.GridSpec(2, 2)
grid = itertools.product([0,1],repeat=2)


clf_cv_mean = []
clf_cv_std = []
for clf, label, grd in zip(clf_list, label, grid):
        
    scores = cross_val_score(clf, X, y, cv=5, scoring='accuracy')
    print("Accuracy: %.2f (+/- %.2f) [%s]" %(scores.mean(), scores.std(), label))
    clf_cv_mean.append(scores.mean())
    clf_cv_std.append(scores.std())
        
    clf.fit(X, y)
    ax = plt.subplot(gs[grd[0], grd[1]])
    fig = plot_decision_regions(X=X, y=y, clf=clf)
    plt.title(label)
 

plt.show()
'''
Accuracy: 0.91 (+/- 0.07) [KNN]
Accuracy: 0.94 (+/- 0.04) [Random Forest]
Accuracy: 0.91 (+/- 0.04) [Naive Bayes]
Accuracy: 0.94 (+/- 0.04) [Stacking Classifier]
'''

在这里插入图片描述

blending:

1. 单纯的Holdout
 
一个版本就是单纯的Holdout集,就是我直接把训练集分成两部分,70%作为新的训练集, 30%作为测试集,然后用这70%的训练集分别训练第一层的模型,然后在30%的测试集上进行预测, 把预测的结果作为第二层模型的训练集特征,这是训练部分。 预测部分就是把真正的测试集先用第一层的模型预测,把预测结过作为第二层测试集的特征进行第二层的预测。 过程图长下面这个样子:
在这里插入图片描述

#创建训练的数据集
#创建训练的数据集
data_0 = iris.data
data = data_0[:100,:]

target_0 = iris.target
target = target_0[:100]
 
#模型融合中使用到的各个单模型
clfs = [LogisticRegression(solver='lbfgs'),
        RandomForestClassifier(n_estimators=5, n_jobs=-1, criterion='gini'),
        RandomForestClassifier(n_estimators=5, n_jobs=-1, criterion='entropy'),
        ExtraTreesClassifier(n_estimators=5, n_jobs=-1, criterion='gini'),
        #ExtraTreesClassifier(n_estimators=5, n_jobs=-1, criterion='entropy'),
        GradientBoostingClassifier(learning_rate=0.05, subsample=0.5, max_depth=6, n_estimators=5)]
 
#切分一部分数据作为测试集
X, X_predict, y, y_predict = train_test_split(data, target, test_size=0.3, random_state=2020)

#切分训练数据集为d1,d2两部分
X_d1, X_d2, y_d1, y_d2 = train_test_split(X, y, test_size=0.5, random_state=2020)
dataset_d1 = np.zeros((X_d2.shape[0], len(clfs)))
dataset_d2 = np.zeros((X_predict.shape[0], len(clfs)))
 
for j, clf in enumerate(clfs):
    #依次训练各个单模型
    clf.fit(X_d1, y_d1)
    y_submission = clf.predict_proba(X_d2)[:, 1]
    dataset_d1[:, j] = y_submission
    #对于测试集,直接用这k个模型的预测值作为新的特征。
    dataset_d2[:, j] = clf.predict_proba(X_predict)[:, 1]
    #print("val auc Score: %f" % roc_auc_score(y_predict, dataset_d2[:, j]))

#融合使用的模型
clf = GradientBoostingClassifier(learning_rate=0.02, subsample=0.5, max_depth=6, n_estimators=30)
clf.fit(dataset_d1, y_d2)
y_submission = clf.predict_proba(dataset_d2)[:, 1]
print("Val auc Score of Blending: %f" % (roc_auc_score(y_predict, y_submission))

2. Holdout交叉

第二个版本的话依然是有一个Holdout集合,但是引入了交叉验证的那种思想,也就是每个模型看到的Holdout集合并不一样。即每个模型会看到这个30%的数据会不一样,说白了,就是把Stacking流程中的K-Fold CV 改成 HoldOut CV。第二阶段的stacker模型就基于第一阶段模型对这30%训练数据的预测值进行拟合。

  1. 我们在第一层中, 用70%的训练集训练多个模型, 然后去预测那30%的数据得到预测值Pi, 同时也预测test集得到预测值Ti。 这里注意,那30%的数据每个模型并不是一样,也是类似于交叉验证的那种划分方式,只不过stacking那里是每个模型都会经历K折交叉验证,也就是有多少模型,就会有多少次K折交叉验证,而blending这里是所有模型合起来只经历了一次K折交叉验证(说的有点绕,看下图就容易懂了)
  2. 第二层中,我们就直接用30%数据在第一层预测的结果Pi进行合并, 作为新的训练集train2, test集的预测值Ti合并作为新的测试集test2, 然后训练第二层的模型。
    在这里插入图片描述

更多内容极力推荐阅读:
零基础数据挖掘入门系列(六) - 模型的融合技术大总结与结果部署

Stacking与Blending相比,Blending的优势在于:

  • Blending比较简单,而Stacking相对比较复杂;

  • 能够防止信息泄露:generalizers和stackers使用不同的数据;

  • 不需要和你的队友分享你的随机种子;

而缺点在于:

  • 只用了整体数据的一部分;

  • 最终模型可能对留出集(holdout set)过拟合;

  • Stacking多次交叉验证要更加稳健。

参考:
刘建平Pinard
细语呢喃

推荐阅读:
直接优化性能指标的多排序模型融合方法

©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页