機械学習でウーラオスの型を判別する
はじめに
「機械学習を使ってポケモン対戦に勝ちたい!」
そんな願いを胸に取り組んだ試みの、第一歩をご紹介します。
対戦相手が使ってくるポケモン「ウーラオス」の型を、コンピュータの力で事前に判別することで、情報アドバンテージ優位を狙います。
📝本記事は、ポケモン ソード・シールドのランクバトル(シングル)での対戦を前提としています。
🔰ポケモンについての前提知識
ポケモン対戦では、お互いに手持ちポケモン6匹を見せ合い、それを判断材料として、対戦に出すポケモン3匹を選出します。
見せ合い時に分かる相手の情報は、ポケモンのドットアイコン、性別のみです。(性別の違いは、対戦にはほぼ影響しません。)
「ウーラオス」は多くのプレイヤーに愛用される、トップクラスに強力なポケモン。そしてこのポケモンは、タイプが かくとう/あく である「一撃の型」と、かくとう/みず である「連撃の型」の2つの型が存在します。
ウーラオスについての詳細は、公式サイトをチェックしてみてください。
🔗ウーラオス|『ポケットモンスター ソード・シールド エキスパンションパス』公式サイト
"一撃" "連撃" 2つの型はドットアイコンが同一であり、相手がどちらの型を使っているのかを、手持ちポケモンの見せ合い時に判別することはできません。
ポーカーで相手の手札を見られたほうが有利なように、相手のウーラオスの型を事前に知ることは、ポケモン対戦を有利に進めるのに役立ちます。
今回はプレイヤーのセンスに頼るのではなく、機械学習を使って統計的、論理的に型を判別してみようと思います。
👩🍳機械学習の手法
機械学習とは、コンピュータにお手本を教え込ませ(学習)、その後に与えたテストで良い点を取らせる(予測)もの。
一口に機械学習と言っても、その手法はいくつもあります。料理をする人によって得意分野、味付けの傾向が異なるように、選ぶ手法によって得られる結果は様々です。
今回僕が選んだ機械学習の手法は「ロジスティック回帰」というもの。理由は学生時代に扱った経験があり、勝手を知っているためです。(本来は手法の選定から行うべきですが、時間がなかったので……。)
「ロジスティック回帰」は分類手法の一種。適切な材料を与えることで、お客さんが商品を買うか買わないか、これから庭に咲く花が赤か青か、診察した患者がガンか否かを予測することができます。この要領で、相手のウーラオスが "一撃" か "連撃" かを予測してもらいましょう。
🥕機械学習の材料集め
機械 "学習" という名のとおり、学習させるための材料(=学習データ)は必須です。売上を予測したいなら、店舗の場所や客層など、ガンを予測したいなら、患者の年齢や病歴などが材料となります。
今回は「手持ちポケモンの見せ合い時に判別する」ことを目指しているため、使える材料は限られています。前述のとおり、見せ合い時に分かる情報はポケモンのドットアイコン(と性別)のみだからです。これが今回の試みの厳しいポイント。一般的に、材料の種類は多いほうが有利であるため、ハードモードといえるでしょう。
材料として、「ウーラオス入りの手持ちポケモン情報(以下、「パーティ」と言い換え)のうち、ウーラオスの型が判明しているもの」を以下から収集しました。
・自分が対戦した相手の記録
・「ぽけっとふぁんくしょん!」(プレイヤーが使ったパーティをまとめたサイト)の情報
・YouTubeに上がっている対戦動画
手元に収集できた合計は、約400パーティです。
▼スマホに保存された、大量のパーティ写真たち
🔪機械学習の材料処理
収集したパーティ情報を、そのままコンピュータに読み込ませるのは効率的ではありません。機械学習に使うための情報である「特徴量」を切り出す工程が必要です。
カレーを作るときに人参(材料)をそのまま鍋に入れるのではなく、洗って皮をむいて切る工程を挟んだほうが、より美味しいものが作れると思います。特徴量の切り出しは、それと同じイメージです。
そして、この特徴量の質によって、機械学習の結果は左右されます。
今回僕が用意した特徴量は、「ポケモンの使用有無ベクトル」と、「攻めのタイプ相性ポイント」の2つです。?・。・?だと思うので、順にご説明します。
特徴量その1:ポケモンの使用有無ベクトル
ウーラオスの型によって、一緒にパーティに入っているポケモンの傾向に違いがあるだろうという予測を立て、単純にポケモンの採用有無をチェックします。
収集した400パーティに入っているポケモンを集計し、パーティごとに「そのポケモンが入っているか」を一覧化します。
パーティ1: サンダー、エースバーン、ミミッキュ、ランドロス、カプレヒレ (+ウーラオス)
パーティ2: ドサイドン、ナットレイ、エースバーン、サンダー、ポリゴン2 (+ウーラオス)
---
サンダー エースバーン ミミッキュ ランドロス カプレヒレ ドサイドン ナットレイ ...
パーティ1: o o o o o x x
パーティ2: o o x x x o o
コンピュータが扱いやすいように数値化(o→1、x→0)して、まとめれば立派な「ベクトル」です。これが特徴量の1つ目。
パーティ1: ([1,1,1,1,1,0,0,...])
パーティ2: ([1,1,0,0,0,1,1,...])
📝ポケモン名の一覧をテキストデータとして扱い、パーティごとにBag of Wordsベクトル化しています。
特徴量その2:攻めのタイプ相性ポイント
パーティ全体を見て、例えばゴーストタイプのポケモンへの攻撃手段に乏しい場合、それに強い "一撃" ウーラオスが、じめんタイプのポケモンへの攻撃手段に乏しい場合、それに強い "連撃" ウーラオスが採用されやすいだろうと考えました。
同じように、使用率の高いポケモンへのタイプ相性をチェックすることで、特徴量として使えるかもしれません。
ということで、「パーティに含まれるポケモンの、使用率40位以内のポケモンに対する攻めのタイプ相性」を記録します。例えばウーラオスの他に「ほのお、みず、くさ」タイプのポケモンが採用されている場合は、以下のように記録します。
(抜群なら+1, 等倍なら0, 半減なら-1のように変換している)
サンダー エースバーン ミミッキュ ランドロス カプレヒレ ポリゴン2 ドラパルト ...
ほのお: 0 -1 0 0 -1 0 -1
みず : 0 +1 0 +1 -1 0 -1
くさ : -1 -1 0 0 +1 0 -1
上記の和: -1 -1 0 +1 -1 0 -3
パーティ単位で加算すれば、特徴量の2つ目の完成です。
このパーティは、タイプが ドラゴン/ゴースト である「ドラパルト」への攻撃手段に乏しいようですが、どちらのウーラオスが採用されやすいでしょうか?
🍛機械学習の結果
さて、手法を決め、材料を集め、特徴量を切り出した今、実際に機械学習を実行してみましょう。未知のパーティ情報を与えた場合の、予測精度を測ります。
(predict_urshifu_style.py 内)
# ロジスティック回帰モデルのインスタンスを作成
logreg = LogisticRegression(C=1, max_iter=450)
# 学習データを用いた交差検定のスコアを測定
scores = cross_val_score(logreg, concatenated_X_train, y_train, cv=5)
print('交差検定での精度(accuracy): {:.2f}'.format(np.mean(scores)))
$ python predict_urshifu_style.py
交差検定での精度(accuracy): 0.72
予測精度は 72%。悪くはないけど、良くもない。わざ「トリプルアクセル」が3連続で当たる確率と同じです。シーズン(対戦ランキング集計期間)がもっと長ければ、改善の時間も取れたでしょう。(血涙)(言い訳)
ということで、「72%の確率で、見せ合い時に相手のウーラオスを正しく判別するプログラム」がここに完成しました。
📝精度を上げるために必要なアプローチとしては、以下が挙げられます。
・学習データの数を増やす
・選出画面から得られる特徴量をさらに検討する
・特徴量を適切にスケール変換する
・モデルやパラメータを色々試す
💥機械学習を使った対戦
さっそく、作成したプログラムを携えてランクバトルに参戦しましょう。
対戦相手が見つかりました。相手のパーティには……ウーラオスがいる!
ウーラオスを除く相手のポケモン5匹をパソコンに入力していきます。見せ合い時間は90秒。急げ!
(X_test.txt 内)
"サンダー ポリゴン2 ドヒドイデ ランドロス霊 ヒードラン"
入力が終わり、作ったプログラムを実行します。
結果は……?
(predict_urshifu_style.py 内)
# テストデータを分類予測
logreg.fit(concatenated_X_train, y_train)
y_pred = logreg.predict(concatenated_X_test)
# 分類予測の結果を表示
if y_pred[0] == '0':
pred_result = '一撃の型(悪)'
else:
pred_result = '連撃の型(水)'
print('テストデータに対する予測結果: {}'.format(pred_result))
$ python predict_urshifu_style.py
テストデータに対する予測結果: 連撃の型(水)
プログラムは、相手のウーラオスを「連撃の型(かくとう/みず)」と予測したようです。相手のパーティにあくタイプがいないことが分かったので、無効化されない強力なエスパーわざ「アシストパワー」を覚えたクレセリアで無双しましょう!
おわりに
僕はセンスで以て対戦を勝ちきれない、強くないプレイヤーなので、機械学習の力で勝つことを目的に、今回の試みを実施しました。
ポケモン対戦で勝つための新しいアプローチは様々あると思いますので、ぜひ皆さんも模索して、共有してください!
機械学習についてめちゃくちゃ嚙み砕いて記述しましたが、なんとなく「面白そうだな~」くらいのニュアンスを伝えることができていれば嬉しいです。
ポケモンプレイヤー向けの余談
これを実施したシーズン20、気になる僕の最終順位は1,200位くらいでした。(は?)
機械学習の力で、すべての "連撃" ウーラオス入りに勝てた感覚がありますが、ウーラオスを採用していない相手(7割ほど)とは単純な実力だけの対戦です。機械学習くんは強かった(?)が僕が弱かった。精進します……。
次の記事を書きながら食べるアイス代にします🍧