文章首发于公众号”大数据风控与机器学习“
一、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复制
五、总结
- 在进行SMOTE过采样之前,样本一定要清洗,去掉其中的异常值,避免插值的过程中生成大量噪音。
- 调整特征为单调趋势。同样是从插值操作本身出发得到的结论。不过本案例没有 体现,因为通常数据集本身做过WOE处理。
- 样本选择的时候由于本身不均衡,头和尾要使用不同的比例来定义错分的概念。
- 样本清洗也可以使用异常检测等方法,根本目的是去除离群值。
- imbalancedData函数内部调用的SMOTE算法参数可以进行微调。