標準化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函數。
五、總結
- 在進行SMOTE過取樣之前,樣本一定要清洗,去掉其中的異常值,避免插值的過程中生成大量噪音。
- 調整特徵為單調趨勢。同樣是從插值操作本身出發得到的結論。不過本案例沒有 體現,因為通常數據集本身做過WOE處理。
- 樣本選擇的時候由於本身不均衡,頭和尾要使用不同的比例來定義錯分的概念。
- 樣本清洗也可以使用異常檢測等方法,根本目的是去除離群值。
- imbalancedData函數內部調用的SMOTE演算法參數可以進行微調。