貸款資料的類別不平衡

以 Python 進行信用風險建模

Michael Crabtree

Data Scientist, Ford Motor Company

資料中的違約樣本過少

  • loan_status 的值代表類別:
    • 非違約:0
    • 違約:1
y_train['loan_status'].value_counts()
loan_status Training Data Count Percentage of Total
0 13,798 78%
1 3,877 22%
以 Python 進行信用風險建模

模型的損失函式

  • xgboost 的梯度提升樹使用對數損失(log-loss)作為損失函式。
    • 目標是最小化此數值。

Formula for log loss

True loan status Predicted probability Log Loss
1 0.1 2.3
0 0.9 2.3
  • 錯判違約的財務影響更大
以 Python 進行信用風險建模

不平衡的成本

  • 偽陰性(將違約預測成非違約)成本高得多。
Person Loan Amount Potential Profit Predicted Status Actual Status Losses
A $1,000 $10 Default Non-Default -$10
B $1,000 $10 Non-Default Default -$1,000
  • 兩者的 log-loss 相同,但實際損失不同。
以 Python 進行信用風險建模

不平衡的成因

  • 資料問題:
    • 信用資料抽樣不當
    • 資料儲存出錯
  • 商業流程:
    • 已有機制避免核准高違約風險
    • 高違約風險案件會迅速轉售他社
  • 行為因素:
    • 多數人不會違約
      • 違約越少,信用評等越高
以 Python 進行信用風險建模

處理類別不平衡

  • 處理類別不平衡的方法:
Method Pros Cons
Gather more data 增加違約樣本數 違約比例可能不變
Penalize models 提高違約的召回率 需要更多調參與維護
Sample data differently 技術調整最少 資料中的違約更少
以 Python 進行信用風險建模

欠抽樣策略

  • 將較小的非違約隨機樣本與違約樣本合併。

Diagram of undersampling strategy

以 Python 進行信用風險建模

合併切分後的資料集

  • 需先把測試集與訓練集合回。
  • 依實際 loan_status 建立兩個新集合。
# Concat the training sets
X_y_train = pd.concat([X_train.reset_index(drop = True),
                       y_train.reset_index(drop = True)], axis = 1)
# Get the counts of defaults and non-defaults
count_nondefault, count_default = X_y_train['loan_status'].value_counts()
# Separate nondefaults and defaults
nondefaults = X_y_train[X_y_train['loan_status'] == 0]
defaults = X_y_train[X_y_train['loan_status'] == 1]
以 Python 進行信用風險建模

對非違約進行欠抽樣

  • 隨機抽樣非違約資料集。
  • 與違約資料集合併。
# Undersample the non-defaults using sample() in pandas
nondefaults_under = nondefaults.sample(count_default)
# Concat the undersampled non-defaults with the defaults
X_y_train_under = pd.concat([nondefaults_under.reset_index(drop = True),
                             defaults.reset_index(drop = True)], axis=0)
以 Python 進行信用風險建模

一起來練習吧!

以 Python 進行信用風險建模

Preparing Video For Download...