대출 데이터의 클래스 불균형

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의 Gradient Boosted Trees는 로그 손실(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
  • 모델의 로그 손실 값은 두 경우 모두 같지만, 실제 손실은 다릅니다
Python을 활용한 신용 위험 모델링

불균형의 원인

  • 데이터 문제
    • 신용 데이터가 올바르게 샘플링되지 않음
    • 데이터 저장 문제
  • 비즈니스 프로세스:
    • 연체 가능성이 높은 경우 승인하지 않는 조치가 이미 마련되어 있음
    • 연체 가능성이 높은 대출은 빠르게 다른 회사에 매각됨
  • 행동적 요인:
    • 일반적으로 사람들은 대출을 연체하지 않음
      • 연체가 적을수록 신용 등급이 높아짐
Python을 활용한 신용 위험 모델링

클래스 불균형 다루기

  • 데이터의 클래스 불균형을 다루는 여러 방법이 있습니다
Method Pros Cons
Gather more data Increases number of defaults Percentage of defaults may not change
Penalize models Increases recall for defaults Model requires more tuning and maintenance
Sample data differently Least technical adjustment Fewer defaults in data
Python을 활용한 신용 위험 모델링

언더샘플링 전략

  • 미연체 데이터의 더 작은 무작위 샘플을 연체 데이터와 결합합니다

언더샘플링 전략 다이어그램

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...