金融风控实战——不均衡学习
上采樣/下采樣
下采樣,對(duì)于一個(gè)不均衡的數(shù)據(jù),讓目標(biāo)值(如0和1分類)中的樣本數(shù)據(jù)量相同,且以數(shù)據(jù)量少的一方的樣本數(shù)量為準(zhǔn)。上采樣就是以數(shù)據(jù)量多的一方的樣本數(shù)量為標(biāo)準(zhǔn),把樣本數(shù)量較少的類的樣本數(shù)量生成和樣本數(shù)量多的一方相同,稱為上采樣。
下采樣
獲取數(shù)據(jù)時(shí)一般是從分類樣本多的數(shù)據(jù)從隨機(jī)抽取等數(shù)量的樣本。
數(shù)據(jù)不平衡
在很多真實(shí)場(chǎng)景下,數(shù)據(jù)集往往是不平衡的。也就是說,在數(shù)據(jù)集中,有一類含有的數(shù)據(jù)要遠(yuǎn)遠(yuǎn)多于其他類的數(shù)據(jù)(類別分布不平衡)。在貸款場(chǎng)景下,我們主要介紹二分類中的類別不平衡問題。
常識(shí)告訴我們一家信用正常客戶的數(shù)據(jù)要遠(yuǎn)遠(yuǎn)多于欺詐客戶的。
考慮一個(gè)簡(jiǎn)單的例子,10萬正樣本(正常客戶標(biāo)簽為0)與1000個(gè)負(fù)樣本(欺詐客戶標(biāo)簽為1),正負(fù)樣本比列為100:1,如果直接帶入模型中去學(xué)習(xí),每一次梯度下降如果使用全量樣本,負(fù)樣本的權(quán)重只有不到1/100,即使完全不學(xué)習(xí)負(fù)樣本的信息,準(zhǔn)確率也有超過99%,所以顯然我們絕不能以準(zhǔn)確率來衡量模型的效果。但是實(shí)踐下面,我們其實(shí)也知道,即使用KS或者AUC來度量模型的表現(xiàn),依然沒法保證模型能將負(fù)樣本很好的學(xué)習(xí)。而我們實(shí)際上需要得到一個(gè)分類器,既能對(duì)于正例有很高的準(zhǔn)確率,同時(shí)又不會(huì)影響到負(fù)例的準(zhǔn)確率。
類似于上面例子中的數(shù)據(jù)集,由于整個(gè)數(shù)據(jù)空間中,正例和負(fù)例的數(shù)據(jù)就是不平衡的。因此,這樣的不平衡數(shù)據(jù)集的產(chǎn)生往往是內(nèi)在的。同時(shí),也有很多其他的因素會(huì)造成數(shù)據(jù)的不平衡,例如,時(shí)間,存儲(chǔ)等。由于這些原因產(chǎn)生不平衡的數(shù)據(jù)集往往被稱為外在的。除了數(shù)據(jù)集的內(nèi)在和外在,我們可能還要注意到數(shù)據(jù)集的相對(duì)不平衡以及絕對(duì)不平衡。假設(shè)上述例子中的數(shù)據(jù)集有100000條數(shù)據(jù),負(fù)例和正例的比例為100:1,只包含1000個(gè)正例。明顯的,我們不能說1000個(gè)數(shù)據(jù)就是絕對(duì)小的,只不過相對(duì)于負(fù)例來說,它的數(shù)量相對(duì)較少。因此,這樣的數(shù)據(jù)集被認(rèn)為是相對(duì)不平衡的。
解決方法
- 下探
- 半監(jiān)督學(xué)習(xí)
- 標(biāo)簽分裂
- 代價(jià)敏感
- 采樣算法
下探
最直接解決風(fēng)控場(chǎng)景樣本不均衡的方法。
所謂下探,就是對(duì)評(píng)分較低被拒絕的人進(jìn)行放款,犧牲一部分收益,來積累壞樣本,供后續(xù)模型學(xué)習(xí)。
這也是所有方法中最直接有效的。但是不是每一家公司都愿意承擔(dān)這部分壞賬。
此外我們之前提到過,隨著業(yè)務(wù)開展,后續(xù)模型迭代的時(shí)候,使用的樣本是有偏的,下探同樣可以解決這個(gè)問題。
半監(jiān)督學(xué)習(xí)
將被模型拒絕客戶的數(shù)據(jù)通過半監(jiān)督的方法逐漸生成標(biāo)簽,然后帶入模型中進(jìn)行訓(xùn)練。比較典型分方法有拒絕演繹、暴力半監(jiān)督等等。
1)拒絕演繹
拒絕演繹或者叫拒絕推斷,是一種根據(jù)經(jīng)驗(yàn)對(duì)低分客戶進(jìn)行百分比采樣的方法。
比如最低分的客群百分之五十視為壞人,其次百分之四十等等。
效果沒有下探好。但不用額外有任何開銷。
參考資料:群內(nèi)預(yù)習(xí)資料中的《信用風(fēng)險(xiǎn)評(píng)分卡研究》第十三章。
2)暴力半監(jiān)督
比較粗暴的做法是將樣本的每一種標(biāo)簽方式進(jìn)行窮舉,帶入模型看對(duì)模型是否有幫助,效率較低,容易過擬合。
3)模型篩選
用訓(xùn)練過的其他模型對(duì)無標(biāo)簽樣本打標(biāo)簽,然后模型進(jìn)行訓(xùn)練。很多公司會(huì)用當(dāng)前模型在上面做預(yù)測(cè),然后帶入模型繼續(xù)訓(xùn)練。很不推薦這樣做,效果一般是很差的。可以考慮無監(jiān)督算法或者用很舊的樣本做訓(xùn)練然后做預(yù)測(cè)。
等等…
標(biāo)簽分裂
我們有時(shí)候會(huì)不止使用傳統(tǒng)的逾期或者rollrate來定義好壞。而是通過一些聚類手段對(duì)數(shù)據(jù)進(jìn)行切分,然后分別在自己的樣本空間內(nèi)單獨(dú)學(xué)習(xí)。基于模型的比如kmeans,分層聚類等等。基于經(jīng)驗(yàn)的比如將失聯(lián)客戶、欺詐客戶拆開,單獨(dú)建模。
為什么要這樣做呢?我們看一個(gè)例子。
小明生了慢粒白血病,她的失散多年的哥哥找到有2家比較好的醫(yī)院,醫(yī)院A和醫(yī)院B供小明選擇就醫(yī)。
小明的哥哥多方打聽,搜集了這兩家醫(yī)院的統(tǒng)計(jì)數(shù)據(jù),它們是這樣的:
醫(yī)院A最近接收的1000個(gè)病人里,有900個(gè)活著,100個(gè)死了。
醫(yī)院B最近接收的1000個(gè)病人里,有800個(gè)活著,200個(gè)死了。
作為對(duì)統(tǒng)計(jì)學(xué)懵懵懂懂的普通人來說,看起來最明智的選擇應(yīng)該是醫(yī)院A對(duì)吧,病人存活率很高有90%啊!總不可能選醫(yī)院B吧,存活率只有80%啊。
呵呵,如果小明的選擇是醫(yī)院A,那么她就中計(jì)了。
就這么說吧,如果醫(yī)院A最近接收的1000個(gè)病人里,有100個(gè)病人病情很嚴(yán)重,900個(gè)病人病情并不嚴(yán)重。
在這100個(gè)病情嚴(yán)重的病人里,有30個(gè)活下來了,其他70人死了。所以病重的病人在醫(yī)院A的存活率是30%。
而在病情不嚴(yán)重的900個(gè)病人里,870個(gè)活著,30個(gè)人死了。所以病情不嚴(yán)重的病人在醫(yī)院A的存活率是96.7%。
在醫(yī)院B最近接收的1000個(gè)病人里,有400個(gè)病情很嚴(yán)重,其中210個(gè)人存活,因此病重的病人在醫(yī)院B的存活率是52.5%。
有600個(gè)病人病情不嚴(yán)重,590個(gè)人存活,所以病情不嚴(yán)重的病人在醫(yī)院B的存活率是98.3%。
畫成表格,就是這樣的——
你可以看到,在區(qū)分了病情嚴(yán)重和不嚴(yán)重的病人后,不管怎么看,最好的選擇都是醫(yī)院B。但是只看整體的存活率,醫(yī)院A反而是更好的選擇了。所謂遠(yuǎn)看是汪峰,近看白巖松,就是這個(gè)道理。
實(shí)際上,我們剛剛看到的例子,就是統(tǒng)計(jì)學(xué)中著名的黑魔法之一——辛普森悖論(Simpson’s paradox)。辛普森悖論就是當(dāng)你把數(shù)據(jù)拆開細(xì)看的時(shí)候,細(xì)節(jié)和整體趨勢(shì)完全不同的現(xiàn)象。
代價(jià)敏感學(xué)習(xí)
類似class_weight
代價(jià)敏感學(xué)習(xí)則是利用不同類別的樣本被誤分類而產(chǎn)生不同的代價(jià),使用這種方法解決數(shù)據(jù)不平衡問題。而且有很多研究表明,代價(jià)敏感學(xué)習(xí)和樣本不平衡問題有很強(qiáng)的聯(lián)系,并且使用代價(jià)敏感學(xué)習(xí)的方法解決不平衡學(xué)習(xí)問題要優(yōu)于使用隨機(jī)采樣的方法。
采樣算法
今天我們涉及的主要是過采樣方法
- 樸素隨機(jī)過采樣
- SMOTE
- ADASYN
樸素隨機(jī)過采樣
復(fù)制少數(shù)樣本
from sklearn.datasets import make_classification from collections import Counter X, y = make_classification(n_samples=5000, n_features=2, n_informative=2,n_redundant=0, n_repeated=0, n_classes=2,n_clusters_per_class=1,weights=[0.01, 0.99],class_sep=0.8, random_state=0) Counter(y) #Counter({1: 4923, 0: 77})from imblearn.over_sampling import RandomOverSampler ros = RandomOverSampler(random_state=0) X_resampled, y_resampled = ros.fit_resample(X, y) sorted(Counter(y_resampled).items()) #[(0, 4923), (1, 4923)]SMOTE
SMOTE: 對(duì)于少數(shù)類樣本a, 隨機(jī)選擇一個(gè)最近鄰的樣本b, 然后從a與b的連線上隨機(jī)選取一個(gè)點(diǎn)c作為新的少數(shù)類樣本;
但是,SMOTE容易出現(xiàn)過泛化和高方差的問題,而且,容易制造出重疊的數(shù)據(jù)。
為了克服SMOTE的缺點(diǎn),Adaptive Synthetic Sampling方法被提出,主要包括:Borderline-SMOTE和Adaptive Synthetic Sampling(ADA-SYN)算法。
Borderline-SMOTE:對(duì)靠近邊界的minority樣本創(chuàng)造新數(shù)據(jù)。其與SMOTE的不同是:SMOTE是對(duì)每一個(gè)minority樣本產(chǎn)生綜合新樣本,而Borderline-SMOTE僅對(duì)靠近邊界的minority樣本創(chuàng)造新數(shù)據(jù)。如下圖,只對(duì)A中的部分?jǐn)?shù)據(jù)進(jìn)行操作:
這個(gè)圖中展示了該方法的實(shí)現(xiàn)過程,我們可以發(fā)現(xiàn)和SMOTE方法的不同之處:
SMOTE對(duì)于每一個(gè)少數(shù)類樣本都會(huì)產(chǎn)生合成樣本,但是Borderline-SMOTE只會(huì)對(duì)鄰近邊界的少數(shù)類樣本生成合成數(shù)據(jù)。
Borderline SMOTE-2和Borderline SMOTE-1是很相似的,區(qū)別是在獲得DANGER集合以后,對(duì)于DANGER中的每個(gè)樣本點(diǎn)xi:
- Borderline SMOTE-1:從少數(shù)類樣本集合P中獲得k個(gè)最近鄰樣本,再隨機(jī)選擇樣本點(diǎn)和xi做隨機(jī)的線性插值產(chǎn)生新的少數(shù)類樣本。(和普通SMOTE算法流程相同)
- Borderline SMOTE-2:從少數(shù)類樣本集合P和多數(shù)類樣本集合N中分別獲得k個(gè)最近鄰樣本Pk和Nk。設(shè)定一個(gè)比例α,在Pk中選出α比例的樣本點(diǎn)和xi做隨機(jī)的線性插值產(chǎn)生新的少數(shù)類樣本,方法同Borderline SMOTE-1;在Nk中選出1?α比例的樣本點(diǎn)和xi做隨機(jī)的線性插值產(chǎn)生新的少數(shù)類樣本,此處的隨機(jī)數(shù)范圍選擇的是(0,0.5),即便得產(chǎn)生的新的樣本點(diǎn)更靠近少數(shù)類樣本。
ADA-SYN:根據(jù)majority和minority的密度分布,動(dòng)態(tài)改變權(quán)重,決定要generate多少minority的新數(shù)據(jù)。
k近鄰中,多數(shù)類樣本多,該少數(shù)類樣本合成數(shù)據(jù)多
基于聚類的隨機(jī)采樣(CBO)
基于聚類的隨機(jī)采樣方法可以用來解決類內(nèi)不平衡問題,主要利用的聚類的方法。具體的過程如下:
隨機(jī)選擇K個(gè)樣本作為K個(gè)簇,并且計(jì)算K類樣本在特征空間的平均值,作為聚類中心;
對(duì)于剩下的每一個(gè)樣本,計(jì)算它和K個(gè)聚類中心的歐氏距離,根據(jù)歐式聚類將其分配到最近的類簇中;
更新每個(gè)簇的聚類中心,直到所有的樣本都用完;
采樣方法和集成方法的集成
目前已經(jīng)有很多的方法把隨機(jī)采樣和集成學(xué)習(xí)的方法集成在一起,下面介紹兩種這樣的方法:
- SMOTEBoost
- DataBoost-IM
SMOTEBoost
SMOTEBoost主要是把SMOTE和AdaBoost.M2集成在一起,SMOTEBoost方法在每次Boost迭代過程中使用合成數(shù)據(jù)的方法。因此,每一次迭代過程中的分類器都會(huì)集中到更多的少數(shù)類樣本。
DataBoost-IM
DataBoost-IM主要是把數(shù)據(jù)生成技術(shù)和AdaBoost.M1方法結(jié)合在一起,主要根據(jù)不同類之間樣本的很難被學(xué)習(xí)到的比例。具體過程主要是如下:
相對(duì)于基本的SMOTE算法, 關(guān)注的是所有的少數(shù)類樣本, 這些情況可能會(huì)導(dǎo)致產(chǎn)生次優(yōu)的決策函數(shù)。
因此SMOTE就產(chǎn)生了一些變體,這些方法關(guān)注在最優(yōu)化決策函數(shù)邊界的一些少數(shù)類樣本, 然后在最近鄰類的相反方向生成樣本。
SMOTE函數(shù)中的kind參數(shù)控制了選擇哪種變體
- regular
- borderline1
- borderline2
- svm
接下來我們啟用上一節(jié)課的例子
import glob import numpy as np import pandas as pd import lightgbm as lgb from sklearn.metrics import roc_auc_score,roc_curve,auc from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from sklearn.model_selection import GridSearchCV as gscv from sklearn.neighbors import KNeighborsClassifier data = pd.read_csv('Acard.txt') data.head() data.obs_mth.unique() #array(['2018-10-31', '2018-07-31', '2018-09-30', '2018-06-30', # '2018-11-30'], dtype=object) train = data[data.obs_mth != '2018-11-30'].reset_index().copy() evl = data[data.obs_mth == '2018-11-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']lr_model = LogisticRegression(C=0.1) 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() #train_ks : 0.41573985983413414 #evl_ks : 0.3928959732014397 lr_model = LogisticRegression(C=0.1,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() #train_ks : 0.4482453222991063 #evl_ks : 0.4198642457760936
接下來先用lgb做預(yù)測(cè),然后做前融合。
相比于不修改損失函數(shù)的xgb,lgb的優(yōu)勢(shì)只是比較快。
這里的思想類似于對(duì)訓(xùn)練樣本做異常點(diǎn)檢測(cè),
只不過不是根據(jù)數(shù)據(jù)內(nèi)部分布差異,而是使用精準(zhǔn)度更高的集成模型,
將難以辨認(rèn)的樣本,視為噪音。
可以理解為大神都做不對(duì)的題目,就別給普通學(xué)員學(xué)了,可能會(huì)適得其反。
首先做網(wǎng)格調(diào)參,給lgb找一組較好的參數(shù)
train_x,test_x,train_y,test_y = train_test_split(x,y,random_state=0,test_size=0.4)params = {'boosting_type':'gbdt','objective':'binary','metric':'auc','nthread':4,'learning_rate':0.1,'num_leaves':30,'max_depth':5,'subsample':0.8,'colsample_bytree':0.8,"verbose":-1}data_train = lgb.Dataset(train_x,train_y)cv_results = lgb.cv(params,data_train,num_boost_round = 1000,nfold = 5,stratified = False,shuffle = True,metrics = 'auc',early_stopping_rounds = 100,seed = 0) print('best n_estimators:',len(cv_results['auc-mean'])) print('best cv score:',pd.Series(cv_results['auc-mean']).max()) #best n_estimators: 24 #best cv score: 0.8097663177199287 def lgb_test(train_x,train_y,test_x,test_y):clf =lgb.LGBMClassifier(boosting_type = 'gbdt',objective = 'binary',metric = 'auc',learning_rate = 0.1,n_estimators = 24,max_depth = 4,num_leaves = 25,max_bin = 40,min_data_in_leaf = 5,bagging_fraction = 0.6,bagging_freq = 0,feature_fraction = 0.8,)clf.fit(train_x,train_y,eval_set = [(train_x,train_y),(test_x,test_y)],eval_metric = 'auc')return clf,clf.best_score_['valid_1']['auc'],lgb_model , lgb_auc = lgb_test(train_x,train_y,test_x,test_y) feature_importance = pd.DataFrame({'name':lgb_model.booster_.feature_name(),'importance':lgb_model.feature_importances_}).sort_values(by=['importance'],ascending=False)pred = lgb_model.predict_proba(train_x)[:,1] fpr_lgb,tpr_lgb,_ = roc_curve(train_y,pred) print(abs(fpr_lgb - tpr_lgb).max())pred = lgb_model.predict_proba(test_x)[:,1] fpr_lgb,tpr_lgb,_ = roc_curve(test_y,pred) print(abs(fpr_lgb - tpr_lgb).max())pred = lgb_model.predict_proba(evl_x)[:,1] fpr_lgb,tpr_lgb,_ = roc_curve(evl_y,pred) print(abs(fpr_lgb - tpr_lgb).max()) #[1] training's auc: 0.764327 valid_1's auc: 0.74748 #[2] training's auc: 0.81104 valid_1's auc: 0.795364 #[3] training's auc: 0.815393 valid_1's auc: 0.801769 #[4] training's auc: 0.819752 valid_1's auc: 0.804643 #[5] training's auc: 0.819358 valid_1's auc: 0.805129 #[6] training's auc: 0.821207 valid_1's auc: 0.805297 #[7] training's auc: 0.821572 valid_1's auc: 0.804743 #[8] training's auc: 0.822117 valid_1's auc: 0.80607 #[9] training's auc: 0.822494 valid_1's auc: 0.806053 #[10] training's auc: 0.821979 valid_1's auc: 0.805704 #[11] training's auc: 0.821362 valid_1's auc: 0.805741 #[12] training's auc: 0.822991 valid_1's auc: 0.806829 #[13] training's auc: 0.824437 valid_1's auc: 0.807311 #[14] training's auc: 0.82526 valid_1's auc: 0.807217 #[15] training's auc: 0.826336 valid_1's auc: 0.807852 #[16] training's auc: 0.826902 valid_1's auc: 0.807857 #[17] training's auc: 0.827597 valid_1's auc: 0.80819 #[18] training's auc: 0.827992 valid_1's auc: 0.808283 #[19] training's auc: 0.828076 valid_1's auc: 0.80852 #[20] training's auc: 0.828594 valid_1's auc: 0.808893 #[21] training's auc: 0.82915 valid_1's auc: 0.808473 #[22] training's auc: 0.829211 valid_1's auc: 0.808736 #[23] training's auc: 0.829284 valid_1's auc: 0.808657 #[24] training's auc: 0.829692 valid_1's auc: 0.808827 #0.5064991567297175 #0.48909811193341235 #0.41935471928695134粗略調(diào)參的lgb比lr無顯著提升,下面進(jìn)行權(quán)重調(diào)整。
前后各取部分錯(cuò)分樣本,減小權(quán)重,其余樣本為1。
雖然后面還會(huì)給予新的權(quán)重,但是這部分權(quán)重永遠(yuǎn)只有正常樣本的固定比例。
此時(shí)的lr,相比于最開始的lr,提升了1個(gè)百分點(diǎn)。
這里省略了一些其他的探索,由于其他算法實(shí)驗(yàn)效果不理想,最終選取lgb作為篩選樣本的工具。
接下來考慮基于差值思想的過采樣方法,增加一部分虛擬的負(fù)樣本。
這里需要注意,之前權(quán)重減小的樣本是不應(yīng)該用來做過采樣的。 (權(quán)重小可能是噪聲)
所以將訓(xùn)練數(shù)據(jù)先拆分成兩部分。weight=1的做過采樣,其余的不變。
下面做基于borderline1的smote算法做過采樣
def lr_predict(train_x,train_y,evl_x,evl_y):lr_model = LogisticRegression(C=0.1,class_weight='balanced')lr_model.fit(train_x,train_y)y_pred = lr_model.predict_proba(train_x)[:,1]fpr_lr,tpr_lr,_ = roc_curve(train_y,y_pred)train_ks = abs(fpr_lr - tpr_lr).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)return train_ks,evl_ksfrom imblearn.over_sampling import BorderlineSMOTE,RandomOverSampler,ADASYN smote = BorderlineSMOTE(k_neighbors=15, kind='borderline-1', m_neighbors=4, n_jobs=1,random_state=0) rex,rey = smote.fit_resample(train_x_osvp,train_y_osvp) print('badpctn:',rey.sum()/len(rey)) df_rex = pd.DataFrame(rex) df_rex.columns =feature_lst df_rex['weight'] = 1 df_rex['bad_ind'] = rey df_aff_ovsp = df_rex.append(osnu_sample) lr_predict(df_aff_ovsp[feature_lst],df_aff_ovsp['bad_ind'],evl_x,evl_y) #badpctn: 0.5 #train_ks : 0.4828705350911966 #evl_ks : 0.439243398952811 #(0.4828705350911966, 0.439243398952811) lr_model = LogisticRegression(C=0.1,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() #train_ks : 0.4859866821876423 #evl_ks : 0.44085108654818894
可以看到,最終跨時(shí)間驗(yàn)證集上,是有3.5個(gè)百分點(diǎn)的提升的。而訓(xùn)練集上提升了5個(gè)百分點(diǎn),較為符合預(yù)期,過擬合的風(fēng)險(xiǎn)不是很大。
請(qǐng)同學(xué)們自行嘗試其他算法進(jìn)行樣本篩選和其他采樣方法。
總結(jié)
以上是生活随笔為你收集整理的金融风控实战——不均衡学习的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 金融风控实战——集成学习
- 下一篇: 金融风控实战——模型融合