K-S통계량은 본래 두 집단의 분포가 동일한 지 검증하는 통계량 입니다. 이진분류예측 모형에 대한 성능을 검증하기 위한 지표로 자주 사용됩니다. K-S통계량 및 해당 내용에 대한 자세한 설명은 K-S-통계량-산출하기 글을 참고하시기 바랍니다. 이번 포스팅에서는 KS통계량 산출 함수를 파이썬으로 작성해 보겠습니다.
실습 데이터 준비
K-S통계량을 산출을 위한 아래 실습 데이터를 D드라이브에 다운로드 받으세요.
데이터는 총 3개의 변수와 32개의 관측치로 구성되어 있습니다.
- id : 고객에게 부여된 고유 식별자
- prob : 우량회원으로 판별될 확률 (값이 클수록 우량 회원일 가능성이 높음을 의미합니다)
- good_yn : 실제 우량회원 여부를 나타내는 라벨링 값(1: 실제 우량 회원 / 0 : 실제 불량 회원)
현장에서 사용되는 실제 데이터는 이보다 훨씬 더 많은 변수와 관측치가 있지만, 실습을 위해 필요한 변수만 fake data를 생성하였습니다.
실습 데이터 가져오기
D드라이브에 실습 데이터를 다운로드 하셨다면, 해당 파일을 파이썬으로 불러 들여야 합니다.
import pandas as pd
ksData = pd.read_csv("D:/test.csv", header = True)
ksData.head()
-----------------------------------------------------
id prob good_yn
0 M1 0.657239 0
1 M2 0.712358 0
2 M3 0.858259 1
3 M4 0.776954 1
4 M5 0.016729 0
- import pandas as pd : 실습에 필요한 pandas 모듈을 로딩합니다.
- ksData = pd.read_csv(“D:/test.csv”, header = True) : read_csv함수를 사용해서 D드라이브에 저장된 test.csv 파일을 ksData에 데이터프레임 형태로 저장합니다(read_csv함수에 대한 자세한 설명은 pandas-read_csv-함수-이해하기 글을 참고하시고, 데이터 프레임에 대한 자세한 설명은 판다스-데이터프레임-이해하기 글을 참고하시면 됩니다.).
- ksData.head() : head 함수를 이용해서 ksData에 저장된 데이터프레임의 상위 5개에 해당하는 데이터를 관찰해 봅니다.
K-S통계량 산출하기
ksData에 저장된 데이터프레임을 활용하여 K-S통계량을 산출해 보겠습니다.
확률값(prob) 기준의 실제 우량, 불량 회원 분포 산출
실제 우량 회원 수 전체에서 각 prob 값에 포함된 우량 회원 분포(비율)를 산출합니다. 유사한 방법으로 실제 불량 회원 수 전체에서 각 prob 값에 포함된 불량 회원 분포(비율)를 산출합니다.
ksStatData = pd.crosstab(index = ksData['prob'], columns = ksData['good_yn'], normalize = 'columns')
ksStatData = ksStatData.cumsum()
ksStatData
-------------------------------------------------
good_yn 0 1
prob
2.270000e-08 0.055556 0.000000
6.520000e-06 0.111111 0.000000
4.930000e-05 0.166667 0.000000
6.460000e-05 0.222222 0.000000
1.051534e-03 0.277778 0.000000
4.082341e-03 0.333333 0.000000
8.017243e-03 0.388889 0.000000
8.611581e-03 0.444444 0.000000
1.463602e-02 0.500000 0.000000
1.537741e-02 0.555556 0.000000
1.672865e-02 0.611111 0.000000
2.046442e-02 0.666667 0.000000
2.490636e-02 0.722222 0.000000
1.250865e-01 0.777778 0.000000
1.347222e-01 0.833333 0.000000
3.283362e-01 0.833333 0.071429
5.900685e-01 0.833333 0.214286
6.572390e-01 0.888889 0.214286
7.103109e-01 0.888889 0.285714
7.123583e-01 0.944444 0.285714
7.769535e-01 0.944444 0.357143
8.327160e-01 0.944444 0.428571
8.570490e-01 1.000000 0.428571
8.582586e-01 1.000000 0.500000
8.721997e-01 1.000000 0.571429
9.215054e-01 1.000000 0.642857
9.759665e-01 1.000000 0.714286
9.763156e-01 1.000000 0.785714
9.817443e-01 1.000000 0.857143
9.899765e-01 1.000000 0.928571
9.951288e-01 1.000000 1.000000
- crosstab 함수를 활용하여 실제 우량/불량 전체 회원수에서 각 prob에 속한 우량/불량 회원 분포를 산출하였습니다
(crosstable 함수에 대한 자세한 설명은 Pandas crosstab() 함수 이해하기 글을 참고하세요). - cumsum 함수를 활용하여 실제 우량/불량 전체 회원수에서 각 prob에 속한 우량/불량 회원 누적 분포를 산출하였습니다. cumsum 함수는 주어진 변수값에 대해 누적합을 계산하는 함수입니다.
K-S 통계량 산출
K-S 통계량 산출 공식을 준용하여 최총 K-S통계량을 산출합니다.
# 각 prob 구간별 실제 누적 불량 회원 비율에서 실제 누적 우량 회원 비율의 차이를 계산한 후, 절대값을 취함
tempKsStat = (ksStatData[0] - ksStatData[1]).abs()
# 각 prob 구간별 KS 통계량 중에서 최댓값을 가져와 최종 K-S통계량을 산출
ksStat = tempKsStat.max()
# K-S 통계량 출력
print(f'K-S 통계량 : {ksStat:.2%}')
------------------------------------------------------
K-S 통계량 : 83.33%
K-S통계량 산출 파이썬 함수 생성
위의 코드를 활용해서 최종 K-S통계량 산출 파이썬 함수를 생성합니다.
import pandas as pd
ksData = pd.read_csv("D:/test.csv")
def ks_statistics(data, p, target) :
# data : KS통계량 산출을 위한 데이터프레임
# p : 우량 회원으로 판별될 확률
# target : 실제 우량/불량 회원을 구분하는 라벨링 값
ksStatData = pd.crosstab(index = p, columns = target, normalize = 'columns')
ksStatData = ksStatData.cumsum()
ksStat = (ksStatData[0] - ksStatData[1]).abs().max()
print(f'K-S 통계량 : {ksStat:.2%}')
# ks_statistics 함수 반환값으로 KS통계량 지정
return ksStat
위에서 작성한 파이썬 함수를 활용하여 KS통계량을 산출한 결과(아래), 위에서 산출한 K-S통계량 값과 동일하게 산출되었음을 확인할 수 있습니다.
ksStat = ks_statistics(ksData, ksData['prob'], ksData['good_yn'])
-------------------------------------------------------------------
K-S 통계량 : 83.33%
ksStat
--------------------
0.8333333333333336
이번 포스팅에서는 이진분류예측 모형에 대한 성능을 검증하는 지표인 KS통계량을 산출하는 파이썬 함수를 작성해 보았습니다. 모델링 이후 해당 함수를 이용해서 성능을 검증해 보시는 건 어떨까요?
감사합니다!