2017-09-29(Fri)
前回の続きです。
ニューラルネットで染め手率を予測しようといろいろアルゴリズムとかをいじっています。
まず、パラメータの数値の選定方法として使っている、遺伝アルゴリズムがどうも胡散臭い感じがしたので、そこを疑うことにしました。
次元の数が数万クラス(入力層200前後、中間層200)のものに対して、損失関数の低さ的に優勢なものが生き残りやすい構造にしているとはいえ、基本的によさげなものをしらみつぶし的に調べる方式に近いので、次元のでかさ(パラメータの取り得る幅)に対して十分探索できていないのではないか、という疑惑です。
ちょうどいいところに確率的勾配降下法というのを勉強してなんとか使えそうだったので、そっちに移行することにしました。
こっちなら損失関数の勾配をだんだん下っていく感じなので、全探索的な方法じゃなくていいかなーと思ったので。
ただ微分を計算しないといけなくて、なかなか理論微分値と実測微分値が合わなくて苦労しましたが。
「おぷてぃまいざー」とかいうなんか確率的勾配降下法の中でもいろいろアルゴリズムの種類があるらしかったのですが、「AdaDelta」というものを採用しました。理由はなんか収束が早い部類らしくてわりかしコード書くのが簡単めだったから。後はノリ。
後は、サンプル数の偏り(非染め手の方が10倍くらい多い)があったので、染め手と非染め手の偏微分の計算を1件ずつ交互にする(染め手と非染め手で別のリストを作って全件調べ終わったらまた先頭に戻る)ことでサンプル数をそろえる的なことをやってみました。
ただ、これでもなかなか狙った通りの予測染め手率になってくれませんでした。(かなり上目の数値が出る傾向があった。)
あくまでトータルの損失関数が最小値を取るパラメータ群を求めてるだけなので、必ずしも実際の染め手率とは合わないのかもしれません。
出てきたパラメータを実際の牌譜(訓練データとほぼイコール)に当てはめて、ニューラルネットの関数にぶちこんだものを柱状グラフみたいなので分析してみたのが↓のグラフみたいな感じです。

捨て牌と鳴き方から求めた予測染め手率が45%~50%の間に入ってるのが2426件(全体は1000試合までのデータで113160件)あって、そのうち訓練データの答えが「染め手」と判断した(つまり、終局までの間に手持ち非染め色が1枚以下だった瞬間があった)件数は204件なので、実際に染め手だった割合は8%くらいしかないので、実際と予測がだいぶずれています。
予測と実測はイコールではないけれども、↑のグラフを見るとなんとなく正の相関(線形ではなさそうだけど)があるように見えます。
ためしに予測染め手率と実測染め手率のロジスティック変換(y=log(x/(1-x)))を噛まして散布図を描いてみると…

なんかよくわからんけど、かなり強い正の相関があって、しかも直線で回帰式っぽいものができそうでした。
(実際は各ラベルごとのサンプル数が異なるので、単純に回帰式の公式に当てはめるのはちょっとやばいんですけど、もう勢いでそのままにしちゃった。)
…というわけで、次のような形で染め手率を予測します。
(1)捨て牌と鳴き方を入力値として、確率的勾配降下法で求めたパラメータを使って中間的な予測染め手指数的なのを出す。(ただし、次のステップに渡すのは出力層の活性化関数(シグモイド関数)を噛ます前の値)
(2)回帰直線(1次式)で中間的な予測染め手指数を変換する。
(3)最後にシグモイド関数を噛ませて最終的な予測染め手率とする。
実際の牌譜で確かめてみます。

東ポンで1p8pの切り出し。
マンズとソーズの染め手率が8%ずつ。
捨て牌的にはやや染め手っぽいけど、役牌ポンなのでその点では染め手っぽくない。
なので、両方合わせて16%くらいというのは、そこまで感覚とかけ離れてる、というわけではないように思います。

続いて打発。
字牌なので、染め手っぽさが少し薄れて、予測染め手率4%+4%。これもいいでしょう。

次の例。
789pチーで4m2mの切り出し。相当染め手っぽいけど、予測値は30%くらい。うーん、ちょっと予測値が低いように感じるけど、まぁ役牌後付とか三色一通チャンタ系もあり得るので、著しく不合理まではいかないか。

