強化学習:モンテカルロとQ-Learningの実装

1から順に交互に数字を言って10を言えた方が勝ちのゲームを考えます。プレイヤーは2人です。1ターンで数字は1つか2つ言えます。このゲームは勝ちパターンがあるゲームです。その勝ちパターンさえ把握していれば先行は勝ち続けることができます。

 

このゲームをプレイする、人間プレイヤー、ランダムプレイヤー、モンテカルロプレイヤー、Q-learningプレイヤーを実装することを目的とします。DQNも実装しようとしましたが、勾配の計算がうまくいかずnanが出てしまうので諦めました。

 

モンテカルロ法について説明します。モンテカルロ法とはある状態における行動を評価する方法です。自分がその行動をとったとして、そのまま最後までランダムプレイヤー同士にゲームを進めさせ、勝ったか負けたか記録します。これを何回も行い、勝率を計算して、その行動を評価するということです。

 

Q-learningについて説明します。Q-learningもある状態における行動を評価する方法です。それをQ関数を用いて計算する方法です。詳しくは、以下のリンクを見てください。Q-learningの実装にあたって、このリンクを参考にしました。

 

qiita.com

 

実装するプレイヤーは以下の4つになります。

 

1:人間プレイヤー:人が手動でキーボードから入力します

2:ランダムプレイヤー:完全にランダムで選択します

3:モンテカルロプレイヤー:モンテカルロ法で学習します

4:Q-learningプレイヤー:Q-learningで学習します

 

説明する順番についてです。

 

1:環境の設定

2:ランダムプレイヤー、人間プレイヤー

3:モンテカルロプレイヤー

4:Q-learningプレイヤー

5:結果確認

 

この5ステップで説明します。

 

作成したプログラムは全てgithubに全て上げてあります。

github.com

 

   1:環境の設定

ゲーム自体を定義するclass:Gameとゲームを進行させるclass:Organizerを作ります。Gameは基本的にOrganizerから呼び出されて使われます。Gameは勝利判定、状態更新、選択肢表示などをします。Organizerはプレイヤー管理とゲーム進行です。

プレイヤーは1、2のいずれかの数字を出力して、行動します。これを行うのは関数actとします。1は2数選択、2は1数選択に対応します。

 

ゲームの流れを説明します。Organizerがplayerのインスタンスを引数にインスタンスを生成されてゲーム準備完了です。Organizer.progressが実行されることで、ゲームが開始します。progressは内部でGameのインスタンスを生成します。後は、状態をもとにプレイヤーが行動し、勝利判定して、状態更新して、次のプレイヤーが行動する、これの繰り返しです。

 

environment.pyです。

 

    2:ランダムプレイヤー、人間プレイヤー

この2つのクラスを実装します。プレイヤーのクラスには、状態を引数にとって、1か2を返す関数actが必要です。この関数はプレイヤーの行動を意味します。

ランダムプレイヤーのactはランダムに1か2を返します。

人間プレイヤーのactは状態を画面に出力し、キーボードから1か2の入力を受け取って、これを返します。

 

random_and_human.pyです。

 

   3:モンテカルロプレイヤー

100回ランダム対戦させて行動評価します。関数trialはその行動を取ったとして、最後までランダム対戦を1回します。

 

 mc.pyです。

 

   4:Q-learningプレイヤー

 Q-LearningではQ関数を学習します。Q関数は(status,action)に対応する配列で表現されます。ここでは、statusは0から9の10種類、actionは1,2の二種類なので、Q関数、self.q_asは2*10の2次元配列です。ここでは、Q関数、self.q_asを学習します。

更新式は、Q(s,a)←(1-α)*Q(s,a)+α*(r+γ*maxQ(s',a'))です。詳しくは、以下のリンクを見てください。ql.pyのtrainではこの式で更新してます。self.q_asがQ(s,a)です。

qiita.com

s'、a'は、sでaをして得られる状態s'と、そこでの行動a'です。これらを得られないと、パラメータを更新できません。なので、s'とa'を得るために、trainや、rain_data、next_status_getで長々といろいろやっています。

 

ql.pyです。

 

    5:結果確認</5>

対戦結果は以下のようになりました。MCがモンテカルロプレイヤーです。qlがQ-Learningプレイヤーです。先行は勝ちパターンさえ把握していれば必ず勝てます。その特徴をしっかりおさえた、理想的な結果となってます。

Randomは先行、後攻関係無く、MCとqlに勝てません。

MCは先行の場合、Random、MC、qlに良い勝率を出してますので、学習は成功していて、ある程度、勝ちパターンを把握していると言えます。

qlは先行の場合、完全勝利です。Random、MCは良いとして、qlに対しても100%ですので、勝ちパターンを完全におさえています。凄いです。

1.pyです。

 

p1: Random : 48 % vs p2: Random
p1: Random : 19 % vs p2: MC
p1: Random : 11 % vs p2: ql
p1: MC : 80 % vs p2: Random
p1: MC : 71 % vs p2: MC
p1: MC : 64 % vs p2: ql
p1: ql : 100 % vs p2: Random
p1: ql : 100 % vs p2: MC
p1: ql : 100 % vs p2: ql

 

以上です。強化学習モンテカルロ、Q-Learningでした。簡単なゲーム設定ではありましたが、かなり良い結果が得られたのでうれしいです。

 

アドバイス、改善点、質問があればお願いします。