Kolmogorov-Smirnov (KS) Statistics は、予測モデルを検証するために使用する最も重要なメトリックの 1 つです。 これは、BFSI ドメインで広く使用されています。
KS統計とは何ですか?
Kolmogorov-Smirnovの略で、Andrey KolmogorovとNikolai Smirnovにちなんで命名されました。 2つの累積分布を比較し、その差の最大値を返します。 これはノンパラメトリック検定で、データの分布に関連するいかなる仮定も検定する必要がないことを意味します。 KS検定では,帰無仮説は,両方の累積分布が類似しているとする. データサイエンスでは、事象と非事象の累積分布を比較し、2つの分布の間に最大差があるところでKSとします。 簡単に言うと、予測モデルがどの程度事象と非事象を識別できるかを理解するのに役立ちます。
ある製品を購入しそうな見込み客を特定することを目的とした傾向モデルを構築しているとします。 この場合、従属(ターゲット)変数は、0 (Non-event) または 1 (Event) の2つの結果しかないバイナリ形式である。 「イベント “は、製品を購入した人々を意味します。 “非イベント” は、製品を購入しなかった人々を意味します。 KS統計量は、モデルが見込み客と非見込み客を区別できるかどうかを測定する。
KS統計量を測定する2つの方法
この方法は、バイナリ予測モデルの検証のためにKS統計量を計算する最も一般的な方法である。
- KSを計算する前に、2つの変数を持っている必要があります。 1つは、従属変数で、バイナリであるべきです。
- 予測される確率列に基づいて10進数を作成し、これは確率を10分割することを意味します。
- 各十分位におけるイベントと非イベントの累積割合を計算し、これら2つの累積分布の差を計算します。
- 差が最大となる場所がKSとなります。
Python : KS Statistics Decile Method
サンプルデータを用意しましたので例として紹介します。 このデータセットにはyとpという2つの列があり、y
は従属変数です。 p
は予測される確率です。
import pandas as pdimport numpy as npdf = pd.read_csv("https://raw.githubusercontent.com/deepanshu88/data/master/data.csv")
def ks(data=None,target=None, prob=None): data = 1 - data data = pd.qcut(data, 10) grouped = data.groupby('bucket', as_index = False) kstable = pd.DataFrame() kstable = grouped.min() kstable = grouped.max() kstable = grouped.sum() kstable = grouped.sum() kstable = kstable.sort_values(by="min_prob", ascending=False).reset_index(drop = True) kstable = (kstable.events / data.sum()).apply('{0:.2%}'.format) kstable = (kstable.nonevents / data.sum()).apply('{0:.2%}'.format) kstable=(kstable.events / data.sum()).cumsum() kstable=(kstable.nonevents / data.sum()).cumsum() kstable = np.round(kstable-kstable, 3) * 100 #Formating kstable= kstable.apply('{0:.2%}'.format) kstable= kstable.apply('{0:.2%}'.format) kstable.index = range(1,11) kstable.index.rename('Decile', inplace=True) pd.set_option('display.max_columns', 9) print(kstable) #Display KS from colorama import Fore print(Fore.RED + "KS is " + str(max(kstable))+"%"+ " at decile " + str((kstable.index==max(kstable)]))) return(kstable)
mydf = ks(data=df,target="y", prob="p")
-
data
はpandas dataframeで、従属変数と確率スコアが含まれているものです。 -
target
は従属変数の列名 -
prob
は予測確率の列名
各十進数の情報を表形式で返し、表の下にKSスコアも出力します。
min_prob max_prob events nonevents event_rate nonevent_rate \Decile 1 0.298894 0.975404 49 51 49.00% 5.67% 2 0.135598 0.298687 19 81 19.00% 9.00% 3 0.082170 0.135089 14 86 14.00% 9.56% 4 0.050369 0.082003 10 90 10.00% 10.00% 5 0.029415 0.050337 5 95 5.00% 10.56% 6 0.018343 0.029384 1 99 1.00% 11.00% 7 0.011504 0.018291 1 99 1.00% 11.00% 8 0.006976 0.011364 1 99 1.00% 11.00% 9 0.002929 0.006964 0 100 0.00% 11.11% 10 0.000073 0.002918 0 100 0.00% 11.11% cum_eventrate cum_noneventrate KS Decile 1 49.00% 5.67% 43.3 2 68.00% 14.67% 53.3 3 82.00% 24.22% 57.8 4 92.00% 34.22% 57.8 5 97.00% 44.78% 52.2 6 98.00% 55.78% 42.2 7 99.00% 66.78% 32.2 8 100.00% 77.78% 22.2 9 100.00% 88.89% 11.1 10 100.00% 100.00% 0.0 KS is 57.8% at decile 3
scipy
python libraryを使用すると、2標本のKS統計量を計算することができる。 data1とdata2という2つのパラメータがあります。 data1には、非イベントに対応するすべての確率スコアを入力します。
from scipy.stats import ks_2sampdf = pd.read_csv("https://raw.githubusercontent.com/deepanshu88/data/master/data.csv")ks_2samp(df.loc, df.loc)
KS スコアは 0.6033 で、p 値は 0.01 より小さく、帰無仮説を棄却し、イベントと非イベントの分布が異なると結論付けられます。
OutputKs_2sampResult(statistic=0.6033333333333333, pvalue=1.1227180680661939e-29)
方法 2 の KS スコアは方法 1 と若干異なり、2 は行レベルで、1 はデータを 10 分割に変換した後に計算されるため。