task5 模型融合 打卡

5.1 模型融合目标

对于多种调参完成的模型进行模型融合。

完成对于多种模型的融合,提交融合结果并打卡。

5.2 内容介绍

模型融合是比赛后期一个重要的环节,大体来说有如下的类型方式。

简单加权融合:

回归(分类概率):算术平均融合(Arithmetic mean),几何平均融合(Geometric mean);

分类:投票(Voting)

综合:排序融合(Rank averaging),log融合

stacking/blending:

构建多层模型,并利用预测结果再拟合预测。

boosting/bagging(在xgboost,Adaboost,GBDT中已经用到):

多树的提升方法

5.3 Stacking相关理论介绍

  1. 什么是 stacking

    简单来说 stacking 就是当用初始训练数据学习出若干个基学习器后,将这几个学习器的预测结果作为新的训练集,来学习一个新的学习器。

    将个体学习器结合在一起的时候使用的方法叫做结合策略。对于分类问题,我们可以使用投票法来选择输出最多的类。对于回归问题,我们可以将分类器输出的结果求平均值。

上面说的投票法和平均法都是很有效的结合策略,还有一种结合策略是使用另外一个机器学习算法来将个体机器学习器的结果结合在一起,这个方法就是Stacking。

在stacking方法中,我们把个体学习器叫做初级学习器,用于结合的学习器叫做次级学习器或元学习器(meta-learner),次级学习器用于训练的数据叫做次级训练集。次级训练集是在训练集上用初级学习器得到的。

  1. 如何进行 stacking

    引用机器学习书上的定义:

    过程1-3 是训练出来个体学习器,也就是初级学习器。

    过程5-9是 使用训练出来的个体学习器来得预测的结果,这个预测的结果当做次级学习器的训练集。

    过程11 是用初级学习器预测的结果训练出次级学习器,得到我们最后训练的模型。

    3)Stacking的方法讲解

    首先,我们先从一种“不那么正确”但是容易懂的Stacking方法讲起。

Stacking模型本质上是一种分层的结构,这里简单起见,只分析二级Stacking.假设我们有2个基模型 Model1_1、Model1_2 和 一个次级模型Model2

Step 1. 基模型 Model1_1,对训练集train训练,然后用于预测 train 和 test 的标签列,分别是P1,T1

Model1_1 模型训练:

Step 2. 基模型 Model1_2 ,对训练集train训练,然后用于预测train和test的标签列,分别是P2,T2

Model1_2 模型训练:

Step 3. 分别把P1,P2以及T1,T2合并,得到一个新的训练集和测试集train2,test2.

这就是我们两层堆叠的一种基本的原始思路想法。在不同模型预测的结果基础上再加一层模型,进行再训练,从而得到模型最终的预测。

Stacking本质上就是这么直接的思路,但是直接这样有时对于如果训练集和测试集分布不那么一致的情况下是有一点问题的,其问题在于用初始模型训练的标签再利用真实标签进行再训练,毫无疑问会导致一定的模型过拟合训练集,这样或许模型在测试集上的泛化能力或者说效果会有一定的下降,因此现在的问题变成了如何降低再训练的过拟合性,这里我们一般有两种方法。

次级模型尽量选择简单的线性模型

利用K折交叉验证

K-折交叉验证: 训练:

5.4 代码示例

5.4.1 回归\分类概率-融合:

1)简单加权平均,结果直接融合

5.1 模型融合目标

对于多种调参完成的模型进行模型融合。

完成对于多种模型的融合,提交融合结果并打卡。

5.2 内容介绍

模型融合是比赛后期一个重要的环节,大体来说有如下的类型方式。

简单加权融合:

回归(分类概率):算术平均融合(Arithmetic mean),几何平均融合(Geometric mean);

分类:投票(Voting)

综合:排序融合(Rank averaging),log融合

stacking/blending:

构建多层模型,并利用预测结果再拟合预测。

boosting/bagging(在xgboost,Adaboost,GBDT中已经用到):

多树的提升方法

5.3 Stacking相关理论介绍

  1. 什么是 stacking

    简单来说 stacking 就是当用初始训练数据学习出若干个基学习器后,将这几个学习器的预测结果作为新的训练集,来学习一个新的学习器。

    将个体学习器结合在一起的时候使用的方法叫做结合策略。对于分类问题,我们可以使用投票法来选择输出最多的类。对于回归问题,我们可以将分类器输出的结果求平均值。

上面说的投票法和平均法都是很有效的结合策略,还有一种结合策略是使用另外一个机器学习算法来将个体机器学习器的结果结合在一起,这个方法就是Stacking。

在stacking方法中,我们把个体学习器叫做初级学习器,用于结合的学习器叫做次级学习器或元学习器(meta-learner),次级学习器用于训练的数据叫做次级训练集。次级训练集是在训练集上用初级学习器得到的。

  1. 如何进行 stacking

    引用机器学习书上的定义:

    过程1-3 是训练出来个体学习器,也就是初级学习器。

    过程5-9是 使用训练出来的个体学习器来得预测的结果,这个预测的结果当做次级学习器的训练集。

    过程11 是用初级学习器预测的结果训练出次级学习器,得到我们最后训练的模型。

    3)Stacking的方法讲解

    首先,我们先从一种“不那么正确”但是容易懂的Stacking方法讲起。

Stacking模型本质上是一种分层的结构,这里简单起见,只分析二级Stacking.假设我们有2个基模型 Model1_1、Model1_2 和 一个次级模型Model2

Step 1. 基模型 Model1_1,对训练集train训练,然后用于预测 train 和 test 的标签列,分别是P1,T1

Model1_1 模型训练:

Step 2. 基模型 Model1_2 ,对训练集train训练,然后用于预测train和test的标签列,分别是P2,T2

Model1_2 模型训练:

Step 3. 分别把P1,P2以及T1,T2合并,得到一个新的训练集和测试集train2,test2.

