93. 은행 가계 대출 심사 승인 여부 분석 실습

📥 실습 주피터 노트북(.ipynb) 다운로드

실전 데이터 분석 93: 대출 신청 가계의 월 소득 및 신용 등급 점수 대비 대출 희망금액별 승인 여부 분석

도입 만화

📊 실습 개요 (Tutorial Overview)

시중 금융 은행의 가계 대출 신청 기록 데이터셋입니다. 대출 신청자의 월 소득(ApplicantIncome), 신용 평가 점수(CreditHistoryScore), 희망 대출 청구액(LoanAmount)과 공동 보증인 유무가 최종 은행 여신 심사 승인 여부(Approved)에 미치는 정책 기여도를 규명하고 가시화합니다.


🛠️ 핵심 분석 실습 역량 (Core Skills)

  • 결측치 중앙값 대치 (`fillna`): 용도가 생략되어 결측된 대출 희망금액을 신청 전체의 중간값(Median) 대입으로 정제합니다.
  • 심사 승인 빈도 카운트 및 대출 소득 대비 심사 산점도 (`countplot`, `scatterplot`): 승인/거절 카운트 비교 및 소득 대비 대출액 위 심사 승인 장벽 맵을 시각화합니다.

🧐 실무 도메인 지식 가이드 (Domain Knowledge Guide)

💰 금융 및 핀테크 (Finance & FinTech) 금융 데이터 분석은 자산의 리스크 관리(Credit Risk), 투자 자산 평가, 이상 금융 거래 감지(FDS) 등을 해결하기 위한 통계적 검정 분야입니다.

  • 리스크와 대출 부도(Default): 대출 연체 여부나 투자 손실 위험은 금융 자산 건전성을 지키기 위해 고도화된 스코어링 모형으로 분석됩니다.
  • 소득 대비 부채 비율(DTI): 개인이 갚을 수 있는 능력 한도를 객관적으로 판단하는 지표로 금융 신용 여신 관리의 핵심 척도입니다.
  • 자산 변동성(Volatility): 주가나 크립토 시세의 표준편차는 위험 자산의 위험도를 계산(VaR)하고 투자 포트폴리오를 다변화하는 기준이 됩니다.

Step 1: 데이터 불러오기 및 기본 정보 확인 (Data Load)

Step 1 데이터 수집 개념도

제공된 CSV 파일을 분석 컴퓨터로 불러와 로드하고, 컬럼의 타입 및 데이터 구조를 확인합니다.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# 한글 폰트 설정
import koreanize_matplotlib
sns.set_theme(style="whitegrid")

# 데이터 로드
df = pd.read_csv('./bank_loan_approval.csv')
print(df.info())
print(df.head())

💻 [실행 결과]

<class 'pandas.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 6 columns):
 #   Column              Non-Null Count  Dtype  
---  ------              --------------  -----  
 0   ApplicantID         1000 non-null   int64  
 1   ApplicantIncome     1000 non-null   int64  
 2   LoanAmount          984 non-null    float64
 3   CreditHistoryScore  1000 non-null   int64  
 4   CoApplicant         1000 non-null   int64  
 5   Approved            1000 non-null   str    
dtypes: float64(1), int64(4), str(1)
memory usage: 49.2 KB
None
   ApplicantID  ApplicantIncome  ...  CoApplicant  Approved
0       930001             6177  ...            0        No
1       930002             4386  ...            0        No
2       930003             9698  ...            0        No
3       930004             6081  ...            0        No
4       930005            17705  ...            0        No

[5 rows x 6 columns]

RangeIndex: 1000 entries, 0 to 999 Data columns (total 6 columns): # Column Non-Null Count Dtype
— —— ————– —–
0 ApplicantID 1000 non-null int64
1 ApplicantIncome 1000 non-null int64
2 LoanAmount 984 non-null float64 3 CreditHistoryScore 1000 non-null int64
4 CoApplicant 1000 non-null int64
5 Approved 1000 non-null str
dtypes: float64(1), int64(4), str(1) memory usage: 47.0 KB

ApplicantID ApplicantIncome LoanAmount CreditHistoryScore CoApplicant Approved 0 930001 6177 18384.0 641 0 No 1 930002 4386 11846.0 425 0 No 2 930003 9698 29729.0 512 0 No 3 930004 6081 10386.0 435 0 No 4 930005 17705 18155.0 801 0 No ```


Step 2: 결측치 및 데이터 정제 (Data Cleaning)

Step 2 데이터 정제 개념도

수집 과정에서 빈칸으로 기록된 결측값(NaN)의 존재 여부를 진단하고, 데이터 도메인 성격에 부합하는 통계 수치 대입 기법으로 정제합니다.

# 1. 컬럼별 결측치 개수 확인
print("--- 정제 전 결측치 확인 ---")
print(df.isnull().sum())

# 2. 결측치 전처리 및 대치 수행
median_loan = df['LoanAmount'].median()
df['LoanAmount'] = df['LoanAmount'].fillna(median_loan)
print(df.isnull().sum())

💻 [실행 결과]

--- 정제 전 결측치 확인 ---
ApplicantID            0
ApplicantIncome        0
LoanAmount            16
CreditHistoryScore     0
CoApplicant            0
Approved               0
dtype: int64
ApplicantID           0
ApplicantIncome       0
LoanAmount            0
CreditHistoryScore    0
CoApplicant           0
Approved              0
dtype: int64

ApplicantIncome 0 LoanAmount 16 CreditHistoryScore 0 CoApplicant 0 Approved 0

— 정제 후 결측치 확인 — ApplicantID 0 ApplicantIncome 0 LoanAmount 0 CreditHistoryScore 0 CoApplicant 0 Approved 0 ```

