備忘録 blog

Docker/Machine Learning/Linux

先後差を考慮した将棋のプロ棋士の強さモデリング(2)

はじめに

本稿は前回に引き続き、先後差を考慮したプロ棋士の強さベイズモデリングをしていきたい。今回は棋士ごとの先手・後手の差をモデルに埋め込んで、先後の強さの差がどのぐらい出るかというのをみていきたい。

前回の記事はこちら。

sharply.hatenablog.com

ローカルな先手後手の差をモデルに埋め込んだモデル

このモデルでは、ローカルな先手後手の差、即ち各棋士ごとに先手後手のムラがあると仮定して、そのムラがどのぐらい強く出るか、というのを棋士ごとにみていきたい。モデルの中身は以下である。

  • 棋士の強さをμ、実力のムラをσとして、対局時の実力を normal(μ, σ) として定める。
    • 棋士の強さμの分散(すなわち正規分布の分散)の事前分布を一様分布として定める。
  • 実力が高いほうが対局に勝利する。具体的には、実力の差をシグモイド変換した確率値 p に対して、 その確率 p で 1 が出るような試行であったとモデリングする(ベルヌーイ分布)。
    • この時に、実力の差に対して、棋士ごとに先手勝ちの場合に δ、後手勝ちの場合に -δ の補正を加える。この補正項によって、棋士ごとの先手・後手の得意・不得意を扱って解析することができる。
      • この δ は平均0の正規分布に従う(その正規分布から各棋士ごと値が選ばれる)というようにここではモデリングする。この制約により、全体の平均が0に収束することを期待している。
with pm.Model() as model:
    # prior
    s_mu = pm.Uniform('s_mu',upper=300)
    mu = pm.Normal('mu', mu=0, sd=s_mu, shape=len_players)
    sigma = pm.Gamma('sigma', alpha=10, beta=10, shape=len_players)
    delta = pm.Normal('delta', mu=0, shape=len_players)

    loser_perf = pm.Normal('loser_perf', mu=mu[battles.Loser-1], sd=sigma[battles.Loser-1], shape=len(battles))
    winner_perf = pm.Normal('winner_perf', mu=mu[battles.Winner-1], sd=sigma[battles.Winner-1], shape=len(battles))
    sente_perf = pm.Normal('sente_perf', mu=delta[battles.Winner-1] * battles.FirstWin, shape=len(battles)) #sp * battles.FirstWin
    gote_perf = pm.Normal('gote_perf', mu=delta[battles.Loser-1] * battles.FirstWin, shape=len(battles)) 
     
    diff = winner_perf-loser_perf + sente_perf + gote_perf
    #p = pm.math.switch(diff, 1.0, 0.0)
    p = pm.math.sigmoid(diff)
    z = pm.Bernoulli('z', p=p, observed=np.ones(len(battles)))
pm.traceplot(trace, var_names=['mu','sigma','delta'])

f:id:sharply:20220225165940p:plain

棋士の先後ムラの平均(大きい順=先手の方が強い棋士

mean sd hdi_3% hdi_97% mcse_mean mcse_sd ess_bulk ess_tail r_hat
藤森哲也 1.303 0.613 0.187 2.504 0.038 0.027 256 521 1.01
村中秀史 1.244 0.624 0.116 2.396 0.051 0.036 150 367 1.02
青嶋未来 1.24 0.537 0.254 2.264 0.031 0.022 300 449 1.01
都成竜馬 1.207 0.551 0.162 2.178 0.034 0.024 258 746 1.01
上村亘 1.163 0.588 0.107 2.341 0.032 0.023 337 692 1.01

棋士の先後ムラの平均(絶対値が小さい順=先後ムラが少ない棋士

ここで示している棋士は、先後による勝率の差が少ない棋士であるといえるだろう。

mean sd hdi_3% hdi_97% mcse_mean mcse_sd ess_bulk ess_tail r_hat
橋本崇載 0 1.008 1.931 1.843 0.013 0.02 5706 2127 1
今泉健司 0 0.564 0.99 1.121 0.036 0.026 240 636 1
小林健 0.002 0.845 1.609 1.531 0.043 0.031 378 771 1
長岡裕也 0.004 0.509 0.928 0.987 0.032 0.022 262 719 1.02
阪口悟 0.005 0.619 1.176 1.106 0.032 0.023 364 758 1
小林宏 0.006 0.771 1.456 1.415 0.036 0.025 461 917 1
小林裕士 0.01 0.56 1.061 1.072 0.035 0.025 257 680 1.02
平藤真吾 0.016 0.607 1.05 1.212 0.036 0.026 280 745 1.01
中村太地 0.024 0.565 0.994 1.082 0.029 0.021 374 675 1.01
屋敷伸之 0.027 0.596 1.125 1.115 0.037 0.026 267 593 1.01

棋士の先後ムラの平均(小さい順=後手の方が強い棋士

mean sd hdi_3% hdi_97% mcse_mean mcse_sd ess_bulk ess_tail r_hat
山本博 -1.604 0.577 -2.657 -0.543 0.038 0.027 233 683 1
川上猛 -1.162 0.742 -2.67 0.166 0.037 0.026 402 725 1
冨田誠也 -1.011 0.585 -2.091 0.089 0.041 0.029 209 386 1.01
窪田義行 -0.93 0.584 -2.034 0.162 0.039 0.028 226 504 1
森悠 -0.81 0.581 -2.002 0.197 0.039 0.028 217 505 1
稲葉陽 -0.806 0.571 -1.849 0.23 0.036 0.026 249 468 1
飯島栄治 -0.717 0.542 -1.722 0.237 0.031 0.022 312 702 1
羽生善治 -0.711 0.487 -1.615 0.215 0.026 0.018 351 585 1
勝又清和 -0.706 0.661 -1.93 0.557 0.035 0.025 358 569 1
田中寅彦 -0.688 0.749 -2.077 0.702 0.069 0.049 118 371 1.03

考察

これらの結果は、2021 年における先手勝率・後手勝率と照らし合わせても概ね妥当である。

kenyu1234.php.xdomain.jp

だとすると単純に先後の勝率だけを比較すれば良いではないか、という意見もあるかもしれないが、このモデルでは対戦相手の強さについてもパラメーターに含めているため、対戦相手の強さも考慮しながら、先後の勝率を補正して計算していると考えられるので、こちらのモデルによる検証も意味があるといえるだろう。

この結果から興味深い点は、後手の方が強い棋士として挙げられている棋士では、特にTop5に振り飛車党が多いといえる。

https://shogidata.info/list/strategrylist_junni.html

この中から居飛車党・オールラウンダー・振り飛車党を括り出して、それぞれどのような特徴を持っているのか調べるということも、今後の課題となりそうだ。

また、統計解析については、独学で行なっているため、補正項の扱い方が適切ではない虞がある。もし良いアイディアがあれば、コメントをいただけると幸いである。

参考文献

gaiasky.hatenablog.com