这就是我们两层堆叠的一种基本的原始思路想法。在不同模型预测的结果基础上再加一层模型,进行再训练,从而得到模型最终的预测。

Stacking本质上就是这么直接的思路,但是直接这样有时对于如果训练集和测试集分布不那么一致的情况下是有一点问题的,其问题在于用初始模型训练的标签再利用真实标签进行再训练,毫无疑问会导致一定的模型过拟合训练集,这样或许模型在测试集上的泛化能力或者说效果会有一定的下降,因此现在的问题变成了如何降低再训练的过拟合性,这里我们一般有两种方法。

次级模型尽量选择简单的线性模型

利用K折交叉验证

K-折交叉验证: 训练:

5.4 代码示例

5.4.1 回归\分类概率-融合:

1)简单加权平均,结果直接融合

生成一些简单的样本数据,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]

import numpy as np

import pandas as pd

定义结果的加权平均函数

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

from sklearn import metrics

各模型的预测结果计算MAE

print(‘Pred1 MAE:‘,metrics.mean_absolute_error(y_test_true, test_pre1))

print(‘Pred2 MAE:‘,metrics.mean_absolute_error(y_test_true, test_pre2))

print(‘Pred3 MAE:‘,metrics.mean_absolute_error(y_test_在这里插入代码片true, test_pre3))

Pred1 MAE: 0.175

Pred2 MAE: 0.075

Pred3 MAE: 0.1

根据加权计算MAE

w = [0.3,0.4,0.3] # 定义比重权值

Weighted_pre = Weighted_method(test_pre1,test_pre2,test_pre3,w)

print(‘Weighted_pre MAE:‘,metrics.mean_absolute_error(y_test_true, Weighted_pre))

2) Stacking融合(回归):

from sklearn import linear_model

def Stacking_method(train_reg1,train_reg2,train_reg3,y_train_true,test_pre1,test_pre2,test_pre3,model_L2= linear_model.LinearRegression()):

model_L2.fit(pd.concat([pd.Series(train_reg1),pd.Series(train_reg2),pd.Series(train_reg3)],axis=1).values,y_train_true)

Stacking_result = model_L2.predict(pd.concat([pd.Series(test_pre1),pd.Series(test_pre2),pd.Series(test_pre3)],axis=1).values)

return Stacking_result

生成一些简单的样本数据,test_prei 代表第i个模型的预测值

train_reg1 = [3.2, 8.2, 9.1, 5.2]

train_reg2 = [2.9, 8.1, 9.0, 4.9]

train_reg3 = [3.1, 7.9, 9.2, 5.0]

y_test_true 代表第模型的真实值

y_train_true = [3, 8, 9, 5]

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]

model_L2= linear_model.LinearRegression()

Stacking_pre = Stacking_method(train_reg1,train_reg2,train_reg3,y_train_true,

test_pre1,test_pre2,test_pre3,model_L2)

print(‘Stacking_pre MAE:‘,metrics.mean_absolute_error(y_test_true, Stacking_pre))

可以发现模型结果相对于之前有进一步的提升,这是我们需要注意的一点是,对于第二层Stacking的模型不宜选取的过于复杂,这样会导致模型在训练集上过拟合,从而使得在测试集上并不能达到很好的效果。

5.4.2 分类模型融合:

对于分类,同样的可以使用融合方法,比如简单投票,Stacking...

from sklearn.datasets import make_blobs

from sklearn import datasets

from sklearn.tree import DecisionTreeClassifier

import numpy as np

from sklearn.ensemble import RandomForestClassifier

from sklearn.ensemble import VotingClassifier

from xgboost import XGBClassifier

from sklearn.linear_model import LogisticRegression

from sklearn.svm import SVC

from sklearn.model_selection import train_test_split

from sklearn.datasets import make_moons

from sklearn.metrics import accuracy_score,roc_auc_score

from sklearn.model_selection import cross_val_score

from sklearn.model_selection import StratifiedKFold

Datawhale 零基础入门数据挖掘-Task5 模型融合

五、模型融合

Tip:此部分为零基础入门数据挖掘的 Task5 模型融合 部分,带你来了解各种模型结果的融合方式,在比赛的攻坚时刻冲刺Top,欢迎大家后续多多交流。

赛题:零基础入门数据挖掘 - 二手车交易价格预测

地址:https://tianchi.aliyun.com/competition/entrance/231784/introduction?spm=5176.12281957.1004.1.38b02448ausjSX

5.1 模型融合目标

对于多种调参完成的模型进行模型融合。

完成对于多种模型的融合,提交融合结果并打卡。

5.2 内容介绍

模型融合是比赛后期一个重要的环节,大体来说有如下的类型方式。

简单加权融合:

回归(分类概率):算术平均融合(Arithmetic mean),几何平均融合(Geometric mean);

分类:投票(Voting)

综合:排序融合(Rank averaging),log融合

stacking/blending:

构建多层模型,并利用预测结果再拟合预测。

boosting/bagging(在xgboost,Adaboost,GBDT中已经用到):

多树的提升方法

5.3 Stacking相关理论介绍

  1. 什么是 stacking

    简单来说 stacking 就是当用初始训练数据学习出若干个基学习器后,将这几个学习器的预测结果作为新的训练集,来学习一个新的学习器。

Image

将个体学习器结合在一起的时候使用的方法叫做结合策略。对于分类问题,我们可以使用投票法来选择输出最多的类。对于回归问题,我们可以将分类器输出的结果求平均值。

上面说的投票法和平均法都是很有效的结合策略,还有一种结合策略是使用另外一个机器学习算法来将个体机器学习器的结果结合在一起,这个方法就是Stacking。

在stacking方法中,我们把个体学习器叫做初级学习器,用于结合的学习器叫做次级学习器或元学习器(meta-learner),次级学习器用于训练的数据叫做次级训练集。次级训练集是在训练集上用初级学习器得到的。

  1. 如何进行 stacking

    算法示意图如下:

Image

引用自 西瓜书《机器学习》