💡 분석가의 통찰 (Analyst’s Insight)

  • 대출금 중앙값 보정의 비즈니스 타당성: 희망 대출 금액은 초고액 기업 성격의 신청 건으로 인해 전체 대출 평균이 심각하게 상단으로 쏠려 있습니다. 무작정 평균 대출금으로 대입하면 서민 가계의 미기재 신청액이 소득 수준을 아득히 뛰어넘는 억대 부채로 과대 포장됩니다. 극단값을 차단하는 중앙값(Median) 대치가 심사 무결성에 맞습니다.

Step 3: 단변수 분포 분석 (Univariate EDA)

Step 3 시각화 개념도

가장 먼저 핵심 변수가 전체 데이터에서 어떤 빈도와 분포를 가졌는지 단일 변수 시각화를 통해 파악해 봅니다.

plt.figure(figsize=(8, 5))

# 단변수 분석 그래프 생성
sns.countplot(data=df, x='Approved', palette='coolwarm')
plt.title('은행 대출 최종 심사 승인(Approved) 빈도 분포', fontsize=14, fontweight='bold')
plt.show()

💻 [실행 결과] 실행 결과 시각화

💡 시각화 차트 읽는 법 & 인사이트

  • 엄격한 리스크 필터링 분포: 대출 심사 승인(Yes)과 거절(No) 비율 막대는 과반의 균형 상태를 나타냅니다. 무조건적 대출 승인을 남발하지 않고 신용에 맞게 승인 장벽을 통제하는 여신 리스크 관리가 작동 중임을 보여줍니다.

Step 4: 다변수 상관관계 및 이상치 분석 (Multivariate EDA)

Step 4 상관관계 분석 개념도

두 개 이상의 변수를 동시에 결합하여, 조건에 따른 수치 차이나 독립 변수와 종속 변수 간의 통계적 경향을 분석합니다.

plt.figure(figsize=(9, 6))

# 다변수 분석 그래프 생성
sns.scatterplot(data=df, x='ApplicantIncome', y='LoanAmount', hue='Approved', palette='Set1', alpha=0.8)
plt.title('신청자 월 소득 대비 대출 희망금액과 승인 여부 분포', fontsize=14, fontweight='bold')
plt.show()

💻 [실행 결과] 실행 결과 시각화

💡 코드 딥다이브 & 비즈니스 통찰 (Analyst’s Insight)

  • DTI 임계선을 넘어서는 거절 벨트 규명: 소득(X축) 대비 대출금(Y축)이 가파르게 솟은 좌상단 영역(소득은 적은데 빌려달라는 돈은 매우 큰 고위험 구역)은 빨간색 점(Approved=No, 거절)으로 도배되어 있습니다. 반면 소득 대비 대출 비율이 완만한 우상향 벨트와 하단 영역은 승인(Yes) 점들이 밀집해 있어, 은행의 소득 비례 부채 한도 필터링 규정이 시각적으로 선명한 대출 승인 경계를 형성함을 입증합니다.

Step 5: 통계적 직관과 해석 (Statistical Logic)

💡 [은행 여신 관리와 로지스틱 회귀 및 부도 임계값(Threshold) 최적화] … (생략: 은행 대출 부도 가능성 예측 로지스틱 모형 및 분류 임계치 최적화 요약)


🎯 30분 강의 마무리 및 심화 과제

오늘 우리는 실전 데이터셋을 분석하여 판다스로 데이터를 가공 및 정제하고, 시각화를 활용하여 핵심 변수 간의 통계적 유의성을 검증했습니다. 데이터 속에서 숨겨진 패턴을 올바른 시각으로 탐색하는 능력이 데이터 사이언티스트의 가장 강력한 무기입니다.

📝 심화 과제 (Advanced Challenge)

  • 신용등급(CreditHistoryScore)과 승인(Approved) 여부의 상관 분석: 신용 등급이 몇 점 이상일 때 거절(No) 확률이 제로에 수렴하는지 구간 분석을 가동해 보세요.
  • 연대 보증 참여에 따른 대출 금액 도약 비교: CoApplicant 유무에 따라 평균 승인되는 대출 한도의 증가액 차이를 피벗 테이블로 대조해 보세요.
서브목차