Bot 機械学習・データサイエンス

開発記録#114(2024/10/14)MLbotの開発.5「DQNとLSTM」

前回の記事に引き続き、今回も仮想通貨botの開発状況をまとめていきます。

Yodaka

今回はXで気になるポストがあったので、それを元に開発に着手しました。参考にしたのは@lawn_repさんのポストです。

ポイント

・MLbotの開発ネタを増やす

・DQN(Deep Q-Network)とLSTM(Long Short-Term Memory)について理解する

・bot開発の引き出しを増やす

・画像を手がかりにコードを書く

DQN(Deep Q-Network)とLSTM(Long Short-Term Memory)

. DQN(Deep Q-Network)とは?

概要:

DQNは強化学習アルゴリズムの一種で、Q-learning をディープニューラルネットワークで実装したものです。Q-learningは、環境の状態に基づいて最適なアクションを学習し、最終的に長期的な利益(報酬)を最大化するアプローチですが、DQNではこれをディープニューラルネットワークを使って大規模な状態空間に適用できるように拡張しています。


Q-learningの基本的なアイデア:

Q-learningでは、Q関数という関数を学習します。Q関数は、ある状態 s において、あるアクション a を取ったときに期待される将来的な報酬の総和を示すものです。Q関数は次のように定義されます:

Q(s,a)=現在の報酬+γ⋅次の状態での最大の報酬

  • Q(s, a): 状態 s でアクション a を取った場合に得られる期待報酬。
  • γ(割引率): 未来の報酬に対する現在の価値。γ が 1 に近いほど、将来の報酬を重要視し、0 に近いほど即時の報酬を重要視します。

DQNの特徴:

DQNは従来のQ-learningを次のような点で拡張しています。

  1. ニューラルネットワークによるQ関数の近似:
    • DQNでは、Q関数をディープニューラルネットワークで近似します。従来のQ-learningでは、状態空間が大きい場合(例えば画像データなど)、すべての状態とアクションの組み合わせに対してQ値を計算するのは難しいため、ディープラーニングを使ってこれを効率的に学習します。
  2. 経験再生(Experience Replay):
    • 強化学習では、連続した状態での相関を取り除くために「経験再生」という手法を使います。エージェントが得た経験(状態、アクション、報酬、次の状態)をリプレイバッファに保存し、そこからランダムにサンプルを取り出して学習することで、相関を減らし学習の安定性を向上させます。
  3. 固定ターゲットQネットワーク:
    • DQNでは、更新する際にターゲットとして用いるQ値のネットワーク(ターゲットネットワーク)を固定した状態で一定期間使います。これにより、Q値の更新が安定化し、振動を防ぎます。

