標準化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演算法參數可以進行微調。