說到評分卡模組化工具,做過評分卡的應該都能想到謝博士的scorecardpy和專為工業界模型開發設計的Python工具包--Toad,兩者相比,scorecardpy更加輕量級,且依賴較少,可以滿足大多數場景下的評分卡建構。
為了使評分卡模組化流程更加便捷,該Python包針對模組化中各個關鍵步驟都提供了現成的函數,如下:
- 資料集劃分 (split_df)
- 變量篩選(iv, var_filter)
- 變量分箱(woebin, woebin_plot, woebin_adj, woebin_ply)
- 分數轉換(scorecard, scorecard_ply)
- 效果評估(perf_eva, perf_psi)
基于github首頁上提供的案例,對每一步操作進行詳細解讀:
資料準備
import scorecardpy as sc # 加載德國信用卡相關資料集 dat = sc.germancredit()
得到的資料集情況如下:
變量篩選
然後根據變量的缺失率、IV值、同值性等因素,對20個變量進行篩選,并對目标變量進行标記,該資料集中creditability為目标變量:
dt_s = sc.var_filter(dat, y="creditability")
通過 var_filter() 函數篩選後,資料集保留以下13個變量:
預設的參數配置為:iv_limit=0.02, missing_limit=0.95, identical_limit=0.95,即當某個變量的 IV 值小于0.02,或缺失率大于95%,或同值率(除空值外)大于95%,則剔除掉該變量。
此外,該方法還内置了除上述以外的其他參數:
def var_filter(dt, y, x=None, iv_limit=0.02, missing_limit=0.95, identical_limit=0.95, var_rm=None, var_kp=None, return_rm_reason=False, positive='bad|1')
其中各參數含義如下:
- varrm可設定強制保留的變量,預設為空;
- varkp可設定強制剔除的變量,預設為空;
- return_rm_reason可設定是否傳回剔除原因,預設為不傳回(False);
- positive可設定壞樣本對應的值,預設為“bad|1”。
資料集劃分
将資料集劃分成訓練集和測試集:
train, test = sc.split_df(dt_s, 'creditability').values()
split_df()函數包括以下參數:
def split_df(dt, y=None, ratio=0.7, seed=186)
預設的切分比例為7:3,也可自行修改參數ratio設定不同的切分比例。
變量分箱
可通過woebin()函數對全部變量進行自動分箱,并基于woe_bin的結果,使用woebin_plot對各變量分箱的count distribution和bad probability進行可視化,可觀察是否存在單調性:
bins = sc.woebin(dt_s, y="creditability") sc.woebin_plot(bins)
bins為字典形式,以變量名作為key,可獲得單個變量的分箱結果詳情:
woebin_plot()得到的可視化結果如下:
woebin()函數包括如下參數:
def woebin(dt, y, x=None, var_skip=None, breaks_list=None, special_values=None, stop_limit=0.1, count_distr_limit=0.05, bin_num_limit=8, # min_perc_fine_bin=0.02, min_perc_coarse_bin=0.05, max_num_bin=8, positive="bad|1", no_cores=None, print_step=0, method="tree", ignore_const_cols=True, ignore_datetime_cols=True, check_cate_num=True, replace_blank=True, save_breaks_list=None, **kwargs)
woebin()可針對數值型和類别型變量生成最優分箱結果,方法可選擇決策樹分箱、卡方分箱或自定義分箱。其他各參數的含義如下:
- var_skip: 設定需要跳過分箱操作的變量;
- breaks_list: 切分點清單,預設為空。如果非空,則按設定的切分點進行分箱處理。
- special_values: 設定需要單獨分箱的值,預設為空。
- count_distr_limit: 設定分箱占比的最小值,一般可接受範圍為0.01-0.2,預設值為0.05;
- stop_limit: 當IV值的增長率小于所設定的stop_limit,或卡方值小于qchisq(1-stoplimit, 1)時,停止分箱。一般可接受範圍為0-0.5,預設值為0.1;
- bin_num_limit: 該參數為整數,代表最大分箱數。
- positive: 指定樣本中正樣本對應的标簽,預設為"bad|1";
- no_cores: 設定用于并行計算的 CPU 數目;
- print_step: 該參數為非負數,預設值為1。若print_step>0,每次疊代會輸出變量名。若iteration=0或no_cores>1,不會輸出任何資訊;
- method: 設定分箱方法,可設定"tree"(決策樹)或"chimerge"(卡方),預設值為"tree";
- ignore_const_cols: 是否忽略常數列,預設值為True,即忽略常數列;
- ignore_datetime_cols: 是否忽略日期列,預設值為True,即忽略日期列;
- check_cate_num: 檢查類别變量中枚舉值數目是否大于50,預設值為True,即自動進行檢查。若枚舉值過多,會影響分箱過程的速度;
- replace_blank: 設定是否将空值填為None,預設為True。
若對自動分箱結果不滿意,還可手動自定義分箱:
breaks_adj = { 'age.in.years': [26, 35, 40], 'other.debtors.or.guarantors': ["none", "co-applicant%,%guarantor"] } bins_adj = sc.woebin(dt_s, y="creditability", breaks_list=breaks_adj)
于是年齡變量的分箱結果變成:
分箱完成後,使用woebin_ply()函數對變量進行woe變換,之後需要把所得到的woe值作為模型的輸入:
train_woe = sc.woebin_ply(train, bins_adj) test_woe = sc.woebin_ply(test, bins_adj)
模型訓練
y_train = train_woe.loc[:,'creditability'] X_train = train_woe.loc[:,train_woe.columns != 'creditability'] y_test = test_woe.loc[:,'creditability'] X_test = test_woe.loc[:,train_woe.columns != 'creditability'] # 邏輯回歸 ------ from sklearn.linear_model import LogisticRegression lr = LogisticRegression(penalty='l1', C=0.9, solver='saga', n_jobs=-1) lr.fit(X_train, y_train) lr.coef_ lr.intercept_ # 預測 train_pred = lr.predict_proba(X_train)[:,1] test_pred = lr.predict_proba(X_test)[:,1]
效果評估
可使用perf_eva()函數對模型效果進行計算及可視化,基于預測的機率值和label值,提供KS(kolmogorov-smirnow), ROC, lift以及precision-recall四種評估名額:
train_perf = sc.perf_eva(y_train, train_pred, title = "train") test_perf = sc.perf_eva(y_test, test_pred, title = "test")
該函數還包括以下參數:
def perf_eva(label, pred, title=None, groupnum=None, plot_type=["ks", "roc"], show_plot=True, positive="bad|1", seed=186)
參數plot_type可設定為:"ks", "lift", "roc", "pr",預設為["ks", "roc"]。
分數轉換
然後基于’woebin'的結果和sklearn.linear_model的LogisticRegression,建立scorecard()函數,用于建構評分卡,隻需一行代碼:
card = sc.scorecard(bins_adj, lr, X_train.columns)
生成的結果為各變量名及其分箱、對應得分組成的字典,例如:
scorecard()包括以下參數:
def scorecard(bins, model, xcolumns, points0=600, odds0=1/19, pdo=50, basepoints_eq0=False, digits=0)
各參數含義如下:
- bins:由`woebin`得到的分箱資訊;
- model:LogisticRegression模型對象;
- points0:基準分數,預設值為600;
- odds0: 基準 Odds(好壞比),與真實違約機率對應,可換算得到違約機率,Odds = p/(1-p)。預設值為 1/19;
- pdo: Points toDouble theOdds,即Odds變成2倍時,所增加的信用分。預設值為50。
然後基于`scorecard`的結果,用scorecard_ply()函數計算train和test資料集的信用分數:
train_score = sc.scorecard_ply(train, card, print_step=0) test_score = sc.scorecard_ply(test, card, print_step=0)
直接生成各樣本的評分:
最後用perf_psi()得到該評分卡在測試資料集上的表現:
sc.perf_psi( score = {'train':train_score, 'test':test_score}, label = {'train':y_train, 'test':y_test} )
perf_psi()可計算群體穩定性名額(PSI),并提供信用分數的分布圖:
參考資料
scorecardpy github首頁:https://github.com/ShichenXie/scorecardpy
⬇️ 掃描下方二維碼關注公衆号【小資料研究院】 ⬇️
回複【算法】,擷取最全面的機器學習算法網絡圖: