やってみた。プロ棋士の強さ推定
階層ベイズモデルで勝敗データからプロ棋士の強さを推定する,StatModeling Memorandumという実験があります。大変面白いので私もやってみました。
データ収集
まず将棋のプロ棋士の対局結果を将棋連盟 棋士別成績一覧から収集しました。こちらのサイトは1964年度以降の棋士公式戦対局結果がまとまっています。米長邦雄の四段昇段が1963年、中原誠の四段昇段が1965年です。大昔ですね。素晴らしいですね。以下の方針でスクレイピングしました。
2017年7月30日時点で、対局総数は103849局、棋士総数292人でした。
また、参考用にプロ棋士の生年月日および四段昇段日も収集しました。こちらは将棋連盟のデータベース、将棋順位戦データベース、Wikipediaの個別ページを基にしました。将棋順位戦データベースも暗記したいほどの素晴らしいサイトです。
モデル
Memorandumの記事で使われたモデルのキモは次の2点だと思います。
モデルはBUGS文法で書かれており、とても複雑に見えます。BUGSはStan以上に使い方が分からないので、私はMemorandumのモデルをせめてStanに移植できないかと試行錯誤しましたが、何をどうしてもサンプリング結果が収束しませんでした。残念です。素人には高いハードルでした。
しょうがないのでモデルを変更しました。対局の勝敗は、勝者の勝率pをskill値の差(勝者-敗者)によるロジットモデルで表します。勝率pはそのまま尤度となります。勝負ムラは考慮しません。
このロジットモデルというのは今回初めて知りましたが1、いかにも便利で使い出がありそうですね。
skillの自己相関は下のように定めました。iは年度のインデックスです。sは全棋士全年度で共通としてます。また、これを正しく自己相関と呼んでいいのか、私は知りません。
aが1/400 * log(10)の場合、スキル差と勝率の関係がイロレーティングと同じになります。つまりこのモデルは、棋士のレーティングを自己相関モデルで推定するものです。
完成したStanのモデルです。dataの構造はMemorandumを参考にしています。
model <- " data { int N_kishi; int N_game; int N_year; int Winner[N_game]; int Loser[N_game]; int Year[N_game]; int Career[N_kishi, 2]; } parameters { real i_skill[N_kishi]; real r_skill[N_kishi, N_year-1]; real<lower=0> a; real<lower=0> s; } transformed parameters { real skill[N_kishi, N_year]; real log_p[N_game]; for(k in 1:N_kishi) { for (y in 1:Career[k,1]) skill[k, y] = i_skill[k]; for(y in (Career[k,1]+1):Career[k,2]) skill[k, y] = skill[k, y-1] + r_skill[k, y-1]; for (y in (Career[k,2]+1):N_year) skill[k, y] = skill[k,Career[k,2]]; } for (g in 1:N_game) log_p[g] = log_inv_logit(a * (skill[Winner[g], Year[g]] - skill[Loser[g], Year[g]])); } model { for (k in 1:N_kishi) { target += normal_lpdf(i_skill[k] | 0, 100); for (y in Career[k,1]:(Career[k,2]-1)) target += normal_lpdf(r_skill[k, y] | 0, s); } target += sum(log_p); target += uniform_lpdf(s | 0, 100); } "
モデル中のYearは公式戦準拠で年度単位となっています。スキル値も同様です。 全棋士の初期skillの事前分布は平均ゼロ、分散100の正規分布としました。 skillの自己相関モデルの標準偏差sの事前分布はゼロから100までの一様分布としました。 Careerは四段昇段以前の対局を含んだ、各棋士の実績の開始年度、終了年度のインデックスです。Career前のskillは初期skillと同じ値、Career後のskillはCareer終了年度のskillと同じ値にします。Career外の年度のskillは本来不要なので、サンプリング後に別処理でNAにしました。
サンプリングの実施
skill、a、sを収集対象パラメータとして、iter=12000、warmup=2000、thin=5、chains=4でサンプリングしました。対局結果データは収集した全データを使用しました。とてもものすごく時間がかかりました。よくやったもんです。
結果
Stanが計算してくれるRhatは全パラメータで1.1以下でした。収束したようです。やりました。
a, sの推定結果
skill差にかける係数aの平均は0.00671でした。イロレーティングの係数1/(400 * log(10))=0.0058
と近いと言えるかもしれません。
mean | se_mean | sd | 2.5% | 25% | 50% | 75% | 97.5% | n_eff | Rhat | |
---|---|---|---|---|---|---|---|---|---|---|
a | 0.0067069 | 2.7922e-05 | 0.00044769 | 0.0058647 | 0.0063853 | 0.0066965 | 0.0070188 | 0.0075937 | 257.07 | 1.0092 |
s | 21.6041800 | 1.2963e-01 | 1.92109918 | 18.2457615 | 20.1846688 | 21.5365262 | 22.9048539 | 25.5018467 | 219.62 | 1.0108 |
skill差(レート差)と勝率の関係を可視化しました。イロレーティングとよく似ていますが偶然でしょう。適当に決めた初期スキルなどの事前分布が偶々こうなるような事前分布であった、ということだと思います。
skillの推定結果
skillの推定結果の統計量をこちらに載せています。
佐藤天彦のskill値の事後分布
Rhat的にはskill値はよく収束しているそうですが、安全安心のために事後分布を可視化してみます。実力制第十三代名人 佐藤天彦のskill値を年度ごとchainごとに可視化しました。
上下のヒゲの伸び方に差はありますが、それ以外はchain間の差がほとんど見られません。いい感じです。
全棋士全年度についてskill値の平均値と中央値を比較すると大体同じでした。skill値の平均値と中央値の差の統計量を下に示します。どのskillも釣鐘型の綺麗な分布をしているんじゃないでしょうかと思います。
diff_mean_median Min. :-3.383 1st Qu.:-0.668 Median :-0.222 Mean :-0.269 3rd Qu.: 0.172 Max. : 1.734
以降はskill値の代表値として平均値を使っていきます。
棋士レーティングとの比較
推定された2017年度のskill値(平均と95%区間)と棋士レーティング(2017年7月30日時点)を比較しました。Memorandumでも同様の可視化をしています。どうしても巨大な画像になりますね。
大体整合的ですね。藤井聡太、大橋貴洸、大橋貴洸、杉本和陽の新人四人は95%区間が大きいです。それ以外の棋士の95%区間は大体同じような大きさに見えます。
下表は2017年度のskill値上位20人です。微差ながら藤井聡太が佐藤天彦を抑えて堂々1位となりました。青嶋未来や近藤誠也もskill値では評価高く、まだレーティングが追いついていない状態と言えます。
skill順位 | 名前 | skill平均 | skill95%区間下 | skill95%区間上 | レーティング | レーティング順位 |
---|---|---|---|---|---|---|
1 | 藤井聡太 | 318.15 | 206.71 | 438.42 | 1703 | 32 |
2 | 佐藤天彦 | 317.40 | 243.53 | 397.99 | 1884 | 1 |
3 | 羽生善治 | 315.03 | 243.92 | 394.22 | 1849 | 4 |
4 | 豊島将之 | 313.00 | 240.05 | 390.72 | 1878 | 2 |
5 | 渡辺明 | 288.24 | 213.38 | 367.98 | 1828 | 7 |
6 | 菅井竜也 | 286.98 | 216.12 | 365.51 | 1856 | 3 |
7 | 稲葉陽 | 274.81 | 201.85 | 354.58 | 1837 | 6 |
8 | 久保利明 | 274.77 | 202.91 | 352.13 | 1839 | 5 |
9 | 永瀬拓矢 | 258.59 | 186.67 | 334.47 | 1825 | 8 |
10 | 糸谷哲郎 | 252.53 | 182.40 | 327.20 | 1808 | 9 |
11 | 千田翔太 | 244.15 | 173.17 | 319.49 | 1790 | 11 |
12 | 斎藤慎太郎 | 240.46 | 169.81 | 313.21 | 1801 | 10 |
13 | 佐々木勇気 | 238.27 | 170.34 | 310.52 | 1778 | 13 |
14 | 広瀬章人 | 234.33 | 163.60 | 309.05 | 1780 | 12 |
15 | 山崎隆之 | 229.63 | 160.52 | 304.31 | 1776 | 14 |
16 | 中村太地 | 226.65 | 153.89 | 300.82 | 1775 | 15 |
17 | 三浦弘行 | 224.80 | 151.06 | 303.74 | 1767 | 17 |
18 | 青嶋未来 | 224.12 | 147.35 | 302.01 | 1715 | 26 |
19 | 近藤誠也 | 224.00 | 142.70 | 307.73 | 1701 | 33 |
20 | 松尾歩 | 219.55 | 148.18 | 295.29 | 1766 | 18 |
全棋士のskill値の推移
せっかく50年余りの推定を行ったので、全棋士のskill値の平均の推移をプロットしました。
デカイです。棋士名が重なって見づらいです。個別の棋士の推移を追うことができないですね。
全体の傾向として、どうもskill値の分布の裾が時間経過とともに広がっていることがわかります。 試しに5年単位でskill値の平均のバイオリンプロットを描いてみました。
分布の中心とばらつきが一定だと年度間でのskill値を容易に比較できて大変便利だと思う、のですが。
- 中央値、平均値とも上昇傾向, skill値はインフレしている
- ばらつきも大きくなる傾向があるような気がするが、はっきりしない。1995年付近を境界にしてばらつきが大きくなった=棋力の格差が広がった、ように見える。
これでは、年度をまたいだskillの値そのものの比較はできませんね。具体的に今回のモデルの何が悪いのかは分かりません。
ちなみにイロレーティングもインフレ・デフレするそうです。
歴代のトップ棋士
各年度におけるskill値の順位TOP10を可視化しました。黒丸は公式戦デビュー時点でランクインしたことを示します。黒字のラベルは翌年度にランク外に陥落したことを示します。
大山→中原→羽生と続く棋界の頂点の推移がよくわかりますね。また、中原誠、羽生善治とも、デビュー時で2位にランクインし、すぐに1位に上り詰めています。先程藤井聡太がskill1位すごいすごいと書いたわけですが、確かにすごいが前例はあるのでした。羽生世代やポスト羽生世代には、デビュー即トップ10入りという棋士が結構います。もちろんデビュー直後なので信頼区間の幅も大きいわけですが。
谷川浩司、渡辺明は一度も1位になっていません。これは違和感があります。谷川浩司については、中原以降羽生以前に覇権を握ったイメージがあったのですが、今回のモデルでは、skill上はそのような時代は無かった、となります。
羽生世代が80年代後半にドカドカと現れて、2010年台にドカドカと退場する、世代交代の様が一目瞭然です。羽生善治も2016年度に1位の座を明け渡したようです。レーティングもそんな感じですね。次なる頂点の候補は佐藤天彦、藤井聡太と、最近の若手では珍しくデビュー時点でトップ10入りの菅井竜也でしょうか。私は糸谷哲郎推しですが、この人ポカが多いんですよね。
山田道美、村山聖はトップ10のまま夭折しました(村山聖は最期は休場)。山田道美は山田定跡の考案者ですね。大山康晴相手にタイトルもとりました。棋士番号制定前の棋士であるためか、将棋連盟の棋士データベースには個別ページさえもありません。
TOP10の棋士のスキルはおおむね右肩上がりに上昇しています。その中で羽生善治は、1995年から2010年まで、2位の棋士相手に常に50以上のskill差をつけています。やはり化物ですね。
棋士の全盛期と年齢
棋士の全盛期と年齢の関係を可視化しました。年齢はデータ収集のところで書いた生年月日をもとに、年度ベースの数え歳で計算しました。つまり平成27年度生まれは平成27年度に1歳、という換算になります。
全盛期をskill値そのもので求めるのは危ないので、期歴におけるskill値の年度順位が最高の年度を全盛期としました。例えば羽生善治は15歳から46歳まで1位を32年間維持したので、この間ずっと全盛期という扱いになります。また、この計算で全盛期が年度期間の両端(1964年、1965年、2016年、2017年)となった棋士は、真の全盛期は計算期間の範囲外にあるものと思われるため、除外しました。
棋士全体ではskill値は20代半ばに全盛期が来ることが多いようです。トップ棋士の場合は山がもっとのっぺりしてます。
40過ぎで全盛期が来て(あるいは全盛期を維持して)、それがトップ20以内の棋士は以下になります。花村元司以上は、1963年以前に全盛期があった可能性があると思います。加藤一二三は名人獲得直前が全盛期ですね。加藤一二三は早熟の天才というイメージがありましたが、今回収集したデータの範囲では40歳前後で順位を上げており、実に不思議な棋士です。「大山康晴に苛められすぎたのが中年になって吹っ切れた」と、中原誠が渡辺明との対談で言っていたような記憶があります(たしか将棋世界誌上)。
id | name | 年度 | skill値の平均 | 順位 | 誕生年度 | 年齢 |
---|---|---|---|---|---|---|
1026 | 大山 康晴 | 1966 | 197.1745 | 1 | 1922 | 45 |
1035 | 原田 泰夫 | 1966 | -4.2594 | 19 | 1922 | 45 |
1035 | 原田 泰夫 | 1967 | -5.3930 | 19 | 1922 | 46 |
1039 | 花村 元司 | 1966 | 7.0797 | 16 | 1917 | 50 |
1064 | 加藤 一二三 | 1981 | 131.3172 | 3 | 1939 | 43 |
1085 | 米長 邦雄 | 1982 | 141.3653 | 2 | 1943 | 40 |
1175 | 羽生 善治 | 2009 | 337.4900 | 1 | 1970 | 40 |
1175 | 羽生 善治 | 2010 | 349.6142 | 1 | 1970 | 41 |
1175 | 羽生 善治 | 2011 | 353.2264 | 1 | 1970 | 42 |
1175 | 羽生 善治 | 2012 | 358.3190 | 1 | 1970 | 43 |
1175 | 羽生 善治 | 2013 | 352.0057 | 1 | 1970 | 44 |
1175 | 羽生 善治 | 2014 | 344.3521 | 1 | 1970 | 45 |
1175 | 羽生 善治 | 2015 | 330.5932 | 1 | 1970 | 46 |
1204 | 三浦 弘行 | 2015 | 230.0110 | 13 | 1973 | 43 |
今回のモデルは単純なので、推定されたskillの平均の推移は、1963年からイロレーティングを計算した場合と大きな違いはないと思います。 デビュー直後の棋士の強さを推定できるのことが優位点でしょうか。 モデルにもっと棋士個人差のパラメタを組み込むと面白いと思います。例えばskillの自己相関の標準偏差や、勝負ムラなど。
色々な可視化ができたのは楽しかったです。
おわり。