2022年7月17日日曜日

コルモゴロフ・スミルノフ検定

2群のデータを比較するためにヒストグラムを作成しました。
それを眺めながら、分布形状が似ている、似ていないを判断したいのですが、主観だと説明性に欠けます。ということで統計的検定の出番です。

以前、2標本(対応ナシ)の条件で Mann-Whitney's U test を使用しました。
https://phreeqc.blogspot.com/2020/12/mann-whitneys-u-test.html

今回は2群のサンプル数が異なるとともに、サンプルが非常に多く何らかの確率分布を仮定できそうでした。
調べてみると、ありますね。
・2標本のコルモゴロフ・スミルノフ検定
two-sample Kolmogorov-Smirnov(K-S) test

手順は、①2群を同じ階級幅で区分して累積度数を求める。②累積度数を累積確率に変換し、その差の絶対値を計算。③絶対値の最大値を使って検定統計量を求め、④棄却限界値と比較し判定する。棄却限界値は自由度f=2のχ2分布から求めます。

これは、好都合。ヒストグラムを全面積で正規化し、縦軸を確率密度で記載していたので処理は半分終わっています。あとは累積確率に直して差の最大値を求めるだけのようなもの。χ2分布の適用も、おかしくはない分布ですから、これで決定です。というか、2群のヒストグラムを書く際に、ルーチンワークとして求めておけば良い内容です。Python コードを残しておきましょう。

def hist_plot(col,x1,x2,label,bins):
    fig = plt.figure(figsize=(15,5))
    ax = fig.add_subplot(1,1,1)

    freq,bin_list,patch=ax.hist([x1,x2], density=True, alpha=0.5 ,edgecolor='black', bins=bins, label=label)
    ax.set_xlabel(col,fontsize=14)
    ax.set_ylabel('確率密度',fontsize=14)
    ax.grid(which='major',color='gray',linestyle='-')
    ax.grid(which='minor',color='gray',linestyle='--')
    ax.legend(borderpad = 0.8,framealpha=1.0,shadow=True)
   
    #2標本コルモゴロフ・スミルノフ検定(χ2分布、各標本数40以上、対応の無い2標本)
    df_p=pd.DataFrame({col:bin_list[1:],label[0]+'_確率密度':freq[0],label[1]+'_確率密度':freq[1]})
    df_p_sum=df_p.cumsum()*bin_list[1]
    df_p_sum=df_p_sum.drop(col,axis=1)
    df_p_sum.columns  = [label[0]+'_累積確率', label[1]+'_累積確率']
    df_p_sum['D']=abs(df_p_sum[label[0]+'_累積確率']-df_p_sum[label[1]+'_累積確率'])
    df_p=pd.concat([df_p, df_p_sum], axis=1)

    n1=len(x1)
    n2=len(x2)
    Dmax=df_p['D'].max()
    Dmax2=Dmax*Dmax
    T=4*Dmax2*(n1*n2)/(n1+n2)
    if T<5.99146:
        comment='有意水準5%で、差があるとは言えない。'
    else:
        comment='有意水準5%で、差があると言える。'       
    display(df_freq,'Dmax',Dmax,'T',T,comment)

Dが小さいと、差があるとは言えない(H0を棄却しない)

H0:帰無仮説(差がない)
H1:対立仮説(差がある)

0 件のコメント:

コメントを投稿