TadaoYamaokaの開発日記

個人開発しているスマホアプリや将棋AIの開発ネタを中心に書いていきます。

仮説検定でプログラムが有意に強くなったか検証する

プログラムで自己対局したときに、その対局数と勝敗の数から何%勝ちなら強くなったといえるのか。
そのような問題に統計的に答える方法として、仮説検定という方法がある。

仮説検定

仮説検定は、帰無仮設と対立仮説を設定し、帰無仮説が定めた有意水準の範囲内かにより、棄却されるか採択されるか判定する。

詳しい説明は、統計の教科書に譲るとして、対局結果から強いかの検定には以下の式で計算する。

帰無仮説 H_0P=P_0(=0.5)
対立仮説 H_1P > P_0
と設定すると、
\displaystyle
u_0 = \frac{r-P_0}{\sqrt{P_0(1-P_0)/n}}
u_0が棄却域Rにあれば、帰無仮説H_0は棄却され、対立仮説H_1が採択される。

ここで、rは勝率、nは対局数で、棄却域Rは、有意水準\alpha=0.05とするとR > 1.644854となる。

棄却域の臨界値は、R言語を使って、

qnorm(0.05, lower.tail=FALSE)

で計算できる。

対局数がn=100の場合、勝率rが有意であるためには、
\displaystyle
\frac{r-0.5}{\sqrt{0.5(1-0.5)/100}}>1.644854
から、
\displaystyle
r>0.5822427
であれば有意に強いと言える。

対局数が1000回だと、
\displaystyle
r>0.5260074
となる。

前回の日記で、自己対局の結果、100回対局して勝率が54%で強くなっていると判断したが、統計的には有意とは言えない。
逆に、勝率54%を有意と言うには、
\displaystyle
\frac{0.54-0.5}{\sqrt{0.5(1-0.5)/n}}>1.644854
から
\displaystyle
n > 422.7414
の対局が必要になる。

勝率と必要対局数

勝率と必要対局数の関係は、以下のグラフのようになる。
f:id:TadaoYamaoka:20170615075043p:plain
※横軸は勝率で、縦軸は必要対局数(10の対数)

グラフはR言語の以下のスクリプトでplotした。

need_n <- function(r) {
  qnorm(0.05, lower.tail=FALSE)^2 * 0.5 * (1-0.5) / (r - 0.5)^2
}
need_n_log10 <- function(r) {
  log10(need_n(r))
}
plot(need_n_log10, 0.5, 1)

Pythonでグラフを描くには、以下のように実行する。

import matplotlib.pyplot as plt
import numpy as np
import scipy.stats

x = np.linspace(0.5, 1, 100)
plt.plot(x, scipy.stats.norm.ppf(0.95)**2 * 0.5 * (1 - 0.5) / (x - 0.5) ** 2)
plt.yscale("log")