コンピュータ将棋基礎情報研究所

コンピュータ将棋に関する基礎的な情報を収集し、分析し、発表する所です。英語名称はLaboratory for Fundamental Information on Computer Shogi (LFICS)。

詳細な説明は、以下の解説記事をご覧ください。

javascriptにより、ブラウザから実行できるプログラムです。単一のhtmlファイルですので、何をしているのかはソースを見れば分かります。

一応、安全性は確認しておりますが、バグやファイル改ざん等のリスクまでは対応できません。利用する際には自己責任でお願い致します。このプログラムの使用に関して、当方は一切の責任を負いません。

古いブラウザだと動かないかもしれません。

対局数が多い場合には、処理に時間がかかることがあります。

英語版の表記は以下の意味です。

  • 「games」:対局数。
  • 「wins」:勝ち数。
  • 「draws」:引き分け数。
  • 「confidence interval」:信頼区間。
  • 「Calculate」:計算実行。
  • 「Select all」:全選択。
  • 「winning percentage」:勝率。
  • 「standard error」:標準誤差。
  • 「relative Elo rating」:相対イロレーティング。

「removed from games」は引き分けを対局数から取り除く場合、「transformed into (draws / 2) wins」は引き分け数の半分(端数は切り捨て)を勝ち数に加える場合に選択してください。

このプログラムは、パブリックドメイン(公有)扱いとします。ご自由にお使いください。

以下はc++版の関数です。やっていることは基本的にjavascript版と同じですが、コメントが付いています。

#include <algorithm> // std::minとstd::maxのため。windows.hの名前衝突に注意。
#include <cmath> // 数学関数のため。

// ----------------------------------------------
double log10_binomial(const int & n, const int & k)
// 二項係数 C(n, k) の常用対数。
// ----------------------------------------------
{
	const int m = std::min(k , (n - k));

	double s = 0.0;

	for (int i = 1; i <= m; i++)
	{
		s += std::log10((n - m + i) / double(i));
		// オーバーフロー対策で対数での計算。
		// 常識的な範囲の計算なら対数を取らずに掛け算のやり方でもよい。
		// javascript版では場合分けで少し高速化。
	}

	return(s);
}

// ----------------------------------------------
double binomial_distribution(const int & n, const int & k, const double & p)
// 二項分布 C(n, k) * p^{k} * (1 - p)^{n - k} の値。
// ----------------------------------------------
{
	return(std::pow(10.0, (log10_binomial(n, k) + k * std::log10(p) + (n - k) * std::log10(1.0 - p))));
	// オーバーフロー対策で対数での計算。
}

// ----------------------------------------------
void confidence_interval(const int & n, const int & k, const double & a, double & p, double & p_min, double & p_max, double & dr, double & dr_min, double & dr_max)
// 入力:対局数n、勝利数k、[100 * (1 - a)]%信頼区間のa。
// 出力:勝率推定値p、勝率下限値p_min、勝率上限値p_max、レート差推定値dr、レート差下限値dr_min、レート差上限値dr_max。
// ----------------------------------------------
{
	if ((n < 5) || (k <= 0) || (k >= n) || (a <= 0.0) || (a >= 1.0))
	{
		// 本来はエラー処理、ここでは省略。
		return;
	}

	// 勝率推定。
	p = k / double(n);

	// 挟み撃ちで区間を絞っていくための初期値。
	int k_min = 0;
	int k_max = n;

	// 区間境界での二項分布の値の初期値。
	double b_min = binomial_distribution(n, k_min, p);
	double b_max = binomial_distribution(n, k_max, p);

	// 確率の積算値。0から始めて、a越えを目指す。
	double s = 0.0;

	while (true) // a超えまでの無限ループ。
	{
		// 境界の分布値が小さい方を狭めていく。
		if (b_min < b_max)
		{
			s += b_min;
			if (s >= a) {break;} // 超えたら抜ける。越える前が信頼区間。
			k_min++;
			b_min = binomial_distribution(n, k_min, p);
		}
		else
		{
			s += b_max;
			if (s >= a) {break;} // 超えたら抜ける。越える前が信頼区間。
			k_max--;
			b_max = binomial_distribution(n, k_max, p);
		}
	}

	// 区間を勝率に直す。
	p_min = k_min / double(n);
	p_max = k_max / double(n);

	// レート差の計算。
	dr = 400.0 * std::log10(p / (1 - p));
	dr_min = (k_min == 0) ? -1.E308 : (400.0 * std::log10(p_min / (1 - p_min)));
	dr_max = (k_max == n) ?  1.E308 : (400.0 * std::log10(p_max / (1 - p_max)));
	// 念のために対数の発散を避けているが、普通の環境なら不要。

	return;
}

前回の記事「自己対戦及び連続対戦の誤差論 1:標準誤差と信頼区間」では、自己対戦/連続対戦の対局数が十分に大きい場合に誤差をどのように見積もればいいのかを整理しました。今回は、対局数の影響について解説します。

標準誤差は対局数nの平方根に逆比例していました。つまり、対局数が大きくなるほど、誤差は小さくなり、精度が高くなるということになります。

必要な精度というのは、実験者がどれくらいまで求めるのかということに依ってきますが、「実際に誤差を計算してみて、必要な精度が出ているかどうか」というのが「対局数が十分であるかどうか」の基本的な判断基準になります。ただし、誤差の計算には、いくつか注意しなければならないことがあります。それが今回の記事の主題です。

前回の記事で紹介した誤差論は、対局数が多くて標準誤差が小さい時に有効なものでした。そうでない場合には、誤差の見積もりを修正しなければならないことがあります。

例えば、標準誤差は、勝率の真値pに依存しており、p (1 - p)に比例していました。これは、pの関数として描くと、下図のようになります。

p_1-p

しかしながら、勝率の真値pは分からないため、勝率の推定値qを用いて、標準誤差を推定することになりました。pとqの値が近ければ、この標準誤差の推定は妥当なものとなりますが、もしそうでなければ、標準誤差の推定は的外れなものになってしまうかもしれません。特に、qが0や1に近い場合には、変化が大きいので、注意が必要です。

実際の標準誤差が推定よりも小さい場合には問題はないのですが、推定よりも大きい場合には、実際の精度よりも過剰に精度を見積もってしまうことになるため、問題が生じ得ます。該当する場合には、標準誤差を適度に上方修正して考える必要があるでしょう。

この話は、言い換えると、誤差の高次の項の問題の一種ということになります。誤差が小さければ現れなかった問題が、誤差が大きくなってくると無視できなくなってくるということです(※)。これらの問題をまとめて解決するには、結局のところ、対局数を増やして精度を上げるしかありません。

※(2016年5月31日追記) そもそも「誤差」は真値との差として定義されているわけですが、真値というのは値が分からないものであるため、「誤差」を計算するには真値について何らかの仮定を置く必要があります。これが、誤差論の根本的な問題の一つであり、高次の項の問題の根本もそこにあります。この問題を避けるため、「誤差」という概念は諦めて、「不確かさ」という概念を導入するというのが近年の主流です。「不確かさ」は平均からのばらつきとして定義され、その平均が真値に近いかどうかは問題を切り分けます。「誤差」と異なり、「不確かさ」についてならば、紛れのない国際基準を作ることも可能であり、その国際基準(GUM)は物理学や工学等の分野で広く採用されています。

一方で、誤差の大きさとは直接的に関係無しに、対局数の不足のみによって生じる問題もあります。具体的には、中心極限定理の適用の妥当性の問題です。こちらは理論的に対処することができます。

中心極限定理は、対局数が十分に大きい時に、確率分布が正規分布になることを示していました。しかしながら、実際には、n回連続対戦した時の勝率の推定値qの確率分布は離散確率分布になっており、正規分布のような連続確率分布にはなっていません。なぜなら、qは、自然数である勝ち数kを使って、“k / n”と計算されるからです。もちろん、nが十分に大きくなれば、“k / n”の有理数は実数に近いものとして取り扱うことができるわけですが、実際にそれがどれくらい良い近似であるのかというのは、誤差の評価とは別に、対局数によって決まってくる問題ということになります。

実際の確率分布は、勝率の真値pを用いると、\[\frac{n!}{k! (n - k)!} p^{k} (1 - p)^{n - k},~~ k = n q\]の二項分布として書き表すことができます。

