KS통계량 산출 함수 만들기

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통계량을 산출하는 파이썬 함수를 작성해 보았습니다. 모델링 이후 해당 함수를 이용해서 성능을 검증해 보시는 건 어떨까요?

감사합니다!

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다