过程1-3 是训练出来个体学习器,也就是初级学习器。

过程5-9是 使用训练出来的个体学习器来得预测的结果,这个预测的结果当做次级学习器的训练集。

过程11 是用初级学习器预测的结果训练出次级学习器,得到我们最后训练的模型。

3)Stacking的方法讲解

首先,我们先从一种“不那么正确”但是容易懂的Stacking方法讲起。

Stacking模型本质上是一种分层的结构,这里简单起见,只分析二级Stacking.假设我们有2个基模型 Model1_1、Model1_2 和 一个次级模型Model2

Step 1. 基模型 Model1_1,对训练集train训练,然后用于预测 train 和 test 的标签列,分别是P1,T1

Model1_1 模型训练:

?

?

?

?

?

?

X

t

r

a

i

n

?

?

?

?

?

?

Model1_1 Train



?

?

?

?

?

?

?

Y

T

r

u

e

?

?

?

?

?

?

训练后的模型 Model1_1 分别在 train 和 test 上预测,得到预测标签分别是P1,T1

?

?

?

?

?

?

X

t

r

a

i

n

?

?

?

?

?

?

Model1_1 Predict



?

?

?

?

?

?

?

P

1

?

?

?

?

?

?

?

?

?

?

?

?

X

t

e

s

t

?

?

?

?

?

?

Model1_1 Predict



?

?

?

?

?

?

?

T

1

?

?

?

?

?

?

Step 2. 基模型 Model1_2 ,对训练集train训练,然后用于预测train和test的标签列,分别是P2,T2

Model1_2 模型训练:

?

?

?

?

?

?

X

t

r

a

i

n

?

?

?

?

?

?

Model1_2 Train



?

?

?

?

?

?

?

Y

T

r

u

e

?

?

?

?

?

?

训练后的模型 Model1_2 分别在 train 和 test 上预测,得到预测标签分别是P2,T2

?

?

?

?

?

?

X

t

r

a

i

n

?

?

?

?

?

?

Model1_2 Predict



?

?

?

?

?

?

?

P

2

?

?

?

?

?

?

?

?

?

?

?

?

X

t

e

s

t

?

?

?

?

?

?

Model1_2 Predict



?

?

?

?

?

?

?

T

2

?

?

?

?

?

?

Step 3. 分别把P1,P2以及T1,T2合并,得到一个新的训练集和测试集train2,test2.

Train_2



?

?

?

?

?

?

P

1

?

?

P

2

?

?

?

?

?

?

a

n

d

Test_2



?

?

?

?

?

?

T

1

?

?

T

2

?

?

?

?

?

?

再用 次级模型 Model2 以真实训练集标签为标签训练,以train2为特征进行训练,预测test2,得到最终的测试集预测的标签列

Y

P

r

e

Train_2



?

?

?

?

?

?

P

1

?

?

P

2

?

?

?

?

?

?

Model2 Train



?

?

?

?

?

?

?

Y

T

r

u

e

?

?

?

?

?

?

Test_2



?

?

?

?

?

?

T

1

?

?

T

2

?

?

?

?

?

?

Model1_2 Predict



?

?

?

?

?

?

?

Y

P

r

e

?

?

?

?

?

?

这就是我们两层堆叠的一种基本的原始思路想法。在不同模型预测的结果基础上再加一层模型,进行再训练,从而得到模型最终的预测。

Stacking本质上就是这么直接的思路,但是直接这样有时对于如果训练集和测试集分布不那么一致的情况下是有一点问题的,其问题在于用初始模型训练的标签再利用真实标签进行再训练,毫无疑问会导致一定的模型过拟合训练集,这样或许模型在测试集上的泛化能力或者说效果会有一定的下降,因此现在的问题变成了如何降低再训练的过拟合性,这里我们一般有两种方法。

次级模型尽量选择简单的线性模型

利用K折交叉验证

K-折交叉验证: 训练:

Image

预测:

Image

5.4 代码示例

5.4.1 回归\分类概率-融合:

1)简单加权平均,结果直接融合

1

生成一些简单的样本数据,test_prei 代表第i个模型的预测值

2

test_pre1 = [1.2, 3.2, 2.1, 6.2]

3

test_pre2 = [0.9, 3.1, 2.0, 5.9]

4

test_pre3 = [1.1, 2.9, 2.2, 6.0]

5

?

6

y_test_true 代表第模型的真实值

7

y_test_true = [1, 3, 2, 6]

1

import numpy as np

2

import pandas as pd

3

?

4

定义结果的加权平均函数

5

def Weighted_method(test_pre1,test_pre2,test_pre3,w=[1/3,1/3,1/3]):

6

Weighted_result = w[0]pd.Series(test_pre1)+w[1]pd.Series(test_pre2)+w[2]*pd.Series(test_pre3)

7

return Weighted_result

1

from sklearn import metrics

2

各模型的预测结果计算MAE

3

print(‘Pred1 MAE:‘,metrics.mean_absolute_error(y_test_true, test_pre1))

4

print(‘Pred2 MAE:‘,metrics.mean_absolute_error(y_test_true, test_pre2))

5

print(‘Pred3 MAE:‘,metrics.mean_absolute_error(y_test_true, test_pre3))

Pred1 MAE: 0.175

Pred2 MAE: 0.075

Pred3 MAE: 0.1

1

根据加权计算MAE

2

w = [0.3,0.4,0.3] # 定义比重权值

3

Weighted_pre = Weighted_method(test_pre1,test_pre2,test_pre3,w)

4

print(‘Weighted_pre MAE:‘,metrics.mean_absolute_error(y_test_true, Weighted_pre))

Weighted_pre MAE: 0.0575

可以发现加权结果相对于之前的结果是有提升的,这种我们称其为简单的加权平均。

还有一些特殊的形式,比如mean平均,median平均

1

定义结果的加权平均函数

2

def Mean_method(test_pre1,test_pre2,test_pre3):

3

