進行度

進行度は、 局面がどれくらい序盤寄りか、中盤寄りか、あるいは終盤寄りかを表す指標である。 Tapered Eval や 評価項目の重み調整に使われる。

概要

同じ特徴量でも、

  • 中盤では重要
  • 終盤では重要でない

ということがよくある。

たとえば、

  • King Safety は中盤で重い
  • 王の活動性は終盤で重い
  • Mobility も局面段階で意味が変わる

といった具合である。

そのため評価関数では、 局面の進み具合を数値で持っておくと便利である。

将棋での進行度

コンピュータ将棋では昔から、 進行度に応じて評価関数の重みを変える工夫が行われてきた。

たとえば、

  • 序盤では駒組みや囲いを重視する
  • 中盤では King Safety や攻防バランスを重視する
  • 終盤では寄せや王の活動性を重く見る

といった切り替えである。

将棋では持ち駒や成りがあるため、 単なる駒数だけで進行度を決めると不自然なことがある。 そのため、より滑らかで局面実態に合う進行度推定が重要になる。

実装例

典型的には、大駒や駒数の残り具合から進行度を作る。

int gamePhase(const Position& pos) {
    int phase = 0;

    phase += popcount(pos.pieces(ROOK)) * 40;
    phase += popcount(pos.pieces(BISHOP)) * 30;
    phase += popcount(pos.pieces(GOLD)) * 10;
    phase += popcount(pos.pieces(SILVER)) * 10;

    return std::min(256, phase);
}

この値を使って、 Tapered Eval の補間係数や 個別項目の重みを変える。

ロジスティック回帰による推定

将棋の進行度については、 2006年の研究報告「将棋の評価関数を変える進行度の改良」で、 棋譜から進行度を自動調整する方法が提案されている。

公開書誌ではこの論文は 片寄裕 氏の論文として登録されており、 GPW 2006 の英語報告では 「Shogi Takeuchi of the University of Tokyo proposed a method to automatically tune the progress value based on game records」 と要約されている。

この系統の考え方では、 局面特徴 x から進行度 p

p = 1 / (1 + exp(-(w · x + b)))

のようなロジスティック関数で求める。

すると進行度は常に 0 から 1 の範囲に収まり、 序盤から終盤への変化を滑らかに表現しやすい。

double estimateProgress(const FeatureVector& x) {
    double z = dot(weights, x) + bias;
    return 1.0 / (1.0 + std::exp(-z));
}

この推定値を使えば、

  • 中盤評価と終盤評価の混合
  • 各評価項目の重み調整
  • 機械学習ベースの最適化

をより自然に行える。

将棋AIでの位置づけ

将棋では、

  • 成り
  • 持ち駒
  • 玉の入玉や寄せ

があるため、単純な駒数だけでは進行度を測りにくい。

それでも、

  • 大駒が多いか
  • 持ち駒が多いか
  • 盤上戦力がどれだけ残っているか

を見れば、中盤寄りか終盤寄りかの近似はできる。 ただし、研究的にはロジスティック回帰のような連続推定の方が自然な場合がある。

注意点

  • 定義が単純すぎると局面段階をうまく表せない
  • 将棋では持ち駒の影響が大きい
  • 進行度推定に使う特徴が悪いと、局面実態とずれた重み切り替えになる

関連項目

参考にしたホームページ