・±3000を超えた評価値は端に張り付いて変化が不明になる
・±500以内などの狭い範囲の変化が読み取りづらい
といった事があり、以下のような関数を縦軸にのみ適用する、似非片対数グラフ的な表示方法を提案します。
y = (2/π) * arcsin( (2/π) * arctan( (π*π/4800) * eval_value ) )
※ (π*π/4800)の部分の定数値は、好みに応じて 0.001~0.005 程度の値にしても良いかと思います。今回は、評価関数の学習時に評価値を勝率[-1,1]に変換する曲線 y = tanh(eval_value / 1200.0) = 2.0 / (1.0 + exp(-eval_value / 600.0)) - 1.0 と原点での傾きが一致する定数として、(π*π/4800)を提案しました。
https://github.com/yaneurao/YaneuraOu/b ... r.cpp#L740
コード: 全て選択
y | eval_value
------+------------
-1.000| -∞
-0.950| -99999
-0.841| -9999
-0.748| -2000
-0.504| -1000
-0.340| -500
-0.289| -400
-0.329| -300
-0.160| -200
-0.082| -100
0.000| +0
+0.001| +1.2
+0.010| +12
+0.082| +100
+0.100| +120.402
+0.160| +200
+0.229| +300
+0.289| +400
+0.340| +500
+0.383| +600
+0.420| +700
+0.452| +800
+0.480| +900
+0.500| +981.432
+0.504| +1000
+0.645| +2000
+0.748| +4000
+0.841| +9999
+0.950| +99999
+1.000| +∞
グラフ表示例: (ShogiDroid/ShogiGUIに適用する際はこの例とは逆に、グラフの上が先手有利(+)になるようにした方が良いかと思います)
https://lab.mzr.jp/shogi/eval.png
関数の入出力値の参考:
https://www.desmos.com/calculator/01gwhrwzsj
擬似コード:
コード: 全て選択
// begin pseudocode
double eval_nonlinear(double x) {
// (-∞,+∞) の範囲の評価値を [-1,+1] の範囲の値に非線形的に変換する
double a = 0.0020561675835602830455905189583075; // ( = π*π/4800 )
double b = 0.63661977236758134307553505349006; // ( = 2/π )
return std::max<double>(std::min<double>(b * std::asin<double>(std::max<double>(std::min<double>(b * std::atan<double>(a * x), 1.0), -1.0)), 1.0), -1.0);
}
double eval_linear(double x) {
// [-3000,+3000] の範囲の評価値を [-1,+1] の範囲の値に線形的に変換する
return std::max<double>(std::min<double>(x / 3000.0, +1.0), -1.0);
}
// end pseudocode
太目盛線の例:
±0, ±500, ±1000, ±9999, ±99999
細目盛線の例:
±100, ±200, ±300, ±400, ±600, ±700, ±800, ±900,
±2000, ±3000, ±4000, ±5000, ±6000, ±7000, ±8000, ±9000
グラフの縦方向の長さが文字サイズに較べて短い場合(ShogiDroid)、優先しない値ラベルは文字が重ならないよう一部省略するようにすると良いかもしれません。
大サイズ時値ラベルの例:
±0, ±100, ±200, ±500, ±1000, ±2000, ±9999, ±99999, (±∞)
小サイズ時値ラベルの例:
±0, (±100), (±200), (±500), ±1000, (±2000), ±9999, (±99999), (±∞)