この二項分布の標準偏差は、\[S = \sqrt{\frac{p (1 - p)}{n}}\]であり、前回の正規分布の標準偏差と同じになりますので、標準誤差については、実は対局数に依らずに厳密な値であったということが分かります。

対局数によって変わってくるのは、標準誤差と信頼区間との間の関係です。以下の図は、正規分布において95%信頼区間である「真値±1.96標準誤差」(上図)と99%信頼区間である「真値±2.58標準誤差」(下図)内の実際の確率を表しています。分布が正規分布であれば、それぞれ0.95と0.99になるはずのものですが、実際には二項分布であるために離散的に値が変わってきます。横軸は対局数nです。

s

二項分布はnが十分に大きければ、正規分布で近似することができます。これは中心極限定理に対応しています。ただし、nが大きくても、n p、もしくはn (1 - p)が小さければ、ポアソン分布になり、正規分布にはなりません。実際に、上記の図でも、pが0.5(黒点)と0.1(橙色点)の時には、正規分布に近い結果になっており、pが0.01(赤点)の時には、正規分布の結果からのズレが大きくなっています。

上の図で示した区間内の確率は大きい分には問題ないのですが、小さくなると、その分だけ信頼が落ちるということになります。また、これらの確率は勝率の真値pに依存しており、真値pは分からないものですので、対局数を調整して信頼を上げるというような操作を行うこともできません。結局のところ、確率の下限の方に着目して、その分だけ信頼区間の%を下方修正して考えるというのが、妥当な解釈ということになるでしょう。

勝率の真値pに対して推定値qを適用してよいということであるのならば、二項分布を用いて、最小の信頼区間を推定することができます。ただし、この信頼区間においても、上で記した「誤差の高次の項の問題」は変わらずに発生し得ます。この処方箋で対処できるのは、「中心極限定理の適用の妥当性の問題」のみです。

さて、前回の記事で、相対レートにおける標準誤差を推定する際に、勝率の標準誤差Sに対する展開を行いました。この展開は、Sがpや(1 - p)よりも十分に小さい時には有効なのですが、そうでない場合には使うことができません。特に、勝率に対してそれなりに広い信頼区間が与えられた時には、破綻してしまいます。

この問題も「誤差の高次の項の問題」の一種ですが、これは観測データの直接的な処理の問題ではなく、誤差伝播という間接的な処理の問題であるため、理論的な対処が可能です。

実際に、相対レートは勝率に対して単調増加関数ですので、信頼区間が与えられた時には、展開を用いなくても、上限値と下限値をそのまま放り込むことで、対応する相対レートの信頼区間を得ることができます。

これらの信頼区間の見積もりはコンピュータで簡単に計算することができます。「連続対戦における信頼区間の計算」の資料記事に計算プログラムを記しました。

以上、自己対戦/連続対戦の結果から勝率やレートを推定する際の誤差論について整理しました。結局のところ、実験の精度はデータの質と量で決まってきます。地道にデータを収集する基礎研究が華々しい成果の基盤になるのだと思います。

コンピュータ将棋の特長の一つに、誰でも簡単にソフト同士の対局実験ができるということがあります。人間の将棋の場合には、同じ人同士を100回、1000回と連続対局させて勝率を推定するというような実験は現実的に困難であるわけですが、コンピュータ同士なら黙々とやってくれます。実験ができるというのは技術開発にとって非常に大切なことです。

「同じソフト同士を戦わせたら毎回、同じ結果になるんじゃないか」と思われる方もいるかもしれませんが、多くの将棋ソフトは序盤に擬似的なランダム性が入っていますので、その範囲内で違った結果になります。逆に言えば、一局の結果というのは確率的なものですので、統計的に処理して、誤差も考えないと、適切な能力評価ができないと言えます。

今回は、自己対戦/連続対戦の結果から勝率やレートを推定する際の誤差の問題について整理してみたいと思います。以下、先手後手の手番については、常に割合を一定で揃えること(同数、もしくは常に先手/後手のみ等)として、誤差には影響しないものとします。また、引き分けもないものとしています。これは、引き分けの対局を取り除いていると考えることもできますし、互いに0.5勝分として2つの引き分けを1勝1敗に変換していると考えることもできます(※引き分けが奇数の場合は余りが出ますが、1つなら、どう処理しても以下の議論にほとんど影響を与えません)。

