0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Q学習でブラックジャックの最適戦略を作らせてみた

Posted at

はじめに

今回は、前回の記事の続きになります。

前回の記事↓

やること

前回は、モンテカルロ法を用いてブラックジャックの最適戦略を作らせてみました。
そこで今回は、Q学習を用いてブラックジャックの最適戦略を作らせてみようと思います。

使用コード・結果

import gym
import numpy as np
import pandas as pd
from collections import defaultdict
def q_learning_blackjack(n_episodes=500000, alpha=0.1, gamma=1.0, epsilon=0.1):
    env = gym.make('Blackjack-v1', natural=True, sab=True)
    Q = defaultdict(lambda: np.zeros(env.action_space.n))  # Qテーブル

    for episode in range(n_episodes):
        state, _ = env.reset()
        done = False

        while not done:
            # ε-グリーディー方策による行動選択
            if np.random.rand() < epsilon:
                action = env.action_space.sample()  # ランダム行動
            else:
                action = np.argmax(Q[state])  # 最良行動

            next_state, reward, done, _, _ = env.step(action)

            # Q値の更新 (Q学習の更新式)
            best_next_action = np.argmax(Q[next_state])
            Q[state][action] += alpha * (reward + gamma * Q[next_state][best_next_action] - Q[state][action])

            state = next_state  # 状態を更新

    return Q

# Q学習で戦略を学習
Q_table = q_learning_blackjack()
# 学習した戦略を評価
def evaluate_policy(Q, n_episodes=10000):
    env = gym.make('Blackjack-v1', natural=True, sab=True)
    wins, draws, losses = 0, 0, 0

    for _ in range(n_episodes):
        state, _ = env.reset()
        done = False

        while not done:
            action = np.argmax(Q[state]) if state in Q else env.action_space.sample()
            state, reward, done, _, _ = env.step(action)

        if reward == 1:
            wins += 1
        elif reward == 0:
            draws += 1
        else:
            losses += 1

    win_rate = wins / n_episodes
    print(f"勝率: {win_rate:.3f}, 引き分け: {draws/n_episodes:.3f}, 負け: {losses/n_episodes:.3f}")

evaluate_policy(Q_table)
勝率: 0.390, 引き分け: 0.068, 負け: 0.542
# 学習した戦略を表形式で表示
policy_df = pd.DataFrame({(player, dealer): 'スタンド' if np.argmax(Q_table[(player, dealer, False)]) == 0 else 'ヒット'
                             for player in range(12, 22) for dealer in range(1, 11)},
                            index=["推奨行動"]).T
プレイヤーの合計 ディーラーのアップカード 推奨行動 プレイヤーの合計(後半) ディーラーのアップカード(後半) 推奨行動(後半)
12 1 ヒット 17 1 ヒット
12 2 ヒット 17 2 スタンド
12 3 ヒット 17 3 スタンド
12 4 ヒット 17 4 スタンド
12 5 ヒット 17 5 スタンド
12 6 ヒット 17 6 スタンド
12 7 スタンド 17 7 スタンド
12 8 ヒット 17 8 ヒット
12 9 スタンド 17 9 ヒット
12 10 ヒット 17 10 スタンド
13 1 スタンド 18 1 スタンド
13 2 スタンド 18 2 スタンド
13 3 スタンド 18 3 スタンド
13 4 スタンド 18 4 スタンド
13 5 ヒット 18 5 スタンド
13 6 ヒット 18 6 スタンド
13 7 スタンド 18 7 スタンド
13 8 ヒット 18 8 スタンド
13 9 ヒット 18 9 ヒット
13 10 スタンド 18 10 スタンド
14 1 ヒット 19 1 スタンド
14 2 ヒット 19 2 スタンド
14 3 スタンド 19 3 スタンド
14 4 ヒット 19 4 スタンド
14 5 スタンド 19 5 スタンド
14 6 ヒット 19 6 スタンド
14 7 スタンド 19 7 スタンド
14 8 スタンド 19 8 スタンド
14 9 スタンド 19 9 スタンド
14 10 ヒット 19 10 スタンド
15 1 スタンド 20 1 スタンド
15 2 ヒット 20 2 スタンド
15 3 ヒット 20 3 スタンド
15 4 スタンド 20 4 スタンド
15 5 スタンド 20 5 スタンド
15 6 スタンド 20 6 スタンド
15 7 スタンド 20 7 スタンド
15 8 スタンド 20 8 スタンド
15 9 ヒット 20 9 スタンド
15 10 ヒット 20 10 スタンド
16 1 ヒット 21 1 スタンド
16 2 スタンド 21 2 スタンド
16 3 スタンド 21 3 スタンド
16 4 スタンド 21 4 スタンド
16 5 ヒット 21 5 スタンド
16 6 スタンド 21 6 スタンド
16 7 ヒット 21 7 スタンド
16 8 ヒット 21 8 スタンド
16 9 スタンド 21 9 スタンド
16 10 スタンド 21 10 スタンド

おわりに

前回のモンテカルロ法での勝率が43.1%だったことを考慮すると、今回のQ学習の方が勝率が低い。ただ、Q学習に関してはもう少し改善できるポイントがあると思うので、もう少し改善してから比較していこうと思います。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?