标准化SMOTE采样框架实现与应用

2019-09-25 17:55:19 浏览数 (2)

文章首发于公众号”大数据风控与机器学习“

一、SMOTE

SMOTE(Synthetic Minority Oversampling Technique)是一种常用于缓解数据不均衡的算法。但是很多小伙伴表示在实际应用中有强烈的过拟合倾向。大多是因为使用流程不规范导致的。本文详细的介绍了一个梅老师自己写的SMOTE过采样流程,并通过一个案例,帮助大家理解其使用。

二、基础模型案例

在开始枯燥的代码解读之前,首先看一下在某金服申请评分卡上的测试。使用数据集data为做过WOE处理后的4个特征的样本集,每个月只保留月末切片代表本月全部样本。将最后一个月作为跨时间验证集evl,其余部分作为训练集train.

代码语言:javascript复制
import pandas as pd
import numpy as np

train = data[data.obs_mth != '2018-06-30'].reset_index().copy()
evl = data[data.obs_mth == '2018-06-30'].reset_index().copy()

feature_lst = ['person_info','finance_info','credit_info','act_info']

x = train[feature_lst]
y = train['bad_ind']

evl_x =  evl[feature_lst]
evl_y = evl['bad_ind']

x = train[feature_lst]
y = train['bad_ind']

evl_x =  evl[feature_lst]
evl_y = evl['bad_ind']

按照通常的逻辑回归评分卡形式,训练一个逻辑回归,看一下模型的表现。

代码语言:javascript复制
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve,auc

lr_model = LogisticRegression(C=0.05,class_weight='balanced')
lr_model.fit(x,y)

y_pred = lr_model.predict_proba(x)[:,1]
fpr_lr_train,tpr_lr_train,_ = roc_curve(y,y_pred)
train_ks = abs(fpr_lr_train - tpr_lr_train).max()
print('train_ks : ',train_ks)

y_pred = lr_model.predict_proba(evl_x)[:,1]
fpr_lr,tpr_lr,_ = roc_curve(evl_y,y_pred)
evl_ks = abs(fpr_lr - tpr_lr).max()
print('evl_ks : ',evl_ks)

from matplotlib import pyplot as plt
plt.plot(fpr_lr_train,tpr_lr_train,label = 'train LR')
plt.plot(fpr_lr,tpr_lr,label = 'evl LR')
plt.plot([0,1],[0,1],'k--')
plt.xlabel('False positive rate')
plt.ylabel('True positive rate')
plt.title('ROC Curve')
plt.legend(loc = 'best')
plt.show()

三、测试SMOTE过采样框架

下面调用自定义的过采样函数:imbalanceData.将训练集调整为平衡数据集。

代码语言:javascript复制
df_aff_ovsp = imbalanceData(train=train,test=evl,mmin=0.3,mmax=0.7, flag='bad_ind',
                            lis=['index', 'uid', 'td_score', 'jxl_score', 'mj_score', 'rh_score',
                                 'zzc_score', 'zcx_score','obs_mth']).apply_smote()

    badpctn: 0.5 (函数内部打印结果)

    可以看到负样本占比为0.5,即正负样本比例调整为1:1.

    下面再使用之前的逻辑回归进行训练。

代码语言:javascript复制
lr_model = LogisticRegression(C=0.05,class_weight='balanced')
lr_model.fit(df_aff_ovsp[feature_lst],df_aff_ovsp['bad_ind'] )
    
y_pred = lr_model.predict_proba(df_aff_ovsp[feature_lst])[:,1]
fpr_lr_train,tpr_lr_train,_ = roc_curve(df_aff_ovsp['bad_ind'],y_pred)
train_ks = abs(fpr_lr_train - tpr_lr_train).max()
print('train_ks : ',train_ks)
    
y_pred = lr_model.predict_proba(evl_x)[:,1]
fpr_lr,tpr_lr,_ = roc_curve(evl_y,y_pred)
evl_ks = abs(fpr_lr - tpr_lr).max()
print('evl_ks : ',evl_ks)

from matplotlib import pyplot as plt
plt.plot(fpr_lr_train,tpr_lr_train,label = 'train LR')
plt.plot(fpr_lr,tpr_lr,label = 'evl LR')
plt.plot([0,1],[0,1],'k--')
plt.xlabel('False positive rate')
plt.ylabel('True positive rate')
plt.title('ROC Curve')
plt.legend(loc = 'best')
plt.show()

可以看到模型有显著提升,没有明显过拟合的迹象。

四、SMOTE过采样框架

下面来看一下SMOTE函数。

代码语言:python代码运行次数:0复制

五、总结

  1. 在进行SMOTE过采样之前,样本一定要清洗,去掉其中的异常值,避免插值的过程中生成大量噪音。
  2. 调整特征为单调趋势。同样是从插值操作本身出发得到的结论。不过本案例没有  体现,因为通常数据集本身做过WOE处理。
  3. 样本选择的时候由于本身不均衡,头和尾要使用不同的比例来定义错分的概念。
  4. 样本清洗也可以使用异常检测等方法,根本目的是去除离群值。
  5. imbalancedData函数内部调用的SMOTE算法参数可以进行微调。

0 人点赞