催收评分卡实战
? 催收評(píng)分卡分為滾動(dòng)率模型、還款率模型和失聯(lián)模型,市面上介紹C卡的模型較少,本人將收集到的貸后催收評(píng)分卡的視頻教程整理列舉如下:
https://www.bilibili.com/video/BV1pJ411y7yA?p=7
https://www.bilibili.com/video/BV1ZE411V7Mk/
觀察期和表現(xiàn)期
? 本次催收評(píng)分卡是M1滾動(dòng)率模型,即預(yù)測(cè)當(dāng)前處于M1狀態(tài)的用戶在本周期內(nèi)回收(出催)的概率。
? 貸后催收評(píng)分卡需要不斷積累建模樣本,所以前期通常會(huì)制定一些貸后緩催策略,后期積累了一定樣本之后再用評(píng)分卡來(lái)實(shí)現(xiàn)更精細(xì)化的切分。關(guān)于催收評(píng)分卡的觀察期和表現(xiàn)期,大致有以下3種做法(假定觀察期為6個(gè)月,表現(xiàn)期為2個(gè)月):
第一種:鎖定觀察期
? 觀察期為放款之后的前6個(gè)月,表現(xiàn)期為第7、8個(gè)月,也就是將mob賬齡鎖定。這種方法的觀察點(diǎn)為第六期期末的時(shí)間,會(huì)因?yàn)榉趴钤碌牟煌诓粩嘁苿?dòng),但是觀察期+觀察點(diǎn)為賬齡的前6期。
一般C卡要包含完整的年度數(shù)據(jù),即觀察點(diǎn)至少需要包含3月、6月、9月、12月四個(gè)時(shí)間節(jié)點(diǎn),因此這種情況下至少要有18個(gè)月的樣本數(shù)據(jù)。
第二種:鎖定表現(xiàn)期
? 表現(xiàn)期鎖定為某兩個(gè)月,比如2020年3月和4月。建模樣本則為截止2020年3月賬齡大于6期的所有樣本。放款月越早,觀察點(diǎn)所處的mob就越大。觀察期可以取最近6期,也可以取2020年3月之前的所有賬期。
第三種:觀察期和表現(xiàn)期都在移動(dòng)
? 這種方法就是將每一個(gè)訂單6期之后的數(shù)據(jù)按賬單日拆分成多條,比如一個(gè)用戶的還款表現(xiàn)為"FFFFFF1212",那么入模的樣本就會(huì)有"FFFFFF12"和"FFFFFF1212"兩條。前面一條的觀察期為前6期,表現(xiàn)期為第7、8期;后一條觀察期為前8期,表現(xiàn)期為第9、10期,以此類(lèi)推。這種方法可以擴(kuò)充建模樣本數(shù)量,但是X變量的衍生會(huì)比較復(fù)雜。
本文將采用第三種方法進(jìn)行評(píng)分卡制作,第三種方法的難點(diǎn)在于X變量的衍生。
數(shù)據(jù)集劃分
? 數(shù)據(jù)集劃分為訓(xùn)練集、測(cè)試集、跨時(shí)間驗(yàn)證集(5:3:2)。訓(xùn)練集進(jìn)行模型訓(xùn)練,如果需要進(jìn)行調(diào)參的話還需要對(duì)訓(xùn)練集進(jìn)行切分,劃分成訓(xùn)練集和驗(yàn)證集。測(cè)試集用于查看模型的泛化能力。跨時(shí)間驗(yàn)證集則是監(jiān)控隨著時(shí)間變化對(duì)模型的預(yù)測(cè)效果產(chǎn)生的影響。
這里注意一點(diǎn),分箱的過(guò)程應(yīng)該是基于訓(xùn)練集進(jìn)行,然后將跨時(shí)間驗(yàn)證集的數(shù)據(jù)根據(jù)分箱結(jié)果進(jìn)行映射。之前為了省事直接在數(shù)據(jù)集上進(jìn)行分箱,然后再根據(jù)放款月份取訓(xùn)練集和跨時(shí)間驗(yàn)證集,這樣會(huì)造成模型過(guò)擬合。
變量選取
? 貸后催收評(píng)分卡常用到的變量有催收行為數(shù)據(jù)、逾期行為數(shù)據(jù)、歷史還款數(shù)據(jù)、客戶檔案數(shù)據(jù)以及第三方數(shù)據(jù)。
催收行為數(shù)據(jù):
歷史還款數(shù)據(jù):
客戶檔案數(shù)據(jù):
第三方數(shù)據(jù):
? 以上是番茄風(fēng)控老騎士的催收評(píng)分卡課程中用到的變量,僅供參考。
? 以下是結(jié)合公司實(shí)際數(shù)據(jù)情況,用到的評(píng)分卡變量,主要用到mob表和還款計(jì)劃表,基于這兩張表進(jìn)行變量的衍生。
? 特征衍生是催收評(píng)分卡制作過(guò)程中的重中之重了,一般會(huì)衍生很多時(shí)間切片變量,反映借款人最近一段時(shí)間內(nèi)的還款能力和意愿。相對(duì)于前兩種觀察期和表現(xiàn)期的取法,一種是固定賬齡mob,一種是固定表現(xiàn)月,這兩種方法取時(shí)間切片變量的時(shí)候都相對(duì)比較容易。如果是觀察期和表現(xiàn)期都不固定的這種,特征衍生的過(guò)程會(huì)復(fù)雜一點(diǎn)。
時(shí)間切片變量衍生
? 首先,會(huì)計(jì)算出截止每一期的賬單日的還款歷史狀態(tài)。大概情況如下:
? 對(duì)每一行的repayment_history取長(zhǎng)度等于mob的位數(shù)就可以得到當(dāng)期的還款歷史字段,然后就可以繼續(xù)衍生當(dāng)期而言的近3期、近6期的逾期行為變量。這里只能衍生逾期狀態(tài)的行為變量,如果需要衍生逾期天數(shù)的行為變量,需要根據(jù)還款計(jì)劃表進(jìn)行計(jì)算。
? 首先,根據(jù)還款計(jì)劃表計(jì)算每一期的逾期天數(shù),如果至今未還的話就用當(dāng)前時(shí)間代替。然后衍生一個(gè)類(lèi)似于還款歷史的字段,只不過(guò)是逾期天數(shù)組合成的字段。后面的操作就和逾期狀態(tài)的處理一樣了。
? 同理,還款金額的時(shí)間切片變量也可以這樣衍生。
# 生成逾期天數(shù)的List overdue_dict=(df_all.groupby('app_id')['overdue_days'].apply(lambda x:list(x))).to_dict() df_all['overdue_days_list']=df_all['app_id'].map(overdue_dict) # 生成實(shí)際還款金額的List pay_amt_dict=df_all.groupby('app_id')['all_pay_amt'].apply(lambda x:list(x)).to_dict() df_all['pay_amt_list']=df_all['app_id'].map(pay_amt_dict)變量穿越
? 變量穿越是指X變量的表現(xiàn)時(shí)間超過(guò)了Y變量,即出現(xiàn)用Y去預(yù)測(cè)Y的情況,這在貸后評(píng)分卡中是很容易犯的。這種變量一旦入模的后果就是變量的IV值極高(一般大于0.5就會(huì)有這種情況),而且模型的KS較高。
? 思考兩個(gè)變量,首次逾期天數(shù)、首逾3天發(fā)生期數(shù)這兩個(gè)變量是否可以入模?
首次逾期天數(shù):用戶發(fā)生首次逾期的天數(shù)。
? 比如一條樣本的還款歷史為FFFFFF12,Y變量為M1-M2,此時(shí)用戶的首逾天數(shù)一定會(huì)大于30天,就會(huì)出現(xiàn)用Y去預(yù)測(cè)Y的情況。因?yàn)槭子馓鞌?shù)大于30天,就意味著一定從M1遷徙到M2。
? 但是如果將這個(gè)首次逾期天數(shù)調(diào)整一下,如果該條記錄為用戶首次逾期,則這個(gè)變量為0。這樣就會(huì)避免變量穿越的問(wèn)題了。
首逾3天發(fā)生期數(shù):首次逾期3天以上發(fā)生的期數(shù)。
? 比如樣本的還款歷史為FFFFFF1112,首次逾期3天以上發(fā)生在第9期,即第三個(gè)1的地方。這條樣本會(huì)被拆成FFFFFF11和FFFFFF111和FFFFFF1112三條樣本。而對(duì)于FFFFFF11這個(gè)樣本,首逾3天以上發(fā)生在第9期,這個(gè)字段一共才取到第8期,所以會(huì)出現(xiàn)變量穿越。
變量分箱
變量有類(lèi)別型變量和數(shù)值型變量。
類(lèi)別型變量:
降基處理:將類(lèi)別占比小于某個(gè)閾值的類(lèi)別劃為一箱。
bad_rate編碼:將每一箱按照壞樣本比例映射成數(shù)值變量。但是變量會(huì)失去原有的解釋性。
數(shù)值型變量:
將數(shù)值型變量和bad_rate編碼轉(zhuǎn)換過(guò)來(lái)的變量進(jìn)行卡方分箱。
? 分箱之后需要看每個(gè)變量的單調(diào)性,一般要求每一箱之間的bad_rate單調(diào)。但是如果是年齡這種變量,可能無(wú)法保證完全單調(diào),只要業(yè)務(wù)上能解釋得通就可以。
? 左圖是近3期逾期次數(shù)的壞樣本率情況,可以發(fā)現(xiàn)近3期逾期次數(shù)越高,變壞的可能性越低。說(shuō)明這部分用戶是習(xí)慣性逾期,每次都會(huì)逾期但是經(jīng)過(guò)催收都會(huì)回正。
? 右圖是近6期M1-M0的次數(shù),99是將2、3降基處理之后的值,可以發(fā)現(xiàn)M1-M0回正次數(shù)越多,變壞的概率就會(huì)越低。
? 個(gè)人覺(jué)得評(píng)分卡的精髓在于如何分箱,因?yàn)榉窒浞椒ǖ牟煌瑫?huì)導(dǎo)致WOE、IV值的不同,進(jìn)而影響后續(xù)建模的一系列動(dòng)作。如何選擇合適的分箱方法和調(diào)整分箱,本人還需要更加深入地學(xué)習(xí)。
變量篩選
主要就是進(jìn)行IV值(>0.02)、相關(guān)性(<0.7)、回歸系數(shù)(為正)。代碼如下:
# 相關(guān)性剔除 def forward_delete_corr(df,col_list,threshold=None):"""df:數(shù)據(jù)集col_list:變量list集合threshold: 相關(guān)性設(shè)定的閾值return:相關(guān)性剔除后的變量"""list_corr = col_list[:]for col in list_corr:corr = df.loc[:,list_corr].corr()[col]corr_index= [x for x in corr.index if x!=col]# corr_values = [x for x in corr.values if x!=1]corr_values = list(corr[corr.index.isin(corr_index)])for i,j in zip(corr_index,corr_values):if abs(j)>=threshold:list_corr.remove(i)return list_corr? 注意,相關(guān)性剔除時(shí)col_list的變量要按照IV值從大到小的順序,這樣才能保證剔除的是IV值較小的那個(gè)變量。
# 邏輯回歸系數(shù)符號(hào)篩選,在篩選前需要做woe轉(zhuǎn)換 def forward_delete_coef(x_train,y_train):"""x_train -- x訓(xùn)練集y_train -- y訓(xùn)練集return :coef_col回歸系數(shù)符號(hào)篩選后的變量lr_coe:每個(gè)變量的系數(shù)值"""col_list = list(x_train.columns)coef_col = []for col in col_list:coef_col.append(col)x_train2 = x_train.loc[:,coef_col]sk_lr = LogisticRegression(C=0.1,class_weight='balanced').fit(x_train2,y_train)coef_df = pd.DataFrame({'col':coef_col,'coef':sk_lr.coef_[0]})if coef_df[coef_df.coef<0].shape[0]>0:coef_col.remove(col)# print(coef_col)x_new_train = x_train.loc[:,coef_col]lr = LogisticRegression(C=0.1,class_weight='balanced').fit(x_new_train,y_train)lr_coe = pd.DataFrame({'col':coef_col,'coef':lr.coef_[0]})return coef_col,lr_coe? 這個(gè)函數(shù)中邏輯回歸的系數(shù)需要和建模時(shí)候的系數(shù)一致,不然就會(huì)出現(xiàn)剔除完之后的變量建模之后,又出現(xiàn)系數(shù)為負(fù)的情況。系數(shù)為負(fù),說(shuō)明變量之間仍然存在多重共線性,而且會(huì)給單變量得分的解釋性造成困擾。關(guān)于多重共線性的影響列舉如下:
建模
? 說(shuō)一下邏輯回歸調(diào)參,一般評(píng)分卡建模中不調(diào)參也是可以的。
調(diào)參主要用到網(wǎng)格搜索算法,主要調(diào)整C和penalty兩個(gè)參數(shù)。
網(wǎng)格調(diào)參的代碼如下:
def pm_search(model,pm,scale,X,y):#調(diào)參函數(shù)param_test = {pm:scale}gsearch = GridSearchCV(LogisticRegression(class_weight='balanced',penalty='l1'), param_grid = param_test, scoring='roc_auc', cv=5 )gsearch.fit(X,y)score_gs=gsearch.grid_scores_#各項(xiàng)參數(shù)的aucscore_pm=[[pm,scale[loc],score_gs[loc][1]] for loc in range(len(score_gs))]print(score_pm)parameter=[str(value[1]) for value in score_pm]scores=[value[2] for value in score_pm]#AUC分?jǐn)?shù)繪圖sns.set(rc={"figure.figsize":(10,6)})sns.set(style='darkgrid',palette='muted',color_codes=True)plt.plot(parameter,scores,scaley =False)#最優(yōu)參數(shù)合并listbest_para=parameter[scores.index(max(scores))]return [pm,best_para]? 模型的KS曲線、ROC曲線等評(píng)估情況這里就不再詳述,有興趣的可以參看之前評(píng)分卡的系列文章。催收評(píng)分卡只是提升催收效率的第一步,對(duì)催收效果影響最大的因素還是催收人員本身。后續(xù)基于模型的分析和策略的制定才是更重要的。這里列出一些催收評(píng)分卡課程中提及到的策略:
【作者】:Labryant
【原創(chuàng)公眾號(hào)】:風(fēng)控獵人
【簡(jiǎn)介】:某創(chuàng)業(yè)公司策略分析師,積極上進(jìn),努力提升。乾坤未定,你我都是黑馬。
【轉(zhuǎn)載說(shuō)明】:轉(zhuǎn)載請(qǐng)說(shuō)明出處,謝謝合作!~
總結(jié)
- 上一篇: 常用机器学习算法原理及推导
- 下一篇: 迁移学习和冷启动