今回の目標
前回行った遺伝的アルゴリズムについて、考察を行いたいと思います。
記事をためずにすぐ考察に入るのは機械学習の時の反省を活かしてのことです。
なお今回の記事では新たな実験などは行わず、あくまでデータ解析と考察に専念し、改善案を挙げるだけで終了します。
ここから本編
Pythonを用いて、それぞれの思考結果のデータを集めました(data.py)。
以下に示すのは、それぞれの世代での勝利回数の平均と分散です。
データ数は上から順に100、1000、100です。
※globを使ったので、前回と違う順番でデータが計算されています。
なお1世代ごとの試合回数は30回なので、どの方法でも平均で勝ち越していることが分かります。
data_1hand_1hand.csv :
mean: 19.07
var: 12.914242424242424
data_1hand_rand.csv :
mean: 20.953
var: 6.87967067067067
data_2hand_rand.csv :
mean: 20.4
var: 9.474747474747474
run_1hand_randとrun_2hand_rand
上のグラフは前回も掲載したもので、それぞれrun_1hand_rand及びrun_2hand_randの世代数と勝利回数です。
どちらもほとんど学習が進んでおらず、勝率は向上していません。
機械学習の時と異なり、相手がランダムに打ってきた場合に対処法が確立されないため学習が進まないのではないかと考えました。
ただ一つ気になるのは、平均で勝ち越していることです。評価値はランダムで決定しているため、コンピュータ側も最初はランダムに置いているのと変わりありません。にもかかわらず勝ち越している理由として以下が考えられます。
- 少しは学習している
- たまたまである
「少しは学習している」について、とてもそうは見えませんがこの可能性を考えました。理由としては、プレイヤー役の思考方法が一定であるのに対し、コンピュータの思考は変動するからです。
ということでrun_1hand_randについて数世代ごとの平均勝率でグラフを作り直してみました(graph.py)。2handの方はデータ数が少ないため正しい傾向がつかめないと考え作りませんでした。
その結果は以下の通りです。
グラフタイトルに書いている数字が平均に用いるデータ数で、例えば一番上のグラフでは10世代ごとに勝利数を平均しています。
あまりこの説は正しくないようです。
「たまたまである」について、実は今回すべてのプログラムにおいて、srandの引数を0で固定しています。
この0という数字が、たまたまコンピュータ側に有利に働きやすい設定だったのでは? と考えられます。
これについては他の記事で検証したいと思います。
run_1hand_1hand
上のグラフは前回も掲載したものです。
他の二つと違い、これについては比較的上手く行きました。
理由として考えられるのは、ランダムとの対戦の時とは逆に、1hand対策が進んだからといえるでしょう。
一見、学習後の評価値は全く学習していないように見えましたが、実は1handに対抗する上での最適解があの値に近いのではないでしょうか。
序盤の勝率は他の手法と比べ低いですが、プレイヤー役がランダムから普通の1handになったことで強化されたことが理由だと思います。
そもそも、考案したアルゴリズムは正しかった?
最大の疑問がこれです。
進化手法について、ここでは一般的な交叉ではなくランダムに引き継ぐ方法を考えました。しかしこれが本当に最適解だったのかは疑問が残ります。理由は単純に他の人が誰もこの進化方法を採用していないからです。
それ以外にも改善点、疑問点はいくつかあります。
- コンピュータとプレイヤーで、「何手先まで読むかの値」を変えられない
- (本質ではないが)「static_cast」の回数が多くて見づらい
- 突然変異の確率は正しかったのか?
まとめ
次回以降検証すべきことは以下の通りです。
- srandの引数を変えながら実験
- 進化手法を変えながら実験
- 思考方法を、それぞれが何手先まで読むか? まで変えながら実験
- 突然変異の確率を変えながら実験
フルバージョン
considerationフォルダ内に入っています。
実際にやってみた
やってないです
次回は
機械学習の考察で示した改善案は、下積み編が終了次第実践していきたいと思います。
次回以降はまとめに示した実験を進めていきます。