概要
データ分析なら「Python」か「R」がいいよね。
・・・ということで「F#」で「独立性の検定(カイ2乗検定・フィッシャーの直接確率検定)」を行なってみました。内容は「PythonとRで独立性の検定」の移植です。解説は Python版 のエントリを参照ください。
なお、F#で実行するにあたって Accord.NET というパッケージを利用しました。あらかじめ nuget で Accord.Statistics を導入しておいてください。ここではバージョン 3.8.0 を使いました。
コード
独立性の検定
open System
open Accord.Statistics.Testing
open Accord.Statistics.Analysis
[<EntryPoint>]
let main argv =
let m = ConfusionMatrix(array2D [ [140; 150]; [160; 180] ])
let cst = new ChiSquareTest(m,yatesCorrection=false)
printfn "カイ2乗検定"
printfn "p値 = %.3f" <| cst.PValue
printfn "自由度 = %d" <| cst.DegreesOfFreedom
printfn ""
let cst = new ChiSquareTest(m,yatesCorrection=true)
printfn "カイ2乗検定(イェーツ補正あり)"
printfn "p値 = %.3f" <| cst.PValue
printfn "自由度 = %d" <| cst.DegreesOfFreedom
printfn ""
let ft = new FisherExactTest(m)
printfn "フィッシャーの直接確率検定"
printfn "p値 = %.3f" <| ft.PValue // 正しく計算できない!
Console.ReadKey() |> ignore
0
実行結果
カイ2乗検定は正しく実行できています(Python版と計算結果が一致)。
しかし、残念ながらフィッシャーの直接確率検定による $p$ 値の計算は失敗しています(確率であるはずの $p$ 値が $1.0$ を超える数値で出力されている)。内部で階乗計算をする際にオーバーフローしていると思われます。
実行結果
カイ2乗検定
p値 = 0.760
自由度 = 1
カイ2乗検定(イェーツ補正あり)
p値 = 0.822
自由度 = 1
フィッシャーの直接確率検定
p値 = 1.300
観測度数が小さなものでフィッシャーの直接確率検定
観測度数が小さい場合は、うまく計算できるのかをチェックします。
まずは、Pythonで実行してみます。
Python
import pandas as pd
import scipy.stats as st
df = pd.DataFrame([[14,10],[21,3]])
_, p = st.fisher_exact(df)
print(f'p値 = {p :.3f}')
実行結果
p値 = 0.049
今度は、F# で実行してみます。
F#
let m = ConfusionMatrix(array2D [ [14; 10]; [21; 3] ])
let ft = new FisherExactTest(m)
printfn "p値 = %.3f" <| ft.PValue
実行結果
p値 = 0.049
一致しました。ついでに R でも試してみます。
R
m=matrix(c(14, 10, 21, 3), nrow=2, byrow=T)
fisher.test(m)
実行結果
Fisher's Exact Test for Count Data
data: m
p-value = 0.04899
alternative hypothesis: true odds ratio is not equal to 1
95 percent confidence interval:
0.03105031 0.99446037
sample estimates:
odds ratio
0.2069884
一致しています。