まずは、AとBがn回連続対戦して、Aがk回勝った時のAの勝率を推定してみましょう。

「そんなの勝率なんだから、“k / n”に決まってるだろ」と思われるかもしれませんが、そう思う根拠は何かということです。実際に、本当の勝率p(真値)というのは無限に多くの対局を行った時の勝ち数の割合の極限値であり、有限の対局数における“k / n”とは必ずしも一致しません。“k / n”というのは、pの推定値に過ぎないわけですから、何故それを推定値とするのかという根拠がいるわけです。

連続対戦のn回の結果は互いに独立であるとしましょう。人間同士の連続対戦であれば、前の結果を引きずる等の影響があるため、結果が独立であるとは限りませんが、コンピュータ同士の場合には、擬似乱数が機能していれば、互いに独立であるとみなすことができます。

今、勝率の真値pは分かりませんので、代わりに推定値qを用いるとすると、この時、Aがk回勝つ確率の推定値Qは、\[Q = \frac{n!}{k! (n - k)!} q^{k} (1 - q)^{n - k}\]となります。実際に「Aがk回勝つ」というのは実現されており、Qはできるだけ大きい値であった方が現実に近いだろうと考えられますので、Qを最大化するq、すなわち、\[\frac{d{Q}}{d{q}} \propto k - n q = 0\]を満たす\[q = \frac{k}{n}\]が最も尤もらしい推定値(最尤値)ということになります。

また、そもそも真の勝率pというのは、無数の対局結果における勝ち点のデータ集合(母集団)の平均(母平均)であるとも考えられます。この時、連続対戦のn回の結果というのは無作為の標本であると考えられますので、標本平均である“k / n” = qは、二乗誤差を最小化する「母平均の不偏推定値」にもなっています。平均と不偏推定値については、「平均と標準偏差:それって不偏推定値?」の解説記事をご覧ください。

つまり、この場合には、qというのは最尤値であり、かつ不偏推定値でもあるため、誰もが自然に受け入れていたということになります。以下、誤差論においては、「標本平均」という立場の方が分かりやすいので、そちらの立場から話を進めていきます。

さて、標本平均は、サンプル数nが同じでも、サンプルセットが異なれば値が変わり得ます。実際、n回の連続対戦を行う度に、毎回、標本平均である勝率の推定値qは異なる値になり得るわけです。つまり、標本平均自体が何らかの確率分布を持っているということになります。

サンプル数nの標本平均の確率分布については、中心極限定理が存在しており、nが十分に大きければ、平均p、標準偏差\[S = \frac{s}{\sqrt{n}}\]の正規分布になることが知られています(※記事の最後に直感的な証明を付記します)。ここで、pはサンプルを取る母集団の平均(すなわち、勝率の真値)であり、sは母集団の標準偏差、すなわち、\[s = \sqrt{p (1 - p)}\]です。標準偏差については、「平均と標準偏差:それって不偏推定値?」の解説記事をご覧ください。

n回の連続対戦を行った時に得られる勝率の推定値は、その確率分布に従って“サイコロ”を投げた時の1つの結果に過ぎません。それがどれくらい真値に近いのかは確率的にしか分からないということになります。

nが十分に大きいとして、確率分布が正規分布であるとすると、“サイコロ”を投げて「真値p±標準偏差S」の区間内の結果が得られる確率は約68.3%ということになります。この時の標準偏差Sは標準誤差とも言います(※慣習的に“シグマ”と呼ぶ人もいますが、記法の慣習は変わりやすいものですので、お勧めはしません)。

また、X%以上の確率で結果が得られるという区間を「X%信頼区間」と言います。つまり、「真値±標準誤差」は「68%信頼区間」です。また、「真値±1.96標準誤差」は「95%信頼区間」であり、「真値±2.58標準誤差」は「99%信頼区間」になります。「真値±(標準誤差×r)」と「[(1 - a)×100]%信頼区間」との関係を下図に示しました。

r-log10a