Mean_result = pd.concat([pd.Series(test_pre1),pd.Series(test_pre2),pd.Series(test_pre3)],axis=1).mean(axis=1)

4

return Mean_result

1

Mean_pre = Mean_method(test_pre1,test_pre2,test_pre3)

2

print(‘Mean_pre MAE:‘,metrics.mean_absolute_error(y_test_true, Mean_pre))

Mean_pre MAE: 0.0666666666667

1

定义结果的加权平均函数

2

def Median_method(test_pre1,test_pre2,test_pre3):

3

Median_result = pd.concat([pd.Series(test_pre1),pd.Series(test_pre2),pd.Series(test_pre3)],axis=1).median(axis=1)

4

return Median_result

1

Median_pre = Median_method(test_pre1,test_pre2,test_pre3)

2

print(‘Median_pre MAE:‘,metrics.mean_absolute_error(y_test_true, Median_pre))

Median_pre MAE: 0.075

2) Stacking融合(回归):

1

from sklearn import linear_model

2

?

3

def Stacking_method(train_reg1,train_reg2,train_reg3,y_train_true,test_pre1,test_pre2,test_pre3,model_L2= linear_model.LinearRegression()):

4

model_L2.fit(pd.concat([pd.Series(train_reg1),pd.Series(train_reg2),pd.Series(train_reg3)],axis=1).values,y_train_true)

5

Stacking_result = model_L2.predict(pd.concat([pd.Series(test_pre1),pd.Series(test_pre2),pd.Series(test_pre3)],axis=1).values)

6

return Stacking_result

1

生成一些简单的样本数据,test_prei 代表第i个模型的预测值

2

train_reg1 = [3.2, 8.2, 9.1, 5.2]

3

train_reg2 = [2.9, 8.1, 9.0, 4.9]

4

train_reg3 = [3.1, 7.9, 9.2, 5.0]

5

y_test_true 代表第模型的真实值

6

y_train_true = [3, 8, 9, 5]

7

?

8

test_pre1 = [1.2, 3.2, 2.1, 6.2]

9

test_pre2 = [0.9, 3.1, 2.0, 5.9]

10

test_pre3 = [1.1, 2.9, 2.2, 6.0]

11

?

12

y_test_true 代表第模型的真实值

13

y_test_true = [1, 3, 2, 6]

1

model_L2= linear_model.LinearRegression()

2

Stacking_pre = Stacking_method(train_reg1,train_reg2,train_reg3,y_train_true,

3

test_pre1,test_pre2,test_pre3,model_L2)

4

print(‘Stacking_pre MAE:‘,metrics.mean_absolute_error(y_test_true, Stacking_pre))

Stacking_pre MAE: 0.0421348314607

可以发现模型结果相对于之前有进一步的提升,这是我们需要注意的一点是,对于第二层Stacking的模型不宜选取的过于复杂,这样会导致模型在训练集上过拟合,从而使得在测试集上并不能达到很好的效果。

5.4.2 分类模型融合:

对于分类,同样的可以使用融合方法,比如简单投票,Stacking...

from sklearn.datasets import make_blobs

from sklearn import datasets

from sklearn.tree import DecisionTreeClassifier

import numpy as np

from sklearn.ensemble import RandomForestClassifier

from sklearn.ensemble import VotingClassifier

from xgboost import XGBClassifier

from sklearn.linear_model import LogisticRegression

from sklearn.svm import SVC

from sklearn.model_selection import train_test_split

from sklearn.datasets import make_moons

from sklearn.metrics import accuracy_score,roc_auc_score

from sklearn.model_selection import cross_val_score

from sklearn.model_selection import StratifiedKFold

1

from sklearn.datasets import make_blobs

2

from sklearn import datasets

3

from sklearn.tree import DecisionTreeClassifier

4

import numpy as np

5

from sklearn.ensemble import RandomForestClassifier

6

from sklearn.ensemble import VotingClassifier

7

from xgboost import XGBClassifier

8

from sklearn.linear_model import LogisticRegression

9

from sklearn.svm import SVC

10

from sklearn.model_selection import train_test_split

11

from sklearn.datasets import make_moons

12

from sklearn.metrics import accuracy_score,roc_auc_score

13

from sklearn.model_selection import cross_val_score

14

from sklearn.model_selection import StratifiedKFold

1)Voting投票机制:

Voting即投票机制,分为软投票和硬投票两种,其原理采用少数服从多数的思想。

‘‘‘

硬投票:对多个模型直接进行投票,不区分模型结果的相对重要度,最终投票数最多的类为最终被预测的类。

‘‘‘

iris = datasets.load_iris()

x=iris.data

y=iris.target

x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3)

clf1 = XGBClassifier(learning_rate=0.1, n_estimators=150, max_depth=3, min_child_weight=2, subsample=0.7,

colsample_bytree=0.6, objective=‘binary:logistic‘)

clf2 = RandomForestClassifier(n_estimators=50, max_depth=1, min_samples_split=4,

min_samples_leaf=63,oob_score=True)

clf3 = SVC(C=0.1)

硬投票

eclf = VotingClassifier(estimators=[(‘xgb‘, clf1), (‘rf‘, clf2), (‘svc‘, clf3)], voting=‘hard‘)

for clf, label in zip([clf1, clf2, clf3, eclf], [‘XGBBoosting‘, ‘Random Forest‘, ‘SVM‘, ‘Ensemble‘]):

scores = cross_val_score(clf, x, y, cv=5, scoring=‘accuracy‘)

print("Accuracy: %0.2f (+/- %0.2f) [%s]" % (scores.mean(), scores.std(), label))

‘‘‘

软投票:和硬投票原理相同,增加了设置权重的功能,可以为不同模型设置不同权重,进而区别模型不同的重要度。

‘‘‘

x=iris.data

y=iris.target

x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3)

clf1 = XGBClassifier(learning_rate=0.1, n_estimators=150, max_depth=3, min_child_weight=2, subsample=0.8,

colsample_bytree=0.8, objective=‘binary:logistic‘)