白ポンで打東。
染め手っぽさはちょっと薄れて10%くらいまで予測染め率が下がる。まぁこれもいいでしょう。
結局のところ、重要なのはシミュレーションでの挙動なので、染め手割合が10%単位で違うということでなければ、まぁそこまで細かく染め手率が1%2%違うからといって、目くじら立てなくてもいいような気がします。
実際、こういう予測染め手割合の求め方をデータ面から一般に出してる人は今のところいないでしょうし、今のところはこれでいいことにしましょう。
なにより、同じテーマでとどまり続けるのに飽きてきました。
なんで、予測染め手率についてはこれでいいとして、次は実際に染め手に向かった者の挙動についてパラメータを取得する作業に移ろうと思います。
ただ、これについてもけっこういろいろ取るべきパラメータの種類は多いです。
単純に今までリーチと副露(+ダマ)のパラメータを取ってたものに新たに染めが加わるに等しいので、今までの作業の半分くらいの分量を新たにやる必要があります。
また、シミュレーションの難易度も染め手かどうかの分岐が入るので、より難しくなります。
まぁ、次の段階に進めただけでもよしとしましょうか。
ニューラルネットで染め手率を予測しようといろいろアルゴリズムとかをいじっています。
まず、パラメータの数値の選定方法として使っている、遺伝アルゴリズムがどうも胡散臭い感じがしたので、そこを疑うことにしました。
次元の数が数万クラス(入力層200前後、中間層200)のものに対して、損失関数の低さ的に優勢なものが生き残りやすい構造にしているとはいえ、基本的によさげなものをしらみつぶし的に調べる方式に近いので、次元のでかさ(パラメータの取り得る幅)に対して十分探索できていないのではないか、という疑惑です。
ちょうどいいところに確率的勾配降下法というのを勉強してなんとか使えそうだったので、そっちに移行することにしました。
こっちなら損失関数の勾配をだんだん下っていく感じなので、全探索的な方法じゃなくていいかなーと思ったので。
ただ微分を計算しないといけなくて、なかなか理論微分値と実測微分値が合わなくて苦労しましたが。
「おぷてぃまいざー」とかいうなんか確率的勾配降下法の中でもいろいろアルゴリズムの種類があるらしかったのですが、「AdaDelta」というものを採用しました。理由はなんか収束が早い部類らしくてわりかしコード書くのが簡単めだったから。後はノリ。
後は、サンプル数の偏り(非染め手の方が10倍くらい多い)があったので、染め手と非染め手の偏微分の計算を1件ずつ交互にする(染め手と非染め手で別のリストを作って全件調べ終わったらまた先頭に戻る)ことでサンプル数をそろえる的なことをやってみました。
ただ、これでもなかなか狙った通りの予測染め手率になってくれませんでした。(かなり上目の数値が出る傾向があった。)
あくまでトータルの損失関数が最小値を取るパラメータ群を求めてるだけなので、必ずしも実際の染め手率とは合わないのかもしれません。
出てきたパラメータを実際の牌譜(訓練データとほぼイコール)に当てはめて、ニューラルネットの関数にぶちこんだものを柱状グラフみたいなので分析してみたのが↓のグラフみたいな感じです。

捨て牌と鳴き方から求めた予測染め手率が45%~50%の間に入ってるのが2426件(全体は1000試合までのデータで113160件)あって、そのうち訓練データの答えが「染め手」と判断した(つまり、終局までの間に手持ち非染め色が1枚以下だった瞬間があった)件数は204件なので、実際に染め手だった割合は8%くらいしかないので、実際と予測がだいぶずれています。
予測と実測はイコールではないけれども、↑のグラフを見るとなんとなく正の相関(線形ではなさそうだけど)があるように見えます。
ためしに予測染め手率と実測染め手率のロジスティック変換(y=log(x/(1-x)))を噛まして散布図を描いてみると…

なんかよくわからんけど、かなり強い正の相関があって、しかも直線で回帰式っぽいものができそうでした。
(実際は各ラベルごとのサンプル数が異なるので、単純に回帰式の公式に当てはめるのはちょっとやばいんですけど、もう勢いでそのままにしちゃった。)
…というわけで、次のような形で染め手率を予測します。
(1)捨て牌と鳴き方を入力値として、確率的勾配降下法で求めたパラメータを使って中間的な予測染め手指数的なのを出す。(ただし、次のステップに渡すのは出力層の活性化関数(シグモイド関数)を噛ます前の値)
(2)回帰直線(1次式)で中間的な予測染め手指数を変換する。
(3)最後にシグモイド関数を噛ませて最終的な予測染め手率とする。
実際の牌譜で確かめてみます。

東ポンで1p8pの切り出し。
マンズとソーズの染め手率が8%ずつ。
捨て牌的にはやや染め手っぽいけど、役牌ポンなのでその点では染め手っぽくない。
なので、両方合わせて16%くらいというのは、そこまで感覚とかけ離れてる、というわけではないように思います。

続いて打発。
字牌なので、染め手っぽさが少し薄れて、予測染め手率4%+4%。これもいいでしょう。

次の例。
789pチーで4m2mの切り出し。相当染め手っぽいけど、予測値は30%くらい。うーん、ちょっと予測値が低いように感じるけど、まぁ役牌後付とか三色一通チャンタ系もあり得るので、著しく不合理まではいかないか。

白ポンで打東。
染め手っぽさはちょっと薄れて10%くらいまで予測染め率が下がる。まぁこれもいいでしょう。
結局のところ、重要なのはシミュレーションでの挙動なので、染め手割合が10%単位で違うということでなければ、まぁそこまで細かく染め手率が1%2%違うからといって、目くじら立てなくてもいいような気がします。
実際、こういう予測染め手割合の求め方をデータ面から一般に出してる人は今のところいないでしょうし、今のところはこれでいいことにしましょう。
なにより、同じテーマでとどまり続けるのに飽きてきました。
なんで、予測染め手率についてはこれでいいとして、次は実際に染め手に向かった者の挙動についてパラメータを取得する作業に移ろうと思います。
ただ、これについてもけっこういろいろ取るべきパラメータの種類は多いです。
単純に今までリーチと副露(+ダマ)のパラメータを取ってたものに新たに染めが加わるに等しいので、今までの作業の半分くらいの分量を新たにやる必要があります。
また、シミュレーションの難易度も染め手かどうかの分岐が入るので、より難しくなります。
まぁ、次の段階に進めただけでもよしとしましょうか。
スポンサーサイト