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

  • 2019 年 10 月 7 日
  • 笔记

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

一、SMOTE

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

二、基础模型案例

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

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']

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

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.将训练集调整为平衡数据集。

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.

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

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函数。

  

五、总结

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