遊戯王AIプロジェクトの進捗状況です。
以前、カードテキスト分散表現すればより汎用的な状況を理解できるはずだという仮定を述べました。
計算機に遊戯王を理解させる - Just a Note for Hobby
現在はその分散表現を得る機構を、ニューラルネットワーク(NN)で実現させようと四苦八苦しております。
追記(2020/10/04)
もしかして重みの修正法が間違っているのか?、と損失関数から勾配を計算したら実装しているNNのそれとは違う結果になったため、計算結果の式で訓練したら原因がそれだとはっきりしました。。。
その結果が次のグラフです。
1日で解決できたから良かったけど、なんてアホなミスをしてたんだ。。。
実装にあたり
Bag of Words
文書分類NNでは、NNに入力する情報形式も様々な工夫がなされていますが、今回私は最も単純な "Bag of Words"という手法を取りました。
理由は単純、実装が簡単だからです。
"Bag of Words" とは文書内の語を分解して、その全ての語を一つのベクトルに詰め込む手法です。
語を1次元のベクトルに圧縮するため、語の順序情報が失われますが文書分類においてはそのような単純な方法でも上手くいくことがあるそうです。
判別するカード
いきなり遊戯王カード10000種を全て判別するのは難しいと考えたため、以下の採用基準を定めました。
- 魔法・トラップ
- カテゴリーに属さない
- 以下20種の効果のいずれかを有する
そして各効果から10枚ずつ、計200枚を訓練データとして選びました。
詳細はこちら
stopwordの除去
ここからデータの前処理の話になります。
テキストにはそれ単体では意味が広すぎて、カード特定に役立たない単語が含まれます。
本来の意味とは異なりますが、それらを "stopword"と呼ぶことにします。
今回わたしはこれらの語を "stopword" としてテキストから除去しました。
同義語の処理
遊戯王は20年の歴史をもつカードゲームですから、ルール上同じでも表現が異なる場合があります。
"banish" は嘗て "remove from play" でした。
”Warrior-Type monster" と "Warrior monster" は同じ意味ですからそれらも統一します。
割と最近変わった表現としては、”GY"などの省略形が挙げられます。
実装
まだ開発途中で、まとまっていませんがソースをここに置いておきます。
言語はPython3
で、必要な外部ライブラリはnumpy
だけです。
上手く完成したらGitHubに挙げるなり、PyPIにあげるなりしてライブラリとして提供したいです。
- 隠れ層の活性化関数 -
tanh
- 出力層の活性化関数 -
softmax
訓練結果
初めは良くて正答率10%とかで、当てずっぽうも良いところだったんですけど、活性化関数をsigmoid関数からtanh関数に変えたら学習し始めました!
しかし、画像をよく見ると気が付くのですが、正答率が40~50%で頭打ちになっています。
当てずっぽうでもないが、識別しているとは言い難い状況です。
今後の課題
当分の目標は50%の壁を破ることです(過去最高は47%)。
パラメータをいじって調整するのも一つの手ですが、まだ奥の手としてこの単純なNNをRNNに進化させるというのがあるので、じっくり仕上げていきたいです。
※冒頭の追記にも書きましたが、重みの補正式が間違ってました。
自力で計算できるくらいには理解が進んだため、その内記事にしてまとめたいと思います。
OCGの話
そう言えば、久しぶりにOCG(の話題に)触れますと、《ドラグーン》が禁止になったり、《指名者》が一枚減っていたり、《混沌領域》というとんでもない【サンダードラゴン】の初動を貰えたりで呼ばれている気がします。
気はするんですけど、復帰は難しいでしょう。
都心へ向かうための往復3時間が毎日浮いたにも関わらず、やりたい事とやらねばならぬ事を成すのに時間が足らず、時々睡眠時間を削っては睡眠不足でストレスを抱えながら日々を送っている状況です。
私は知っています、メタゲーム調整に莫大な時間が必要なことを。そして、その犠牲となるのは「やらねばならぬ事」である事を(私の性格による)。
何で1日は24時間で、人生は高々100年なんでしょうね。
どっかの株主さんみたいに、1日1時間の睡眠でパフォーマンスが出せるような体であってほしかったです。
そしてカードがありません。
去年の10月以降のカードは皆無です。《原始生命態ニビル》も《冥王結界波》もありません。
むしろ《強欲で金満な壺》は売りたいです。