DQNの学習プロセス:

  1. 環境から状態 s を観察します。
  2. 現在のQ関数に基づいて、次に取るべきアクション a を選択します(通常は ε-greedy 戦略で、εの割合でランダムなアクションを選び、1-εの割合で最適なアクションを選びます)。
  3. アクションを環境に適用し、次の状態 s' と報酬 r を観察します。
  4. 経験(s, a, r, s')をメモリに保存します。
  5. メモリからランダムにサンプリングした経験に基づいてQ関数を更新します。
  6. これを繰り返し、最適なポリシーを学習します。

2. LSTM(Long Short-Term Memory)とは?

概要:

LSTMは、RNN(Recurrent Neural Network) の一種で、主に時系列データを扱うために使われます。RNNは過去の情報を記憶し、系列データのパターンを捉えることができますが、通常のRNNでは「長期的な依存関係」を捉えるのが困難です。そこでLSTMは、特に長期的な依存関係を学習できるように設計されたネットワークです。


RNNの基本的な問題:

通常のRNNは、隠れ層で時間的な情報を連続して処理します。しかし、時間が進むにつれて、情報が前のステップから伝搬していく過程で、重要な情報が次第に薄れてしまう(勾配消失問題)ことがあります。そのため、RNNは短い期間の依存関係には強いですが、長期的な情報を保持するのが苦手です。


LSTMの仕組み:

LSTMは、通常のRNNに「ゲート機構」を追加することで、重要な情報を選択的に保持したり、忘れたりすることができるようになっています。LSTMのユニットは3つのゲートを持っています:

  1. 忘却ゲート(Forget Gate):
    • 過去の情報をどれだけ「忘れる」かを決定します。これにより、不要な情報は削除され、重要な情報だけが残ります。
  2. 入力ゲート(Input Gate):
    • 新しい情報をどれだけ「記憶」するかを決定します。これにより、現在の入力に基づいて重要な情報を記憶します。
  3. 出力ゲート(Output Gate):
    • 現在のセルの状態からどの情報を「出力」するかを決定します。これにより、次の層に渡すべき情報が選択されます。

LSTMの構造:

LSTMは、内部に「セル状態(Cell State)」と「隠れ状態(Hidden State)」を持っています。これらを使って、過去の情報を制御しながら次のステップに情報を渡します。

  • セル状態(Cell State): 長期的な情報を保持する経路。ゲートを通じて、重要な情報だけが伝わり続ける仕組みです。
  • 隠れ状態(Hidden State): 現在のステップに関する情報を保持し、次の計算に使用される。

LSTMの使いどころ:

LSTMは、時系列データや依存関係のあるデータの処理に非常に有効です。典型的な応用例としては、次のようなものがあります:

  1. 時系列予測:株価や仮想通貨の価格の予測など。
  2. 自然言語処理(NLP):テキストの生成や翻訳、感情分析など。
  3. 音声認識:音声データの解析。

3. DQNとLSTMの組み合わせ

DQNとLSTMを組み合わせると、時系列データにおける強化学習を強化できます。

  • LSTM:時系列データの依存関係を学習し、過去の状態を効率的に利用することで、将来のアクション選択に活用。
  • DQN:Q-learningを通じて、現在の状態において最適なアクションを選択し、長期的な報酬を最大化する。

この組み合わせにより、例えば仮想通貨の取引のように価格が時間とともに変動する環境で、過去の価格の影響を考慮しながら最適な取引タイミングを学習することが可能になります。

まとめ:

  • DQN は、強化学習のQ-learningをディープニューラルネットワークで拡張したもので、最適な行動を学習するためのアルゴリズムです。
  • LSTM は、時系列データを扱うのに優れたRNNの一種で、特に長期的な依存関係を学習するのに適しています。
  • これらを組み合わせることで、時系列データを活用した環境(例えば、株価や仮想通貨の取引)における最適化を行うことができます。

コードの雛形

このシステムの重要な要素は、DQN(Deep Q-Network)とLSTMを用いたアルゴリズムであり、以下の要素を踏まえたコードを作成できます。

  • DQN: Q-Learningをディープニューラルネットワークで実装し、強化学習を通じて最適なアクションを選択する。
  • LSTM: 時系列データを扱うためのRNN(Recurrent Neural Network)ベースのアルゴリズム。ここでは価格データなどの時系列情報を学習するために使用。
  • 売買ロジック: Bid/Ask情報に基づいて、売りや買いを行う。

以下は、簡略化された形でのDQN + LSTMを使った仮想通貨取引の自動売買ボットの実装例です。これは、環境の状態(価格の時系列データ)を観察し、最適な行動(売り、買い、何もしない)を選択する部分を含んでいます。

import numpy as np
import pandas as pd
import random
from collections import deque
import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras.optimizers import Adam

# 環境設定
class TradingEnv:
    def __init__(self, data, initial_balance=10000):
        self.data = data
        self.n_steps = len(data)
        self.initial_balance = initial_balance
        self.current_step = 0
        self.balance = initial_balance
        self.position = 0  # 現在のポジション(1:買い、-1:売り、0:ノーポジション)
        self.position_price = 0  # 現在のポジション価格
        self.done = False

    def reset(self):
        self.current_step = 0
        self.balance = self.initial_balance
        self.position = 0
        self.position_price = 0
        self.done = False
        return self._get_observation()

    def _get_observation(self):
        return self.data[self.current_step]

    def step(self, action):
        # action: 0 = 何もしない, 1 = 買い, 2 = 売り
        price = self.data[self.current_step]

        reward = 0
        if action == 1 and self.position == 0:  # 買い
            self.position = 1
            self.position_price = price
        elif action == 2 and self.position == 1:  # 売り
            reward = price - self.position_price
            self.balance += reward
            self.position = 0

        self.current_step += 1
        if self.current_step >= self.n_steps - 1:
            self.done = True

        return self._get_observation(), reward, self.done

# DQNエージェントの作成
class DQNAgent:
    def __init__(self, state_size, action_size):
        self.state_size = state_size
        self.action_size = action_size
        self.memory = deque(maxlen=2000)
        self.gamma = 0.95    # 割引率
        self.epsilon = 1.0   # 探索率
        self.epsilon_min = 0.01
        self.epsilon_decay = 0.995
        self.learning_rate = 0.001
        self.model = self._build_model()

    def _build_model(self):
        model = tf.keras.Sequential()
        model.add(layers.LSTM(50, input_shape=(1, self.state_size), return_sequences=True))
        model.add(layers.LSTM(50))
        model.add(layers.Dense(24, activation='relu'))
        model.add(layers.Dense(self.action_size, activation='linear'))
        model.compile(loss='mse', optimizer=Adam(lr=self.learning_rate))
        return model

    def remember(self, state, action, reward, next_state, done):
        self.memory.append((state, action, reward, next_state, done))

    def act(self, state):
        if np.random.rand() <= self.epsilon:
            return random.randrange(self.action_size)
        state = np.reshape(state, [1, 1, self.state_size])
        act_values = self.model.predict(state)
        return np.argmax(act_values[0])

    def replay(self, batch_size):
        minibatch = random.sample(self.memory, batch_size)
        for state, action, reward, next_state, done in minibatch:
            target = reward
            if not done:
                next_state = np.reshape(next_state, [1, 1, self.state_size])
                target = reward + self.gamma * np.amax(self.model.predict(next_state)[0])
            state = np.reshape(state, [1, 1, self.state_size])
            target_f = self.model.predict(state)
            target_f[0][action] = target
            self.model.fit(state, target_f, epochs=1, verbose=0)
        if self.epsilon > self.epsilon_min:
            self.epsilon *= self.epsilon_decay

# データのロード
# 仮想データを使う
data = np.random.normal(1000, 10, 1000)

# 環境とエージェントの初期化
env = TradingEnv(data)
agent = DQNAgent(state_size=1, action_size=3)

# トレーニング
episodes = 100
batch_size = 32

for e in range(episodes):
    state = env.reset()
    total_reward = 0
    for time in range(500):
        action = agent.act(state)
        next_state, reward, done = env.step(action)
        agent.remember(state, action, reward, next_state, done)
        state = next_state
        total_reward += reward
        if done:
            print(f"Episode {e+1}/{episodes}, Total reward: {total_reward}")
            break
        if len(agent.memory) > batch_size:
            agent.replay(batch_size)

説明:

  • TradingEnv: 環境のシミュレーション。価格の時系列データを元に「買い」「売り」「何もしない」の3つのアクションを提供し、その結果を返します。
  • DQNAgent: DQNエージェントで、LSTMを使って過去の価格データの時系列を学習します。Q学習をベースにして、次のアクションを選択します。
  • 記憶(Memory): エージェントは状態、アクション、報酬を記憶し、それを用いてQネットワークのトレーニングを行います。
  • LSTM: 状態(価格)を時系列的に理解し、次にどのようなアクションを取るべきかを決定します。

このコードをカスタマイズして、具体的な取引ロジックやパフォーマンスの指標を追加できます。また、仮想通貨の実際のデータを使うためには、取引所のAPIを使ってリアルタイムデータを取得する必要があります。

解説パート

このコードは、DQN(Deep Q-Network)とLSTM(Long Short-Term Memory)を用いて、仮想通貨の自動売買をシミュレートするためのものです。以下、各部分を詳しく説明します。

1. 環境設定(TradingEnv クラス)

class TradingEnv:
    def __init__(self, data, initial_balance=10000):
        self.data = data
        self.n_steps = len(data)
        self.initial_balance = initial_balance
        self.current_step = 0
        self.balance = initial_balance
        self.position = 0  # 現在のポジション(1:買い、-1:売り、0:ノーポジション)
        self.position_price = 0  # 現在のポジション価格
        self.done = False

説明1:

  • __init__ メソッド:環境を初期化する部分です。
    • data:価格データの配列(例えば、仮想通貨の価格の時系列データ)。
    • initial_balance:トレーディング開始時の資金。
    • position:現在のポジション状態を表す(1は「買い」、-1は「売り」、0は「ノーポジション」)。
    • position_price:現在のポジションで取得した価格。
    • done:トレーディングが終了したかどうかを判定するフラグ。

説明2:

    def reset(self):
        self.current_step = 0
        self.balance = self.initial_balance
        self.position = 0
        self.position_price = 0
        self.done = False
        return self._get_observation()

    def _get_observation(self):
        return self.data[self.current_step]
  • reset メソッド:トレーディングセッションの初期化。初期ステップに戻り、資金やポジションもリセットされます。最初の観測(価格)を返します。
  • _get_observation メソッド:現在の価格(環境の状態)を返します。

説明3:

    def step(self, action):
        price = self.data[self.current_step]
        reward = 0
        if action == 1 and self.position == 0:  # 買い
            self.position = 1
            self.position_price = price
        elif action == 2 and self.position == 1:  # 売り
            reward = price - self.position_price
            self.balance += reward
            self.position = 0

        self.current_step += 1
        if self.current_step >= self.n_steps - 1:
            self.done = True

        return self._get_observation(), reward, self.done
  • step メソッド:エージェントが行ったアクション(0=何もしない、1=買い、2=売り)に基づいて、トレードの進行を管理します。
    • アクションに応じて、ポジションが更新されます。
    • 買いアクション(action == 1):ポジションが空いている場合、買い注文を出し、その価格を記録。
    • 売りアクション(action == 2):ポジションを保持している場合、売り注文を出し、利益(報酬)を計算して資金に加えます。
    • 報酬は、売却時に得られる利益(現在の価格 - 買った価格)です。
    • ステップがデータの最後に達した場合、トレーディングは終了。

2. DQN エージェント(DQNAgent クラス)

class DQNAgent:
    def __init__(self, state_size, action_size):
        self.state_size = state_size
        self.action_size = action_size
        self.memory = deque(maxlen=2000)
        self.gamma = 0.95    # 割引率
        self.epsilon = 1.0   # 探索率
        self.epsilon_min = 0.01
        self.epsilon_decay = 0.995
        self.learning_rate = 0.001
        self.model = self._build_model()

説明1:

  • __init__ メソッド:DQNエージェントを初期化します。
    • state_size:状態空間の次元(ここでは価格データの長さ)。
    • action_size:選択できるアクションの数(0=何もしない、1=買い、2=売りの3つ)。
    • memory:経験を保存するメモリ。エージェントは過去の経験を記録し、リプレイに利用します。
    • gamma:割引率(将来の報酬の重要度を決める)。近い未来の報酬を優先し、遠い未来の報酬を割引して考えます。
    • epsilon:探索率(ランダムにアクションを選ぶ確率)。最初は探索的にランダムアクションを取りますが、学習が進むと徐々に減少します。

説明2:

def _build_model(self):
    model = tf.keras.Sequential()
    model.add(layers.LSTM(50, input_shape=(1, self.state_size), return_sequences=True))
    model.add(layers.LSTM(50))
    model.add(layers.Dense(24, activation='relu'))
    model.add(layers.Dense(self.action_size, activation='linear'))
    model.compile(loss='mse', optimizer=Adam(lr=self.learning_rate))
    return model
  • _build_model メソッド:エージェントの神経ネットワーク(モデル)を構築します。
    • LSTM層:過去の価格データの時系列情報を学習し、次のアクションに活用。
    • Dense層:アクションを選択するための出力層。出力は3つのアクション(何もしない、買い、売り)に対応します。

説明:2

    def remember(self, state, action, reward, next_state, done):
        self.memory.append((state, action, reward, next_state, done))
  • remember メソッド:経験を保存します。トレードの結果(状態、アクション、報酬、次の状態、終了フラグ)をメモリに追加。

説明3:

    def act(self, state):
        if np.random.rand() <= self.epsilon:
            return random.randrange(self.action_size)
        state = np.reshape(state, [1, 1, self.state_size])
        act_values = self.model.predict(state)
        return np.argmax(act_values[0])
  • act メソッド:エージェントが現在の状態からアクションを選択します。
    • 探索的にランダムなアクションを選ぶか、モデルの予測を元に最適なアクションを選択するかを決定。
    • epsilon の確率に基づいてランダムアクションを選ぶ(探索)。
    • 探索しない場合、LSTMを使ったモデルの出力に基づき最適なアクションを選びます。

説明4:

    def replay(self, batch_size):
        minibatch = random.sample(self.memory, batch_size)
        for state, action, reward, next_state, done in minibatch:
            target = reward
            if not done:
                next_state = np.reshape(next_state, [1, 1, self.state_size])
                target = reward + self.gamma * np.amax(self.model.predict(next_state)[0])
            state = np.reshape(state, [1, 1, self.state_size])
            target_f = self.model.predict(state)
            target_f[0][action] = target
            self.model.fit(state, target_f, epochs=1, verbose=0)
        if self.epsilon > self.epsilon_min:
            self.epsilon *= self.epsilon_decay
  • replay メソッド:経験からエージェントを学習させます。
    • メモリからランダムにミニバッチを選び、次の状態に対する最大Q値を使ってQ関数を更新します。
    • 報酬が得られた場合、それを元に報酬を更新します。
    • 学習後に探索率(epsilon)を減少させ、徐々により賢いアクションを選択するようにします。

3. メインループ

# データのロード
data = np.random.normal(1000, 10, 1000)

# 環境とエージェントの初期化
env = TradingEnv(data)
agent = DQNAgent(state_size=1, action_size=3)

# トレーニング
episodes = 100
batch_size = 32

for e in range(episodes):
    state = env.reset()
    total_reward = 0
    for time in range(500):
        action = agent.act(state)
        next_state, reward, done = env.step(action)
        agent.remember(state, action, reward, next_state, done)
        state = next_state
        total_reward += reward
        if done:
            print(f"Episode {e+1}/{episodes}, Total reward: {total_reward}")
            break
        if len(agent.memory) > batch_size:
            agent.replay(batch_size)

説明:

  • データのロード:仮想的なデータセットを生成します。
  • 環境とエージェントの初期化:トレーディング環境とエージェントを初期化。
  • トレーニングループ:100回のエピソードを実行し、各エピソードごとに500ステップ(時間)までトレードを行います。
    • 各ステップでエージェントは状態に基づいてアクションを選び、環境にフィードバックを与えて、報酬と次の状態を得ます。
    • メモリに経験を記録し、十分なメモリが溜まったらミニバッチを使って学習します。

修正版のコード

Yodaka

以下のコードはCursorに修正させて実際に稼働できるようにしたものです。

import numpy as np
import pandas as pd
import random
from collections import deque
import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras.optimizers import Adam

# 環境設定
class TradingEnv:
    def __init__(self, data, initial_balance=10000):
        self.data = data
        self.n_steps = len(data)
        self.initial_balance = initial_balance
        self.current_step = 0
        self.balance = initial_balance
        self.position = 0  # 現在のポジション(1:買い、-1:売り、0:ノーポジション)
        self.position_price = 0  # 現在のポジション価格
        self.done = False

    def reset(self):
        self.current_step = 0
        self.balance = self.initial_balance
        self.position = 0
        self.position_price = 0
        self.done = False
        return self._get_observation()

    def _get_observation(self):
        return np.array([self.data[self.current_step]])

    def step(self, action):
        # action: 0 = 何もしない, 1 = 買い, 2 = 売り
        price = self.data[self.current_step]

        reward = 0
        if action == 1 and self.position == 0:  # 買い
            self.position = 1
            self.position_price = price
        elif action == 2 and self.position == 1:  # 売り
            reward = price - self.position_price
            self.balance += reward
            self.position = 0

        self.current_step += 1
        if self.current_step >= self.n_steps - 1:
            self.done = True

        return self._get_observation(), reward, self.done

# DQNエージェントの作成
class DQNAgent:
    def __init__(self, state_size, action_size):
        self.state_size = state_size
        self.action_size = action_size
        self.memory = deque(maxlen=2000)
        self.gamma = 0.95    # 割引率
        self.epsilon = 1.0   # 探索率
        self.epsilon_min = 0.01
        self.epsilon_decay = 0.995
        self.learning_rate = 0.001
        self.model = self._build_model()

    def _build_model(self):
        model = tf.keras.Sequential()
        model.add(layers.LSTM(50, input_shape=(1, self.state_size), return_sequences=True))
        model.add(layers.LSTM(50))
        model.add(layers.Dense(24, activation='relu'))
        model.add(layers.Dense(self.action_size, activation='linear'))
        model.compile(loss='mse', optimizer=Adam(learning_rate=self.learning_rate))
        return model

    def remember(self, state, action, reward, next_state, done):
        self.memory.append((state, action, reward, next_state, done))

    def act(self, state):
        if np.random.rand() <= self.epsilon:
            return random.randrange(self.action_size)
        state = np.reshape(state, [1, 1, self.state_size])
        act_values = self.model.predict(state)
        return np.argmax(act_values[0])

    def replay(self, batch_size):
        minibatch = random.sample(self.memory, batch_size)
        for state, action, reward, next_state, done in minibatch:
            target = reward
            if not done:
                next_state = np.reshape(next_state, [1, 1, self.state_size])
                target = reward + self.gamma * np.amax(self.model.predict(next_state)[0])
            state = np.reshape(state, [1, 1, self.state_size])
            target_f = self.model.predict(state)
            target_f[0][action] = target
            self.model.fit(state, target_f, epochs=1, verbose=0)
        if self.epsilon > self.epsilon_min:
            self.epsilon *= self.epsilon_decay

# データのロード
# 仮想データを使う
data = np.random.normal(1000, 10, 1000)

# 環境とエージェントの初期化
env = TradingEnv(data)
agent = DQNAgent(state_size=1, action_size=3)

# トレーニング
episodes = 100
batch_size = 32

for e in range(episodes):
    state = env.reset()
    total_reward = 0
    for time in range(500):
        action = agent.act(state)
        next_state, reward, done = env.step(action)
        agent.remember(state, action, reward, next_state, done)
        state = next_state
        total_reward += reward
        if done:
            print(f"Episode {e+1}/{episodes}, Total reward: {total_reward}")
            break
        if len(agent.memory) > batch_size:
            agent.replay(batch_size)

このコードは、DQN(Deep Q-Network)とLSTM(Long Short-Term Memory)を使った強化学習エージェントを実装したもので、仮想的なトレーディング環境でエージェントが学習しながら行動を決定する仕組みになっています。以下に各部分を解説します。


1. 環境設定(TradingEnv クラス)

このクラスは、仮想的なトレーディング環境をシミュレートしています。

__init__ メソッド:

  • トレーディング環境を初期化し、初期残高やステップ数、ポジション(売りや買いの状態)などを設定します。

reset メソッド:

  • エージェントが新しいエピソードを始める際に、環境をリセットし、最初の状態(価格)を返します。

_get_observation メソッド:

  • 現在のステップでの観察(現在の価格データ)を返します。

step メソッド:

  • エージェントが取るアクション(0=何もしない、1=買い、2=売り)に応じて、トレーディングの進行をシミュレートします。
  • エージェントが「買い」を選択した場合、ポジションを保持し、次に「売り」を選択した場合に利益(報酬)が計算されます。
  • ステップが終わったかどうかを判断し、次の状態、報酬、エピソードの終了フラグを返します。

2. DQNエージェント(DQNAgent クラス)

このクラスは、Q-learningをディープラーニングで実装したDQNエージェントです。エージェントはLSTMを使用して価格の時系列データを学習し、最適な行動を決定します。

__init__ メソッド:

  • エージェントのパラメータ(割引率、探索率、メモリの初期化)を設定し、DQNモデルを構築します。

_build_model メソッド:

  • LSTM層を持つニューラルネットワークを定義し、これをQ関数の近似モデルとして使用します。
  • モデルは「状態」を入力とし、3つのアクション(何もしない、買い、売り)に対するQ値を出力します。

remember メソッド:

  • エージェントが得た経験(状態、アクション、報酬、次の状態、終了フラグ)をメモリに保存します。

act メソッド:

  • エージェントが現在の状態を基に次に取るべきアクションを決定します。
  • 探索率(epsilon)に基づいて、ランダムなアクション(探索)を取るか、ニューラルネットワークの予測に基づいた最適なアクションを取るかを決定します。

replay メソッド:

  • メモリに保存された経験をランダムにサンプリングし、それを使ってDQNモデルをトレーニングします。
  • この方法により、過去の経験から学習し、次のアクションをより効率的に選択できるようになります。

3. トレーニングループ

episodes = 100
batch_size = 32

for e in range(episodes):
    state = env.reset()
    total_reward = 0
    for time in range(500):
        action = agent.act(state)
        next_state, reward, done = env.step(action)
        agent.remember(state, action, reward, next_state, done)
        state = next_state
        total_reward += reward
        if done:
            print(f"Episode {e+1}/{episodes}, Total reward: {total_reward}")
            break
        if len(agent.memory) > batch_size:
            agent.replay(batch_size)
  • エピソードの繰り返し(100回):各エピソードでエージェントがリセットされた環境で学習を開始し、取引を行います。
  • 1ステップごとに:
    • エージェントは現在の状態から次のアクションを選択し、環境でそのアクションを実行して次の状態、報酬、エピソード終了フラグを受け取ります。
    • エージェントは得た経験をメモリに保存し、メモリが十分に溜まるとミニバッチで学習を行います。
  • エピソード終了時:累積報酬を表示します。

4. 仮想データの生成

data = np.random.normal(1000, 10, 1000)

正規分布に従った仮想データ(価格データ)を生成します。平均が1000、標準偏差が10の範囲で1000個のデータポイントを生成しています。

まとめ:

このコードは、DQN(Deep Q-Network)とLSTMを使って時系列データに基づく強化学習エージェントを実装しています。仮想的な価格データを使ったトレーニング環境で、エージェントが最適な取引アクション(買い、売り、何もしない)を学習します。時間とともにエージェントは、過去の経験から学習し、より良いアクションを取るように進化していきます。

まとめ

今回はDQNとLSTMを使ったMLbotのプロトタイプを作ってみました。

機械学習モジュールの使用方法や実際のトレードに活かす方法なども少しずつ蓄積されてきたように感じます。

また、AIに画像を読み込ませることでもある程度の予測を立てて取引戦略のコードを書けることがわかったのも収穫の一つでした。

Yodaka

モジュールやAIなどのツールを活用しながら、自分の取引戦略の引き出しを増やしていきたいです。

今後もこの調子で開発の状況を発信していきます。

-Bot, 機械学習・データサイエンス