進行度は、 局面がどれくらい序盤寄りか、中盤寄りか、あるいは終盤寄りかを表す指標である。 Tapered Eval や 評価項目の重み調整に使われる。
同じ特徴量でも、
ということがよくある。
たとえば、
といった具合である。
そのため評価関数では、 局面の進み具合を数値で持っておくと便利である。
コンピュータ将棋では昔から、 進行度に応じて評価関数の重みを変える工夫が行われてきた。
たとえば、
といった切り替えである。
将棋では持ち駒や成りがあるため、 単なる駒数だけで進行度を決めると不自然なことがある。 そのため、より滑らかで局面実態に合う進行度推定が重要になる。
典型的には、大駒や駒数の残り具合から進行度を作る。
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));
}
この推定値を使えば、
をより自然に行える。
将棋では、
があるため、単純な駒数だけでは進行度を測りにくい。
それでも、
を見れば、中盤寄りか終盤寄りかの近似はできる。 ただし、研究的にはロジスティック回帰のような連続推定の方が自然な場合がある。