金融贷款逾期的模型构建7——模型融合

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012736685/article/details/86062182


数据传送门(data.csv)https://pan.baidu.com/s/1G1b2QJjYkkk7LDfGorbj5Q
目标:数据集是金融数据(非脱敏),要预测贷款用户是否会逾期。表格中 “status” 是结果标签:0表示未逾期,1表示逾期。

任务:用你目前评分最高的模型作为基准模型,和其他模型进行stacking融合,得到最终模型及评分果。

一、集成学习

集成学习是将几种机器学习算法组合成一个预测模型的算法,以达到减小方差(bagging)、偏差(boosting)或改进预测(stacking)的效果。

1、Bagging

基本思想:给定大小为 n n 的训练集 D D ,Bagging 从中均匀、有放回地选出 m m 个大小为 n n' 的子集 D i D_i ,作为新的训练集。在这么 m m 个训练集上使用分类、回归等算法,可以得到 m m 个模型,再通过平均值(常用于回归问题)、投票法(常用于分类问题)等方法综合产生预测结果,即可得到 Bagging 模型。
在这里插入图片描述

优点:高效、可并行实现、能不经修改的适用于多分类和回归任务、包外估计。

典型模型:随机森林(Random Forest)

2、Boosting

基本思想:个体学习器之间存在强依赖关系,必须串行序列化生成的集成学习方法。对训练样本分布调整,主要是通过增加误分类样本的权重,降低正确分类样本的权重。

工作机制如下:

  • 先从初始训练集中学习一个基学习器;
  • 根据基学习器的表现对训练样本分布进行调整,使得先前基学习器做错的训练样本在后续收到更多关注;
  • 基于调整后的样本分布来训练下一个基学习器;
  • 如此反复,直到基学习器数目达到 T,最终将这 T 个基学习器进行加权结合。
    在这里插入图片描述
    典型模型:Adaboost

3、Stacking

概述:将个体机器学习器的结果结合在一起,即对学习器的结果再加上一层学习器。将训练集学习器的学习结果作为输入,将训练集的输出作为输出,重新训练一个学习器来得到最终结果。(也就是常说的两层)

术语

  • 弱学习器称为初级学习器,将用于结合的学习器称为次级学习器;
  • 对于测试集,我们首先用初级学习器预测一次,得到次级学习器的输入样本,再用次级学习器预测一次,得到最终的预测结果。

(1)核心图解

在这里插入图片描述
对于每一轮的 5-fold,Model 1都要做满5次的训练和预测。

a、构建新的训练集

  1. 先将训练集 D T r a i n i n g D a t a D(Training Data) 拆成 k k 个大小相似但互不相交的子集 D 1 , D 2 , , D k D_1,D_2,…,D_k
  2. D j = D D j D_j'= D - D_j ,在 D j D_j' 上训练一个弱学习器 L j L_j 。将 D j D_j 作为测试集,获得 L j L_j D j D_j 上的输出 D j D_j''
  3. 步骤2可以得到 k k 个弱学习器以及 k k 个相应的输出 D j D_j'' ,这个 k k 个输出加上原本的类标构成新的训练集 D n D_n
  4. D n D_n 训练次学习器 L L L L 即为最后的学习器。

b、构建新的测试集

  1. 对于每个训练好的一个弱学习器 L j L_j ,在测试集(Test Data,图中所示绿色部分,不要与上面的“测试集”混淆。注意:此处是测试集的全部)进行预测,将 k k 次的预测结果取平均作为新的预测集。

c、最终的训练与预测

  1. 训练集为构建新的训练集步骤得到的训练集,测试集为构建新的测试集得到的测试集
  2. 训练分类器并预测。

(2)示例

a、构建新的训练集

Train Data有890行。(请对应图中的上层部分)

每1次的fold,都会生成 713行 小train, 178行 小test。我们用Model 1来训练 713行的小train,然后预测 178行 小test。预测的结果是长度为 178 的预测值。

这样的动作走5次! 长度为178 的预测值 X 5 = 890 预测值,刚好和Train data长度吻合。这个890预测值是Model 1产生的,我们先存着,因为,一会让它将是第二层模型的训练来源。

重点:这一步产生的预测值我们可以转成 890 X 1 (890 行,1列),记作 P1 (大写P)

b、构建新的测试集

Test Data 有 418 行。(请对应图中的下层部分,对对对,绿绿的那些框框)

每1次的fold,713行 小train训练出来的Model 1要去预测我们全部的Test Data(全部!因为Test Data没有加入5-fold,所以每次都是全部!)。此时,Model 1的预测结果是长度为418的预测值。

这样的动作走5次!我们可以得到一个 5 X 418 的预测值矩阵。然后我们根据行来就平均值,最后得到一个 1 X 418 的平均预测值。

