流行りの機械学習をフル活用して棋力スカウター開発してみた話(後編)

歴代の名人と今の名人はどちらが強いのか。将棋が強くなる上で必要な力は何であるか。女流棋士は此処数年でどのぐらい強くなったのか。アマチュアトップとプロの実力差はどのぐらいなのか。

前回に引き続きこの壮大な問に挑戦するべく、棋力スカウターの開発をしていきます。今回はKaggleなどで使われる技術をフル活用して回帰精度を上げていきます。今回用いた技術の大半は以下の書籍から学ぶことが出来ます。実際お勧め。

【前回までの進捗】
前回までの進捗を簡単に纏めると以下のようになります。

・人間の棋譜と各局面での評価値をやねうら王で計算したものから対局者のレーティングをあてるのが目標
・先行研究で使われていた、最善手と実際の指し手の評価値の差分の平均値からレートを計算する機能を実装
・評価値の差分の平均値とレートの間に強い相関があることを再現
・一方、1局毎の評価値差分の平均は人によってブレが大きいことを確認。特に相手が勝手に自滅した場合にフタコブになってしまう
・評価値の差分ではなく、評価値から計算される勝率の差分を指標にするのは良くないことがわかった

qhapaq.hatenablog.com

この面倒な問題に流行りの機械学習技術をフル活用すると果たしてどうなるのでしょうか。


【今回の棋力測定戦略】
今回は「局面毎にレートを推定し、各種モデルのアンサンブルを取って最終予想とする」という戦略を用います。

教師データとしてプレイヤーの棋譜を見た場合、プレイヤーによって棋譜の数が変わり、更に、棋譜によって手数が変わります。可変長のデータを扱う方法としては、RNNなどの自然言語処理向けの技術が知られていますが、これらの手法は往々にして計算量が多く、今回のような教師データが少ない系にはあまり適していません。

そのため、前回紹介した評価値差分平均と同様に、局面毎に手の質を計算しその平均からレートを計算することにします。手の質は色々な評価方法が考えられますが、ここでは評価値の分布から指し手のレートを予測する問題を教師あり学習で解かせて、レートの予測値を手の質とみなすことにします。回帰モデルには機械学習コンペでよく用いられる勾配ブースティング(XGBoost、NGBoost)とニューラルネットワークの二つを用いました。

最終的なレートは各種モデルが予測したレートの合議で決定します。合議の方法についても勾配ブースティングによる教師あり学習を用いました。

全体の学習の流れは以下のようになります。

f:id:qhapaq:20200301192659p:plain
棋力スカウターの学習フロー


【各種モデルの回帰結果】
以下に各種モデルの回帰結果を紹介します。

【XGBoost】

f:id:qhapaq:20200304083045p:plain
xgboostによる棋力予想。横軸がレート(右ほど強い)、縦軸が棋力(上ほど強い)

f:id:qhapaq:20200304083608g:plain
図面上部に書かれているのが正しいレート、横軸が1つの対局から予測されたレート、縦軸がその分布

グリッドサーチでハイパラチューニングをしたり、考慮に入れる手の順位を弄ったりしましたが、予測精度には殆ど差は出ませんでした。評価値差分のときに比べフタコブが大分緩和されているのが解ります。どこをみてコブを消したのかが凄く知りたいですが、勾配ブースティングの判断基準の可視化って難しい。

【NGBoost】
NGBoostは予測の不確かさも同時に出力できる、新型の勾配ブースティングです。かの有名なAndrew Ngも開発に絡んでいるのでこの名前になっているようです。中身の概要を知りたい人にはAI Scholarの記事がおすすめです。

挙動としてはXGBoostとほぼ同じです。NGBoostにはweightの調整機能などの気の利いた処理がないにもかかわらずXGBoostに比べても悪くない結果が出ています。不確かさが出るのも用途によってはものすごく便利でしょう。


f:id:qhapaq:20200304084237p:plain
横軸が実際のレート、縦軸が棋力 in NGBoost

f:id:qhapaq:20200304084402g:plain
図面上部に書かれているのが正しいレート、横軸が1つの対局から予測されたレート、縦軸がその分布

ニューラルネット
MSEという観点ではニューラルネットが一番いいスコアが出ていました。

f:id:qhapaq:20200304084537p:plain
ニューラルネットによる棋力予想 横軸が実際のレート、縦軸が予測された棋力

やはり、フタコブはある程度解消されています

f:id:qhapaq:20200304084716g:plain
図面上部に書かれているのが正しいレート、横軸が1つの対局から予測されたレート、縦軸がその分布


【アンサンブル】
今まで作ったモデルをよく眺めると、モデルによって一長一短があることが解ります。例えば、レート上位層の予測については単純な評価値差分が良いように見えますし、フタコブをなくすという意味では勾配ブースティング系が良さそうです。そして、単純なmseではニューラルネットが良さそうです。

そこで、これらの意見のいいとこ取りをするために、各種モデルの予測値をあつめ、これらを合議することで最終的なレートを予測し直すことを考えます。Kagglerにとってはおなじみの合議です。

まずは単純な線形足し合わせ。フタコブがかなり解消され滑らかになっているのが解ります。

f:id:qhapaq:20200304090924g:plain
図面上部に書かれているのが正しいレート、横軸が1つの対局から予測されたレート、縦軸がその分布

XGBoostを使って回帰した場合。更にピークがシャープになっています。

f:id:qhapaq:20200304090957g:plain
図面上部に書かれているのが正しいレート、横軸が1つの対局から予測されたレート、縦軸がその分布


棋力の予測値が全体的に2000によっているのが気になる(二乗誤差を基準にしたのが悪い)ので、実際にレートを予測する場合は「予測値*3 - 4000」みたいな式を挟む必要があるでしょう(二乗誤差よりも優れた評価関数があればもっと精度は上がるのでしょうけど、あまりそのへん詳しくないので詳しい人良ければ教えてください

【まとめと課題】
棋譜の特徴量抽出+各種非線形モデリング+アンサンブルというKaggleでおなじみの技法をフル活用して棋力スカウターを作ってみました。モデルを増やしアンサンブルを取ることで予測精度が向上することが確認できました。未解決の課題としては以下のようなものがあります。

・本当に過学習していないかを確認する
・プロ棋士やコンピュータなど教師データよりも強いプレイヤーの棋力を見積もれるか


【次回予告?】
スカウターの骨組みが完成したので、これを使ってプロ棋士やコンピュータの棋譜を解析していきます。冒頭で述べたような壮大な問は解けるのか....ご期待ください!