clf2 = RandomForestClassifier(n_estimators=50, max_depth=1, min_samples_split=4,

min_samples_leaf=63,oob_score=True)

clf3 = SVC(C=0.1, probability=True)

软投票

eclf = VotingClassifier(estimators=[(‘xgb‘, clf1), (‘rf‘, clf2), (‘svc‘, clf3)], voting=‘soft‘, weights=[2, 1, 1])

clf1.fit(x_train, y_train)

for clf, label in zip([clf1, clf2, clf3, eclf], [‘XGBBoosting‘, ‘Random Forest‘, ‘SVM‘, ‘Ensemble‘]):

scores = cross_val_score(clf, x, y, cv=5, scoring=‘accuracy‘)

print("Accuracy: %0.2f (+/- %0.2f) [%s]" % (scores.mean(), scores.std(), label))

Datawhale 零基础入门数据挖掘-Task5 模型融合

五、模型融合

Tip:此部分为零基础入门数据挖掘的 Task5 模型融合 部分,带你来了解各种模型结果的融合方式,在比赛的攻坚时刻冲刺Top,欢迎大家后续多多交流。

赛题:零基础入门数据挖掘 - 二手车交易价格预测

地址:https://tianchi.aliyun.com/competition/entrance/231784/introduction?spm=5176.12281957.1004.1.38b02448ausjSX

5.1 模型融合目标

对于多种调参完成的模型进行模型融合。

完成对于多种模型的融合,提交融合结果并打卡。

5.2 内容介绍

模型融合是比赛后期一个重要的环节,大体来说有如下的类型方式。

简单加权融合:

回归(分类概率):算术平均融合(Arithmetic mean),几何平均融合(Geometric mean);

分类:投票(Voting)

综合:排序融合(Rank averaging),log融合

stacking/blending:

构建多层模型,并利用预测结果再拟合预测。

boosting/bagging(在xgboost,Adaboost,GBDT中已经用到):

多树的提升方法

5.3 Stacking相关理论介绍

  1. 什么是 stacking

    简单来说 stacking 就是当用初始训练数据学习出若干个基学习器后,将这几个学习器的预测结果作为新的训练集,来学习一个新的学习器。

Image

将个体学习器结合在一起的时候使用的方法叫做结合策略。对于分类问题,我们可以使用投票法来选择输出最多的类。对于回归问题,我们可以将分类器输出的结果求平均值。

上面说的投票法和平均法都是很有效的结合策略,还有一种结合策略是使用另外一个机器学习算法来将个体机器学习器的结果结合在一起,这个方法就是Stacking。

在stacking方法中,我们把个体学习器叫做初级学习器,用于结合的学习器叫做次级学习器或元学习器(meta-learner),次级学习器用于训练的数据叫做次级训练集。次级训练集是在训练集上用初级学习器得到的。

  1. 如何进行 stacking

    算法示意图如下:

Image

引用自 西瓜书《机器学习》

过程1-3 是训练出来个体学习器,也就是初级学习器。

过程5-9是 使用训练出来的个体学习器来得预测的结果,这个预测的结果当做次级学习器的训练集。

过程11 是用初级学习器预测的结果训练出次级学习器,得到我们最后训练的模型。

3)Stacking的方法讲解

首先,我们先从一种“不那么正确”但是容易懂的Stacking方法讲起。

Stacking模型本质上是一种分层的结构,这里简单起见,只分析二级Stacking.假设我们有2个基模型 Model1_1、Model1_2 和 一个次级模型Model2

Step 1. 基模型 Model1_1,对训练集train训练,然后用于预测 train 和 test 的标签列,分别是P1,T1

Model1_1 模型训练:

?

?

?

?

?

?

X

t

r

a

i

n

?

?

?

?

?

?

Model1_1 Train



?

?

?

?

?

?

?

Y

T

r

u

e

?

?

?

?

?

?

训练后的模型 Model1_1 分别在 train 和 test 上预测,得到预测标签分别是P1,T1

?

?

?

?

?

?

X

t

r

a

i

n

?

?

?

?

?

?

Model1_1 Predict



?

?

?

?

?

?

?

P

1

?

?

?

?

?

?

?

?

?

?

?

?

X

t

e

s

t

?

?

?

?

?

?

Model1_1 Predict



?

?

?

?

?

?

?

T

1

?

?

?

?

?

?

Step 2. 基模型 Model1_2 ,对训练集train训练,然后用于预测train和test的标签列,分别是P2,T2

Model1_2 模型训练:

?

?

?

?

?

?

X

t

r

a

i

n

?

?

?

?

?

?

Model1_2 Train



?

?

?

?

?

?

?

Y

T

r

u

e

?

?

?

?

?

?

训练后的模型 Model1_2 分别在 train 和 test 上预测,得到预测标签分别是P2,T2

?

?

?

?

?

?

X

t

r

a

i

n

?

?

?

?

?

?

Model1_2 Predict



?

?

?

?

?

?

?

P

2

?

?

?

?

?

?

?

?

?

?

?

?

X

t

e

s

t

?

?

?

?

?

?

Model1_2 Predict



?

?

?

?

?

?

?

T

2

?

?

?

?

?

?

Step 3. 分别把P1,P2以及T1,T2合并,得到一个新的训练集和测试集train2,test2.

Train_2



?

?

?

?

?

?

P

1

?

?

P

2

?

?

?

?

?

?

a

n

d

Test_2



?

?

?

?

?

?

T

1

?

?

T

2

?

?

?

?

?

?

再用 次级模型 Model2 以真实训练集标签为标签训练,以train2为特征进行训练,预测test2,得到最终的测试集预测的标签列

Y

P

r

e

Train_2



?

?

?

?

?

?

P

1

?

?

P

2

?

?

?

?

?

?

Model2 Train



?

?

?

?

?

?

?

Y

T

r

u

e

?

?

?

?

?

?

Test_2



?

?

?

?

?

?

T

1

?

?

