ML - 贷款用户逾期情况分析4 - 模型融合之Stacking

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

模型融合之Stacking (判定贷款用户是否逾期)

给定金融数据,预测贷款用户是否会逾期。(status是标签:0表示未逾期,1表示逾期。)

Task7(模型融合) - 对Task6调优后的模型, 进行模型融合。例如, 用目前评分最高的模型作为基准模型, 和其他模型进行stacking模型融合, 得到最终模型和评分。

1. 理论介绍

1.1 系统解释

学习器的结合策略有:平均法、投票法和学习法。
对回归问题,平均法就是对若干个学习器的输出进行平均得到最终的预测输出。复杂点还可以对每个学习器设置权重。
对分类问题,投票法就是多数表决法(少数服从多数)。

Stacking学习法的代表方法,这里我们不再对学习器的结果做简单的逻辑处理,而是再加上一层学习器。将训练集学习器的学习结果作为输入,将训练集的输出作为输出,重新训练一个学习器来得到最终结果。

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

1.2 详细解释

stacking有一张经典的图:
Stacking

下面用语言对其详细解释。

首先选几个模型作为第一层模型进行5折交叉验证。

例如:分别选用LR、SVM和决策树作为第一层模型Model1,分别实施以下步骤:
1)把train分train1~train5,共5份,用其中4份预测剩下的那份,同时预测test数据,这样的过程做5次,生成5份train(原train样本数/5)数据和5份test数据。
2)把5份预测的train数据纵向叠起来(即为原来的整个train,只是顺序不同),把test预测的结果做平均。

扫描二维码关注公众号,回复: 4361459 查看本文章

将三个模型得到的train并列合并成一个3列的矩阵作为training-data,得到的test并列合并成一个3列的矩阵作为testing-data。
让下一层的模型,基于他们进一步训练。

2. 代码

import pandas as pd
import pickle

# 数据集预览
data = pd.read_csv('data.csv')
# 去重
data.drop_duplicates(inplace=True)
print(data.shape)
data.head()
# 载入特征
with open('feature.pkl', 'rb') as f:
    X = pickle.load(f)

# 观测正负样本是否均衡
y = data.status
y.value_counts()
# 划分训练集测试集
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3,random_state=2333)

# 特征归一化
std = StandardScaler()
X_train = std.fit_transform(X_train.values)
X_test = std.transform(X_test.values)

模型评估

from sklearn.metrics import accuracy_score, roc_auc_score

def model_metrics(clf, X_train, X_test, y_train, y_test):
    # 预测
    y_train_pred = clf.predict(X_train)
    y_test_pred = clf.predict(X_test)
    
    y_train_proba = clf.predict_proba(X_train)[:,1]
    y_test_proba = clf.predict_proba(X_test)[:,1]
    
    # 准确率
    print('[准确率]', end = ' ')
    print('训练集:', '%.4f'%accuracy_score(y_train, y_train_pred), end = ' ')
    print('测试集:', '%.4f'%accuracy_score(y_test, y_test_pred))
    
    # auc取值:用roc_auc_score或auc
    print('[auc值]', end = ' ')
    print('训练集:', '%.4f'%roc_auc_score(y_train, y_train_proba), end = ' ')
    print('测试集:', '%.4f'%roc_auc_score(y_test, y_test_proba))

模型选择

from sklearn.linear_model import LogisticRegression
from sklearn import svm
from sklearn.tree import DecisionTreeClassifier
from xgboost.sklearn import XGBClassifier
from lightgbm.sklearn import LGBMClassifier

from mlxtend.classifier import StackingClassifier

# 模型调优后得到的参数
lr = LogisticRegression(C = 0.1, penalty = 'l1')
svm_linear = svm.SVC(C = 0.01, kernel = 'linear', probability=True)
svm_poly =  svm.SVC(C = 0.01, kernel = 'poly', probability=True)
svm_rbf =  svm.SVC(gamma = 0.01, C =0.01 , probability=True)
svm_sigmoid =  svm.SVC(C = 0.01, kernel = 'sigmoid',probability=True)
dt = DecisionTreeClassifier(max_depth=11,min_samples_split=550,min_samples_leaf=80,max_features=19)
xgb = XGBClassifier(learning_rate =0.01, n_estimators=180, max_depth=3, min_child_weight=5, 
                    gamma=0.4, subsample=0.5, colsample_bytree=0.9, reg_alpha=1, 
                    objective= 'binary:logistic', nthread=4,scale_pos_weight=1, seed=27)
lgb = LGBMClassifier(learning_rate =0.1, n_estimators=60, max_depth=3, min_child_weight=11, 
                    gamma=0.1, subsample=0.5, colsample_bytree=0.8, reg_alpha=1e-5, 
                    nthread=4,scale_pos_weight=1, seed=27)

2.1 调包实现

使用4种SVM、决策树、XGBoost和LightGBM作为初级分类器,LR作为次级分类器。

1)将初级分类器产生的类别标签作为新特征

import warnings
warnings.filterwarnings("ignore")

sclf = StackingClassifier(classifiers=[svm_linear, svm_poly, svm_rbf, 
                                       svm_sigmoid, dt, xgb, lgb], meta_classifier=lr)
sclf.fit(X_train, y_train.values)
model_metrics(sclf, X_train, X_test, y_train, y_test)

输出

[准确率] 训练集: 0.8242 测试集: 0.8066
[auc值] 训练集: 0.6981 测试集: 0.6765

2)将初级分类器产生的输出类概率作为新特征
对输出概率use_probas=True,有两种不同的处理方式。

假设有2个初级分类器和3个类别输出概率:p1=[0.2,0.5,0.3],p2=[0.3,0.4,0.4]。
如果average_probas=True,则对分类器的结果求平均,得到:p=[0.25,0.45,0.35]
[推荐]如果average_probas=False,则分类器的所有结果都保留作为新的特征:p=[0.2,0.5,0.3,0.3,0.4,0.4]

sclf = StackingClassifier(classifiers=[svm_linear, svm_poly, svm_rbf, svm_sigmoid, dt, xgb, lgb],  meta_classifier=lr, use_probas=True,average_probas=False)
sclf.fit(X_train, y_train.values)
model_metrics(sclf, X_train, X_test, y_train, y_test)

输出

[准确率] 训练集: 0.8365 测试集: 0.8017
[auc值] 训练集: 0.8773 测试集: 0.7962

2.2 自己实现

参见博客模型融合之blending和stacking

遇到的问题

1)sclf.fit(X,y)时会报错
解决:注意X_train是array,而y_train是Series且索引不一定从0开始。此处我们取y_train.values,将y_train也转成array。

Reference

详解stacking过程
集成学习原理小结
集成学习stacking
【机器学习】模型融合方法概述

More

代码参见Github: https://github.com/libihan/Exercise-ML

猜你喜欢

转载自blog.csdn.net/a786150017/article/details/84502918
今日推荐