確率というものは、いくら確率が低くても当たる時には当たってしまうものですので、絶対ということはありません。「標準誤差の何倍まで」/「何%信頼区間」で良しとするのかは、そのデータの重要性を鑑みての人間の判断ということになります。とりあえずは標準誤差を推定しておけば、後は各人で判断が可能です。

ここで、「標準誤差を推定」と書いたのは、上述のSの式が母集団の標準偏差sに依存しているためです。母集団の標準偏差は、勝率の真値pが分からないと分からないため、これも推定する必要があります。ただし、こちらは真値の推定よりもゆるいものでよいため、式中の勝率の真値pを推定値q = k / nで置き換えて、\[s \approx \sqrt{q (1 - q)}\]としてもいいですし、標本の不偏標準偏差を用いて\[s \approx \sqrt{\frac{n}{n - (3 / 2)} q (1 - q)}\]と推定してもかまいません(※)。nが十分に大きければ、どちらでもほぼ同じ値になります。不偏推定値にこだわるかどうかの違いです。

※(2016年5月31日追記) 不偏分散の平方根(すなわち、分母が「n - (3 / 2)」ではなく、「n - 1」)を使うこともあり、これを実験誤差と呼びます。これは理論的には中途半端な取り扱いということになるのですが、慣習的には最もよく使われており、例えば、不確かさの国際基準(GUM)でも標準として採用されています。

さて、これでAとBとの間の勝率と標準誤差の推定ができるようになりましたので、次に両者の間の相対レートを求めてみましょう。

相対レートの推定値dRは、勝率の推定値qを用いて、\[dR = 400 \log_{10}(\frac{q}{1 - q}) + K\]で与えられます。ここで、Kは系統誤差を表していますが、これについては後で説明します。イロレーティングについては、以下の解説記事をご覧ください。

相対レートの標準誤差を求めるには、誤差伝播を考慮する必要があります。勝率の推定値qが、勝率の真値pと標準誤差Sから、q = p±Sで書かれる場合を想定して、上の相対レートの推定値の式をpの周りでSについて1次まで展開すると、\[dR \approx 400 \log_{10}(\frac{p}{1 - p}) + \frac{400}{\ln{(10)}} \frac{S}{p (1 - p)} + K\]となります。最初の項が相対レートの真値であり、次のSの1次の項が相対レートの標準誤差に当たります。相対レートの標準誤差を、Sの次数を変えないように推定値のみで書き換えると、\[\frac{400}{\ln{(10)}} \frac{S}{p (1 - p)} \approx 173.7 \frac{S}{q (1 - q)}\]となります。この誤差伝播における展開は、Sがpや(1 - p)よりも十分に小さくないと成立しませんので、適用する際にはご注意ください。

一般的に、誤差には偶然誤差と系統誤差があります(※設定ミスや計算ミス等の人為的な誤差も生じ得ますが、ここでは除きます)。今まで記してきた標準誤差というのは、偶然誤差を表す指標です。誤差には他に系統誤差が存在しており、これは統計処理で推定したり、取り除いたりすることはできません。

実は、勝率の推定の際にも系統誤差が生じる余地がありました。例えば、擬似乱数が偏っていたり、定期的に“何とかアップデート”が起動してマシンリソースが偏ったりするというようなことがあると、系統誤差が生じてしまい、それは統計処理で何とかなるものではありません。ただし、その時の系統誤差はあったとしても影響は少ないだろうと推測して省いていたわけです。

しかしながら、相対レートについては、相性の問題とイロレーティングの理論の問題があるために、系統誤差を無視することはできません。本来の相対レートというのは相性の問題を取り除いた上で評価されなければなりませんし、そもそもイロレーティングの理論で用いた仮定が妥当でなければ、有意義な値は出てきません。理論の部分については、そもそもイロレーティングを使うべきかという話になりますので、一先ず置いておくとしても、相性の問題は深刻です。

相性の問題については、今のところはデータが整理されておらず、各人の経験によって脳内補正するしかない状況であるようです。この問題については、機会がありましたら、改めて解析してみたいと考えています。