T

2

?

?

?

?

?

?

Model1_2 Predict



?

?

?

?

?

?

?

Y

P

r

e

?

?

?

?

?

?

这就是我们两层堆叠的一种基本的原始思路想法。在不同模型预测的结果基础上再加一层模型,进行再训练,从而得到模型最终的预测。

Stacking本质上就是这么直接的思路,但是直接这样有时对于如果训练集和测试集分布不那么一致的情况下是有一点问题的,其问题在于用初始模型训练的标签再利用真实标签进行再训练,毫无疑问会导致一定的模型过拟合训练集,这样或许模型在测试集上的泛化能力或者说效果会有一定的下降,因此现在的问题变成了如何降低再训练的过拟合性,这里我们一般有两种方法。

次级模型尽量选择简单的线性模型

利用K折交叉验证

K-折交叉验证: 训练:

Image

预测:

Image

5.4 代码示例

5.4.1 回归\分类概率-融合:

1)简单加权平均,结果直接融合

1

生成一些简单的样本数据,test_prei 代表第i个模型的预测值

2

test_pre1 = [1.2, 3.2, 2.1, 6.2]

3

test_pre2 = [0.9, 3.1, 2.0, 5.9]

4

test_pre3 = [1.1, 2.9, 2.2, 6.0]

5

?

6

y_test_true 代表第模型的真实值

7

y_test_true = [1, 3, 2, 6]

1

import numpy as np

2

import pandas as pd

3

?

4

定义结果的加权平均函数

5

def Weighted_method(test_pre1,test_pre2,test_pre3,w=[1/3,1/3,1/3]):

6

Weighted_result = w[0]pd.Series(test_pre1)+w[1]pd.Series(test_pre2)+w[2]*pd.Series(test_pre3)

7

return Weighted_result

1

from sklearn import metrics

2

各模型的预测结果计算MAE

3

print(‘Pred1 MAE:‘,metrics.mean_absolute_error(y_test_true, test_pre1))

4

print(‘Pred2 MAE:‘,metrics.mean_absolute_error(y_test_true, test_pre2))

5

print(‘Pred3 MAE:‘,metrics.mean_absolute_error(y_test_true, test_pre3))

Pred1 MAE: 0.175

Pred2 MAE: 0.075

Pred3 MAE: 0.1

1

根据加权计算MAE

2

w = [0.3,0.4,0.3] # 定义比重权值

3

Weighted_pre = Weighted_method(test_pre1,test_pre2,test_pre3,w)

4

print(‘Weighted_pre MAE:‘,metrics.mean_absolute_error(y_test_true, Weighted_pre))

Weighted_pre MAE: 0.0575

可以发现加权结果相对于之前的结果是有提升的,这种我们称其为简单的加权平均。

还有一些特殊的形式,比如mean平均,median平均

1

定义结果的加权平均函数

2

def Mean_method(test_pre1,test_pre2,test_pre3):

3

Mean_result = pd.concat([pd.Series(test_pre1),pd.Series(test_pre2),pd.Series(test_pre3)],axis=1).mean(axis=1)

4

return Mean_result

1

Mean_pre = Mean_method(test_pre1,test_pre2,test_pre3)

2

print(‘Mean_pre MAE:‘,metrics.mean_absolute_error(y_test_true, Mean_pre))

Mean_pre MAE: 0.0666666666667

1

定义结果的加权平均函数

2

def Median_method(test_pre1,test_pre2,test_pre3):

3

Median_result = pd.concat([pd.Series(test_pre1),pd.Series(test_pre2),pd.Series(test_pre3)],axis=1).median(axis=1)

4

return Median_result

1

Median_pre = Median_method(test_pre1,test_pre2,test_pre3)

2

print(‘Median_pre MAE:‘,metrics.mean_absolute_error(y_test_true, Median_pre))

Median_pre MAE: 0.075

2) Stacking融合(回归):

1

from sklearn import linear_model

2

?

3

def Stacking_method(train_reg1,train_reg2,train_reg3,y_train_true,test_pre1,test_pre2,test_pre3,model_L2= linear_model.LinearRegression()):

4

model_L2.fit(pd.concat([pd.Series(train_reg1),pd.Series(train_reg2),pd.Series(train_reg3)],axis=1).values,y_train_true)

5

Stacking_result = model_L2.predict(pd.concat([pd.Series(test_pre1),pd.Series(test_pre2),pd.Series(test_pre3)],axis=1).values)

6

return Stacking_result

1

生成一些简单的样本数据,test_prei 代表第i个模型的预测值

2

train_reg1 = [3.2, 8.2, 9.1, 5.2]

3

train_reg2 = [2.9, 8.1, 9.0, 4.9]

4

train_reg3 = [3.1, 7.9, 9.2, 5.0]

5

y_test_true 代表第模型的真实值

6

y_train_true = [3, 8, 9, 5]

7

?

8

test_pre1 = [1.2, 3.2, 2.1, 6.2]

9

test_pre2 = [0.9, 3.1, 2.0, 5.9]

10

test_pre3 = [1.1, 2.9, 2.2, 6.0]

11

?

12

y_test_true 代表第模型的真实值

13

y_test_true = [1, 3, 2, 6]

1

model_L2= linear_model.LinearRegression()

2

Stacking_pre = Stacking_method(train_reg1,train_reg2,train_reg3,y_train_true,

3

test_pre1,test_pre2,test_pre3,model_L2)

4

print(‘Stacking_pre MAE:‘,metrics.mean_absolute_error(y_test_true, Stacking_pre))

Stacking_pre MAE: 0.0421348314607

可以发现模型结果相对于之前有进一步的提升,这是我们需要注意的一点是,对于第二层Stacking的模型不宜选取的过于复杂,这样会导致模型在训练集上过拟合,从而使得在测试集上并不能达到很好的效果。

5.4.2 分类模型融合:

对于分类,同样的可以使用融合方法,比如简单投票,Stacking...

from sklearn.datasets import make_blobs