重点:这一步产生的预测值我们可以转成 418 X 1 (418行,1列),记作 p1 (小写p)

c、多模型的处理

走到这里,你的第一层的Model 1完成了它的使命。

第一层还会有其他Model的,比如Model 2,同样的走一遍, 我们有可以得到 890 X 1 (P2) 和 418 X 1 (p2) 列预测值。

这样吧,假设你第一层有3个模型,这样你就会得到:

来自5-fold的预测值矩阵 890 X 3,(P1,P2, P3) 和 来自Test Data预测值矩阵 418 X 3, (p1, p2, p3)。

d、最终的训练与预测

来自5-fold的预测值矩阵 890 X 3 作为你的Train Data,训练第二层的模型
来自Test Data预测值矩阵 418 X 3 就是你的Test Data,用训练好的模型来预测他们吧。

三、实现

目前单模型评分最高的模型是 XGBoost,其评分如下:

准确率:  	训练集:  0.8458 	测试集:  0.7898

1、手动实现

## 手动实现,stacking方法
def get_oof(clf, X_train, y_train, X_test):
    oof_train = np.zeros((ntrain,))     # 1 * 3327
    oof_test = np.zeros((ntest,))       # 1 * 1427
    oof_test_skf = np.empty((5, ntest)) # 5 * 1427

    # for clf in clfs:
    for i,(train_index, test_index) in enumerate(kf.split(X_train)): # X_train:3327*33
        print(train_index)
        kf_X_train = X_train.iloc[train_index]    # 2661*33
        kf_y_train = y_train.iloc[train_index]    # 2661*33
        kf_X_test = X_train.iloc[test_index]       # 666*7

        clf.fit(kf_X_train, kf_y_train)    # 学习分类器

        oof_train[test_index] = clf.predict(kf_X_test)  # 1*666
        oof_test_skf[i, :] = clf.predict(X_test)        # 测试集的预测作为测试数据

    oof_test[:] = oof_test_skf.mean(axis=0)   # 测试集的均值作为stcking的测试集
    return oof_train.reshape(-1, 1), oof_test.reshape(-1, 1)

## 使用多模型实现
rf_model = RandomForestClassifier()
xgbt_model = xgb.XGBClassifier()
gdbt_model = GradientBoostingClassifier()
dt_model = DecisionTreeClassifier()

train_sets = []
test_sets = []

for clf in [rf_model, xgbt_model, gdbt_model]:
    train_set, test_set = get_oof(clf, X_train, y_train, X_test)
    train_sets.append(train_set)
    test_sets.append(test_set)

meta_train = np.concatenate([result_set for result_set in train_sets], axis=1)
meta_test = np.concatenate([y_test_set for y_test_set in test_sets], axis=1)

# 使用决策树作为次级分类器
dt_model = DecisionTreeClassifier()
dt_model.fit(meta_train,y_train)
# df_predict = dt_model.predict(meta_test)

## 模型评估
model_metrics(dt_model, meta_train, meta_test, y_train, y_test)

==》

<准确率>:
训练集: 0.8031
测试集: 0.7884
<auc值>:
训练集: 0.6853
测试集: 0.6579

2、StackingClassifier类实现

## 使用多模型实现
from mlxtend.classifier import StackingClassifier

rf_model = RandomForestClassifier()
xgbt_model = xgb.XGBClassifier()
gdbt_model = GradientBoostingClassifier()
dt_model = DecisionTreeClassifier()

sclf = StackingClassifier(classifiers=[rf_model,xgbt_model,gdbt_model],meta_classifier=dt_model)
sclf.fit(X_train,y_train)

for clf,label in zip([rf_model,xgbt_model,gdbt_model,sclf],['随机森林','XGBoost','GBDT','StackingClassifier']):
    scores = cross_val_score(clf,X_train,y_train,cv = 5,scoring='accuracy')
    print("Accuracy: %0.2f (+/- %0.2f) [%s]"% (scores.mean(), scores.std(), label))

==》

Accuracy: 0.77 (+/- 0.01) [随机森林]
Accuracy: 0.80 (+/- 0.00) [XGBoost]
Accuracy: 0.79 (+/- 0.01) [GBDT]
Accuracy: 0.78 (+/- 0.01) [StackingClassifier]

小结

  • 从结果来看,本文的Stacking结果和只是用XGBoost的结果基本持平(实际略低于XGBoost)。
    • 换用一些弱分类器作为基本分类器效果会怎么样?

Reference

  1. https://zhuanlan.zhihu.com/p/26890738

猜你喜欢

转载自blog.csdn.net/u012736685/article/details/86062182
今日推荐