最後に、具体例で計算してみましょう。10000戦してAが8000勝したとします。すなわち、n = 10000、k = 8000です。この時の勝率の推定値は、\[q = \frac{8000}{10000} = 0.8\]となり、標準誤差は、\[S = \sqrt{\frac{10000}{10000 - 1.5}~ \times 0.8~ \times (1 - 0.8)}~~ \approx 0.004\]となります。相対レートの推定値は、\[dR = 400 \log_{10}(\frac{0.8}{1 - 0.8}) + K \approx 240.8 + K\]であり、その時の標準誤差は\[173.7 \times \frac{0.004}{0.8 (1 - 0.8)} \approx 4.3\]です。系統誤差Kについては、この情報からだけでは何も分かりません。

さて、以上の話は「nが十分に大きい」ということが前提になっていました。しかしながら、「十分に大きい」というのは具体的にどれくらいの大きさなのでしょうか? また、実験の都合により「十分ではないが、それなりに大きい」という場合には、何か別の処理方法があるのでしょうか? 次回は、その辺の話について書きたいと思います。

-------------------

付記:中心極限定理の直感的な証明

以下の証明は直感的なもので厳密ではありません(※積率母関数を用いた弱収束の証明の簡易版です)。厳密な証明は統計学の教科書をご覧ください。

母集団の平均は0、標準偏差は1だとします。これは値の原点とスケールの取り方に対応しますので、一般性を失いません。

サンプル数nの無作為標本\[\{ x_{1}, x_{2}, \cdots, x_{n} \}\]の標本平均を\[M = \sum_{i = 1}^{n} \frac{x_{i}}{n}\]とします。

標本を何度も無作為に作り直す時、標本平均Mの期待値は、\[\big< M \big> = \sum_{i = 1}^{n} \frac{\big< x_{i} \big>}{n} = 0\]となります。ここで、母集団の平均が0であることを利用しました。

さらに、標本平均の2乗の期待値は、\[\big< M^{2} \big> = \sum_{i = 1}^{n} \sum_{j = 1}^{n} \frac{\big< x_{i} x_{j} \big>}{n^{2}} = \sum_{i = 1}^{n} \frac{\big< x_{i}^{2} \big>}{n^{2}} = \frac{1}{n}\]となります。ここで、無作為標本であることから、異なる2つの要素間の相関\[\big< x_{i} x_{j} \big>~~ (i \ne j)\]は0であるとしました。また、母集団の標準偏差が1であることを利用しました。

一般的に、同じ要素のペアだけが消えずに残ることから、m個の要素間の相関について、\[\sum_{i = 1}^{n} \sum_{j = 1}^{n} \sum_{k = 1}^{n} \cdots \sum_{l = 1}^{n} \big< x_{i} x_{j} x_{k} \cdots x_{l} \big>\]\[ = (m - 1) \sum_{i = 1}^{n} \big< x_{i}^{2} \big> \sum_{k = 1}^{n} \cdots \sum_{l = 1}^{n} \big< x_{k} \cdots x_{l} \big> (1 + O(1 / n))\]の分離定理が成立します。ここで、O(1 / n)は(1 / n)以下の項を表しており、具体的には、3つ以上の同じ要素の組み合わせから出てくる寄与のことを指しています。さらに、母集団の標準偏差が1であることから、\[(m - 1) \sum_{i = 1}^{n} \big< x_{i}^{2} \big> \sum_{k = 1}^{n} \cdots \sum_{l = 1}^{n} \big< x_{k} \cdots x_{l} \big> = (m - 1) n \sum_{k = 1}^{n} \cdots \sum_{l = 1}^{n} \big< x_{k} \cdots x_{l} \big>\]となります。

上の段落において、あらゆる異なる要素間の相関がゼロになるという「無作為」を仮定していること、並びに、m個の要素間の相関が発散せずに存在することを仮定していることに注意してください。これらの仮定は意外と自明ではありません。

nが十分に大きいとして、(1 / n)以下の寄与を無視すると、標本平均MのL次の積率\[\big< M^{L} \big>\]は、Lが奇数の時は0となり、Lが偶数の時には、L = 2 lとすると、\[\big< M^{2 l} \big> = \frac{1}{n^{l}} \prod_{j = 1}^{l} (2 j - 1)\]となります。

これらの積率は、確率分布が平均0、分散(1 / n)の正規分布であるとした場合のものと一致するため、nが十分に大きい時には、確率分布が正規分布となることが分かります。■

このページのトップヘ