from sklearn import datasets

from sklearn.tree import DecisionTreeClassifier

import numpy as np

from sklearn.ensemble import RandomForestClassifier

from sklearn.ensemble import VotingClassifier

from xgboost import XGBClassifier

from sklearn.linear_model import LogisticRegression

from sklearn.svm import SVC

from sklearn.model_selection import train_test_split

from sklearn.datasets import make_moons

from sklearn.metrics import accuracy_score,roc_auc_score

from sklearn.model_selection import cross_val_score

from sklearn.model_selection import StratifiedKFold

1

from sklearn.datasets import make_blobs

2

from sklearn import datasets

3

from sklearn.tree import DecisionTreeClassifier

4

import numpy as np

5

from sklearn.ensemble import RandomForestClassifier

6

from sklearn.ensemble import VotingClassifier

7

from xgboost import XGBClassifier

8

from sklearn.linear_model import LogisticRegression

9

from sklearn.svm import SVC

10

from sklearn.model_selection import train_test_split

11

from sklearn.datasets import make_moons

12

from sklearn.metrics import accuracy_score,roc_auc_score

13

from sklearn.model_selection import cross_val_score

14

from sklearn.model_selection import StratifiedKFold

1)Voting投票机制:

Voting即投票机制,分为软投票和硬投票两种,其原理采用少数服从多数的思想。

1

‘‘‘

2

硬投票:对多个模型直接进行投票,不区分模型结果的相对重要度,最终投票数最多的类为最终被预测的类。

3

‘‘‘

4

iris = datasets.load_iris()

5

?

6

x=iris.data

7

y=iris.target

8

x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3)

9

?

10

clf1 = XGBClassifier(learning_rate=0.1, n_estimators=150, max_depth=3, min_child_weight=2, subsample=0.7,

11

colsample_bytree=0.6, objective=‘binary:logistic‘)

12

clf2 = RandomForestClassifier(n_estimators=50, max_depth=1, min_samples_split=4,

13

min_samples_leaf=63,oob_score=True)

14

clf3 = SVC(C=0.1)

15

?

16

硬投票

17

eclf = VotingClassifier(estimators=[(‘xgb‘, clf1), (‘rf‘, clf2), (‘svc‘, clf3)], voting=‘hard‘)

18

for clf, label in zip([clf1, clf2, clf3, eclf], [‘XGBBoosting‘, ‘Random Forest‘, ‘SVM‘, ‘Ensemble‘]):

19

scores = cross_val_score(clf, x, y, cv=5, scoring=‘accuracy‘)

20

print("Accuracy: %0.2f (+/- %0.2f) [%s]" % (scores.mean(), scores.std(), label))

1

‘‘‘

2

软投票:和硬投票原理相同,增加了设置权重的功能,可以为不同模型设置不同权重,进而区别模型不同的重要度。

3

‘‘‘

4

x=iris.data

5

y=iris.target

6

x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3)

7

?

8

clf1 = XGBClassifier(learning_rate=0.1, n_estimators=150, max_depth=3, min_child_weight=2, subsample=0.8,

9

colsample_bytree=0.8, objective=‘binary:logistic‘)

10

clf2 = RandomForestClassifier(n_estimators=50, max_depth=1, min_samples_split=4,

11

min_samples_leaf=63,oob_score=True)

12

clf3 = SVC(C=0.1, probability=True)

13

?

14

软投票

15

eclf = VotingClassifier(estimators=[(‘xgb‘, clf1), (‘rf‘, clf2), (‘svc‘, clf3)], voting=‘soft‘, weights=[2, 1, 1])

16

clf1.fit(x_train, y_train)

17

?

18

for clf, label in zip([clf1, clf2, clf3, eclf], [‘XGBBoosting‘, ‘Random Forest‘, ‘SVM‘, ‘Ensemble‘]):

19

scores = cross_val_score(clf, x, y, cv=5, scoring=‘accuracy‘)

20

print("Accuracy: %0.2f (+/- %0.2f) [%s]" % (scores.mean(), scores.std(), label))

2)分类的Stacking\Blending融合:

‘‘‘

5-Fold Stacking

‘‘‘

from sklearn.ensemble import RandomForestClassifier

from sklearn.ensemble import ExtraTreesClassifier,GradientBoostingClassifier

import pandas as pd

创建训练的数据集

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‘),

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)

dataset_blend_train = np.zeros((X.shape[0], len(clfs)))

dataset_blend_test = np.zeros((X_predict.shape[0], len(clfs)))

5折stacking

n_splits = 5

skf = StratifiedKFold(n_splits)

skf = skf.split(X, y)

for j, clf in enumerate(clfs):

#依次训练各个单模型

dataset_blend_test_j = np.zeros((X_predict.shape[0], 5))

for i, (train, test) in enumerate(skf):

#5-Fold交叉训练,使用第i个部分作为预测,剩余的部分来训练模型,获得其预测的输出作为第i部分的新特征。

X_train, y_train, X_test, y_test = X[train], y[train], X[test], y[test]

clf.fit(X_train, y_train)

y_submission = clf.predict_proba(X_test)[:, 1]

dataset_blend_train[test, j] = y_submission

dataset_blend_test_j[:, i] = clf.predict_proba(X_predict)[:, 1]

#对于测试集,直接用这k个模型的预测值均值作为新的特征。

dataset_blend_test[:, j] = dataset_blend_test_j.mean(1)

print("val auc Score: %f" % roc_auc_score(y_predict, dataset_blend_test[:, j]))

clf = LogisticRegression(solver=‘lbfgs‘)

clf.fit(dataset_blend_train, y)

y_submission = clf.predict_proba(dataset_blend_test)[:, 1]

print("Val auc Score of Stacking: %f" % (roc_auc_score(y_predict, y_submission)))

Blending优点在于:

1.比stacking简单(因为不用进行k次的交叉验证来获得stacker feature)

2.避开了一个信息泄露问题:generlizers和stacker使用了不一样的数据集

