はじめに
趣旨
こんにちは、最近個人的な勉強としてディープラーニングを始めたtonnyです。
手始めに、O’Reilly Japanさんから出版されているゼロから作るDeep Learningを読みました。
しかし、私自身に知識がなく、いまいちピンとこなかったので、簡単なものを作ってみようと考えました。
とはいえ、せっかくなら自分の趣味でもある麻雀に関わるところで作ろうと考えました。
(以前Qiitaにも同じ記事を投稿しましたが、こちらにも投稿します。)
筆者のスペック
- Python、機械学習ともに初心者
- 普段はPHPやRubyを使ったWebのお仕事
環境
- Python 3.6.0
- bottle 0.12.13
- heroku
機能概要
作成したアプリは下記になります。
https://python-mahjang.herokuapp.com/index
また、ソースコードは下記になります。
https://github.com/naoki85/python_mahjong
- 配牌と結果のみを学習対象としました。
- 配牌を下図のように、かたちで分解し、それぞれの重みから「アガれる」か「アガれない」か出力します。
- あくまで「アガリ」という結果のみなので、役にはこだわっていません。
実装に関して
教師データ
教師データはYoutubeなどでプロの対局を見て、配牌と結果を収集しました。
数としては100いっていないため、これは継続して収集します。
前処理
配牌を以下の3つのノードに分解しています。
- 順子の数(階段並び)
- 対子の数(同じ牌が2枚)
- 暗刻の数(同じ牌が3枚)
各ノードの重みの学習
各ノードの重みはゼロから作るDeep Learningを参考に、勾配法で推定しています。
実際に使ってみた
Youtubeにあがっていたとあるネット麻雀の動画で試してみました。
局 | 結果 | あがれる確率 | あがれない確率 |
---|---|---|---|
東1局 | あがれない | 17% | 83% |
東2局 | あがれない | 29% | 71% |
東3局 | あがれない | 7% | 93% |
東3局1本場 | あがれない | 17% | 83% |
東4局 | あがれない | 33% | 67% |
南1局 | あがれる | 20% | 80% |
南1局1本場 | あがれない | 26% | 74% |
南2局 | あがれない | 17% | 83% |
南3局 | あがれる | 26% | 74% |
南4局 | あがれる | 23% | 77% |
パッと見、ちゃんと予測できているようには見えないです。
よく考えたら、麻雀は4人のうち1人があがれるゲームなので、単純計算でアガれる確率は25%です。
教師データが足りないのかもしれないと思い、とりあえずプロの対局1局分追加してみました。
再テスト
同じ動画で再度試してみました。
アガれない結果のみを比較してみます。
局 | 結果 | あがれる確率 | あがれない確率 |
---|---|---|---|
東1局 | あがれない | 83% | 73% |
東2局 | あがれない | 71% | 64% |
東3局 | あがれない | 93% | 92% |
東3局1本場 | あがれない | 83% | 80% |
東4局 | あがれない | 67% | 72% |
南1局 | あがれる | 80% | 85% |
南1局1本場 | あがれない | 74% | 79% |
南2局 | あがれない | 83% | 80% |
南3局 | あがれる | 74% | 79% |
南4局 | あがれる | 77% | 73% |
10局のうち、6局の「アガれない確率」が下がっています。
やはり、教師データを増やせば結果は変わってくるようです。
学習させた結果から
学習させた重みパラメータは下記になります。
第1要素がアガリへの寄与、第2要素がアガれない方への寄与になります。
1 2 3 4 5 | # 第一要素があがれる方、第二要素があがれない方 # 重み [[ 0.17258578 -0.17396835] # 順子 [ 0.20088727 -0.20564398] # 対子 [-0.33262621 0.34681625]] # 暗刻 |
この結果を見ると、順子、対子はアガリに寄与していますが、暗刻は逆にアガリに寄与していないようです。
暗刻があると手が狭くなるからでしょうか?
バイアスパラメータは下記になります。
すでにアガれない方のバイアスが高すぎます。
1 | [-1.07893278 1.07893278] |
さいごに
課題
現在は下記の2点を課題としてあげて勉強しようと思っています。
- 教師データを増やす
- レイヤーのノードを追加(リャンメン、カンチャン、ペンチャン)の数
今回このWebアプリを作ったのは、教師データを増やす上で入力を楽にしたいためです。
その過程でPythonの軽量FWであるbottleについて学べて良かったと思っています。
やってみての感想
ディープラーニングも学習したてで、何をして良いのかもよく分かっておりません。
(そもそも麻雀という不確定要素の塊を題材にすること自体ナンセンスなのかもしれませんが。。。)
そのため、ご指摘やそもそも間違っているなどのご指導ありましたらコメントをください!
(アドバイスなどもいただけると嬉しく思います。)