缺点在于:

1.使用了很少的数据(第二阶段的blender只使用training set10%的量)

2.blender可能会过拟合

3.stacking使用多次的交叉验证会比较稳健 ‘‘‘

原文地址:https://www.cnblogs.com/david750/p/12636653.html

时间: 2024-10-09 01:38:11

task5 模型融合 打卡的相关文章

CS231n 卷积神经网络与计算机视觉 7 神经网络训练技巧汇总 梯度检验 参数更新 超参数优化 模型融合 等

前面几章已经介绍了神经网络的结构.数据初始化.激活函数.损失函数等问题,现在我们该讨论如何让神经网络模型进行学习了. 1 梯度检验 权重的更新梯度是否正确决定着函数是否想着正确的方向迭代,在UFLDL中我们提到过,计算时梯度公式如果计算错误是不容被察觉的,我们需要比较分析法得到梯度与数值法得到的梯度是否相似,下面是一些技巧: 1.1 centered formula 高等数学中我们知道导数的近似公式: df(x)dx=f(x+h)?f(x)h 以及下面的centered formula: df(

多模型融合推荐算法

常见的多模型融合算法 多模型融合算法可以比单一模型算法有极为明显的效果提升.但是怎样进行有效的融合,充分发挥各个算法的长处?这里总结一些常见的融合方法: 1. 线性加权融合法 线性加权是最简单易用的融合算法,工程实现非常方便,只需要汇总单一模型的结果,然后按不同算法赋予不同的权重,将多个推荐算法的结果进行加权,即可得到结果: 是给用户(user)推荐商品(item)的得分, 是算法K的权重,是算法k得到的用户(user)对商品item的推荐得分.这种融合方式实现简单,但效果较差.因为线性加权的参

十大经典预测算法六---集成学习(模型融合算法)

模型融合算法概念 它不是具体的指某一个算法,而是一种把多个弱模型融合合并在一起变成一个强模型的思想 用模型融合算法的原因 1.单个模型容易过拟合,多个模型融合可以提高范化能力 2.单个模型预测能力不高,多个模型往往能提高预测能力 3.对于数据集过大或过小,可以分别进行划分和有放回的操作,产生不同的数据子集,然后通过数据子集训练不同的分类模型,最终合并成一个大的分类器 4.对于多个异构的特征集的时候,很难进行融合,可以考虑每个数据集构建一个分类模型,然后将多个模型融合 5.模型融合算法成功的关键在

Gluon炼丹(Kaggle 120种狗分类,迁移学习加双模型融合)

http://www.cnblogs.com/fiercex/p/7927804.html fiercex 路漫漫其修远兮,吾将上下而求索 Gluon炼丹(Kaggle 120种狗分类,迁移学习加双模型融合) 这是在kaggle上的一个练习比赛,使用的是ImageNet数据集的子集.注意,mxnet版本要高于0.12.1b2017112.下载数据集. train.zip test.zip labels然后解压在data文件夹下 1. 数据 1.1 整理数据 将解压后的数据整理成Gluon能够读取

模型融合

一.Voting 模型融合其实也没有想象的那么高大上,从最简单的Voting说起,这也可以说是一种模型融合.假设对于一个二分类问题,有3个基础模型,那么就采取投票制的方法,投票多者确定为最终的分类. 二.Averaging 对于回归问题,一个简单直接的思路是取平均.稍稍改进的方法是进行加权平均.权值可以用排序的方法确定,举个例子,比如A.B.C三种基本模型,模型效果进行排名,假设排名分别是1,2,3,那么给这三个模型赋予的权值分别是3/6.2/6.1/6这两种方法看似简单,其实后面的高级算法也可

谈谈模型融合之一 —— 集成学习与 AdaBoost

前言 前面的文章中介绍了决策树以及其它一些算法,但是,会发现,有时候使用使用这些算法并不能达到特别好的效果.于是乎就有了集成学习(Ensemble Learning),通过构建多个学习器一起结合来完成具体的学习任务.这篇文章将介绍集成学习,以及其中的一种算法 AdaBoost. 集成学习 首先先来介绍下什么是集成学习: 构建多个学习器一起结合来完成具体的学习任务,常可获得比单一学习器显著优越的泛化性能,对"弱学习器" 尤为明显(三个臭皮匠,顶个诸葛亮) 也称为Multi-Classif

谈谈模型融合之二 —— 随机森林

前言 上篇文章介绍了集成学习的相关概念以及基于 Boosting的 AdaBoost,这篇文章将介绍基于模型融合的另一种方式 Bagging 的算法,随机森林(Random Forest).(上篇公式敲的太累了这篇就来个简单的缓解缓解) 随机森林 算法思想 我们先来看看这个算法的名字,可以拆分开为两部分,随机和森林.森林我们很容易可以想到,就是有很多棵树,即由多颗决策树组成.那么随机指的是什么呢?这里我们来看看 Bagging 的思想了. 首先先说说自助采样(Bootstrap Sanpling

基于BERT的多模型融合借鉴

本次介绍假新闻赛道一第一名的构建思路,大家一起学习下 任务描述 文本是新闻信息的主要载体,对新闻文本的研究有助于虚假新闻的有效识别.虚假新闻文本检测,具体任务为:给定一个新闻事件的文本,判定该事件属于真实新闻还是虚假新闻.该任务可抽象为NLP领域的文本分类任务,根据新闻文本内容,判定该新闻是真新闻还是假新闻.针对该任务,本文采用BERT-Finetune.BERT-CNN-Pooling.BERT-RCN-Pooling的多种结构进行融合,在输入上引入字词结合的形式,另外充分利用假新闻的关键词特

模型融合之blending和stacking

1. blending 需要得到各个模型结果集的权重,然后再线性组合. """Kaggle competition: Predicting a Biological Response. Blending {RandomForests, ExtraTrees, GradientBoosting} + stretching to [0,1]. The blending scheme is related to the idea Jose H. Solorzano presente