数式とPython実装から理解する価値反復法
価値反復法は強化学習における基本的かつ重要なアルゴリズムの一つです。マルコフ決定過程(MDP)において最適な方策を求めるための手法であり、理論的な背景から実際のPythonコードによる実装までを通じて学ぶことで、理解が深まります。
この記事では、数式を用いた価値反復法の原理説明と、それをPythonでどのように実装するかを丁寧に解説します。初心者の方でもわかりやすいように、数式の意味を噛み砕きながら段階的に進めていきます。
この記事で学べること:
- 価値反復法の基本的な数式とその解釈
- 価値反復法のアルゴリズムの流れ
- Pythonによる価値反復法の実装例
- 実装コードのポイントと動作の確認方法
価値反復法の核となる更新式は以下の通りです。状態 \(s\) における価値関数 \(V(s)\) は、将来の報酬を最大化するように次のように更新されます。
\[
V_{k+1}(s) = \max_{a} \sum_{s’, r} p(s’, r | s, a) \left[ r + \gamma V_k(s’) \right]
\]
ここで、\(p(s’, r | s, a)\) は状態遷移確率、\(\gamma\) は割引率を表します。
結論
価値反復法は、理論的な数式と実装の両面から理解することで、強化学習の基礎をしっかり固められる手法です。数式の意味を確認しながら、Pythonコードを動かしてみることで、アルゴリズムの挙動が直感的に理解できます。
今回紹介した価値反復法は、環境モデルが既知の場合に有効です。これを応用することで、より複雑な問題や実際の強化学習タスクに挑戦できるようになります。
次に読むと良い関連記事候補の観点としては、「モデルフリー強化学習アルゴリズム」との比較があります。価値反復法(モデルベース)とモデルフリー手法の違いや使い分けを理解すると、強化学習全体の知識がより深まります。
次のアクション
- この記事のPythonコードを実際に動かしてみる
- マルコフ決定過程(MDP)の基礎を復習する
- モデルフリー強化学習アルゴリズム(Q学習やSARSA)について調べる
- OpenAI Gymなどの環境を使って価値反復法を試す
価値反復法とは何か
価値反復法(Value Iteration)は、強化学習における基本的な動的計画法の一つで、最適な行動方針(ポリシー)を見つけるためのアルゴリズムです。環境の状態と行動に対する報酬をもとに、「状態価値関数」と呼ばれる各状態の価値を繰り返し更新し、最終的に最適な価値関数を求めます。
価値反復法の中心的な考え方は、ベルマン方程式に基づいて価値関数を更新することです。ベルマン方程式は以下のように表されます。
現在の状態 \( s \) における価値 \( V(s) \) は、選択可能なすべての行動 \( a \) について、即時報酬 \( R(s,a) \) と次の状態 \( s’ \) の価値の割引和の最大値をとることで更新されます。
\[
V_{k+1}(s) = \max_{a} \left( R(s,a) + \gamma \sum_{s’} P(s’|s,a) V_k(s’) \right)
\]
- \( V_k(s) \):状態 \( s \) の価値関数の \( k \) 回目の更新後の値
- \( R(s,a) \):状態 \( s \) で行動 \( a \) をとったときの即時報酬
- \( \gamma \):割引率(0から1の間の値で、将来の報酬の重要度を調整)
- \( P(s’|s,a) \):状態 \( s \) で行動 \( a \) をとったときに次の状態が \( s’ \) である確率
この式は、現在の価値を「即時の報酬」と「将来の価値の期待値」の和として捉え、最も価値が高くなる行動を選ぶことを意味します。反復的にこの計算を行うことで、価値関数は収束し、最適なポリシーを導き出せます。
実際のPythonコードでは、状態と行動の集合をループしながら価値を更新します。簡単な例を示します。
states = [0, 1, 2]
actions = [0, 1]
gamma = 0.9
# 状態遷移確率と報酬の例(辞書形式)
P = {
(0, 0): [(1.0, 1, 5)], # (遷移確率, 次状態, 報酬)
(0, 1): [(1.0, 2, 10)],
(1, 0): [(1.0, 0, -1)],
(1, 1): [(1.0, 2, 2)],
(2, 0): [(1.0, 0, 0)],
(2, 1): [(1.0, 1, 1)],
}
V = {s: 0 for s in states} # 初期価値関数
for _ in range(10): # 10回の反復
new_V = {}
for s in states:
action_values = []
for a in actions:
total = 0
for prob, next_s, reward in P[(s, a)]:
total += prob * (reward + gamma * V[next_s])
action_values.append(total)
new_V[s] = max(action_values)
V = new_V
print(V)
この例では、状態と行動ごとに報酬と遷移確率を設定し、10回の反復で価値関数を更新しています。最終的に各状態の価値が求まり、最適な行動選択の指針となります。
以上のように、価値反復法は数式の理論とコードによる実装がシンプルで直感的なため、強化学習の基礎を学ぶ上で非常に重要な手法です。
価値反復法の基本的な考え方
価値反復法(Value Iteration)は、強化学習における基本的な方策評価の手法の一つで、マルコフ決定過程(MDP)における最適な価値関数を求めるための反復計算方法です。具体的には、状態価値関数 \(V(s)\) を更新することで、最適な行動方針(ポリシー)を導き出します。
価値反復法の核となる数式は以下のベルマン最適方程式です。
状態 \(s\) における価値関数を次のように更新します。
\[
V_{k+1}(s) = \max_a \sum_{s’, r} P(s’, r \mid s, a) \left[ r + \gamma V_k(s’) \right]
\]
- \(V_k(s)\):反復 \(k\) 回目の状態価値関数
- a:行動(アクション)
- P(s’, r \mid s, a):状態 \(s\) で行動 \(a\) を取った時、次の状態 \(s’\) と報酬 \(r\) が得られる確率
- \(\gamma\):割引率(0〜1の値で未来の報酬の重要度を調整)
この数式の意味は簡単で、「各状態 \(s\) において可能な行動すべてを試し、その中で最も期待報酬が高くなる行動の価値を新しい状態価値として更新する」ということです。この操作を全ての状態について繰り返し行うことで、価値関数が収束し、最適な方策が得られます。
実際のPython実装では、状態と行動の集合をループし、価値の更新を反復的に行います。以下は簡単な擬似コード例です。
def value_iteration(states, actions, P, R, gamma, theta):
V = {s: 0 for s in states} # 初期価値関数はゼロで初期化
while True:
delta = 0
for s in states:
v = V[s]
V[s] = max(
sum(P(s, a, s_next) * (R(s, a, s_next) + gamma * V[s_next]) for s_next in states)
for a in actions
)
delta = max(delta, abs(v - V[s]))
if delta < theta:
break
return V
ここでは、P(s, a, s_next)が遷移確率、R(s, a, s_next)が報酬関数を表しており、全状態・全行動について期待報酬を計算し最大値を取っています。thetaは収束判定の閾値です。
価値反復法は単純ですが、理論的に最適解に収束する保証があり、強化学習や動的計画法の基礎を学ぶ上で非常に重要な手法です。次のステップとしては、この価値関数から最適な行動を導出する方法や、具体的な環境での応用例を見ていくと理解が深まります。
マルコフ決定過程(MDP)の基礎知識
価値反復法を理解するためには、まずマルコフ決定過程(Markov Decision Process、MDP)の基礎を押さえることが重要です。MDPは、意思決定問題を数学的にモデル化したもので、エージェントが環境と相互作用しながら最適な行動を学習する枠組みとして広く使われています。
MDPは主に以下の4つの要素で構成されます:
- 状態(State)\(S\): エージェントの現在の状況を表す集合
- 行動(Action)\(A\): エージェントが取ることのできる選択肢の集合
- 遷移確率(Transition Probability)\(P(s’|s,a)\): 状態\(s\)で行動\(a\)を取ったとき、次の状態が\(s’\)になる確率
- 報酬(Reward)\(R(s,a)\): 状態\(s\)で行動\(a\)を取った際に得られる即時の報酬
これらを踏まえて、MDPにおける目標は「将来得られる報酬の総和を最大化する」ことです。ここで重要になるのが価値関数で、特に状態価値関数\(V(s)\)は、状態\(s\)にいるときに期待される将来の累積報酬のことを指します。
価値反復法は、この価値関数を反復的に計算することで最適な行動方針(ポリシー)を求めるアルゴリズムです。価値関数の更新は以下のベルマン方程式に基づいています:
\[
V_{k+1}(s) = \max_{a \in A} \left[ R(s,a) + \gamma \sum_{s’} P(s’|s,a) V_k(s’) \right]
\]
ここで、
- \(V_k(s)\): 現在の反復ステップでの状態価値
- \(\gamma\): 割引率(0から1の値、未来の報酬の現在価値を調整)
- \(\max\) は、各行動の価値の中で最も高いものを選ぶ操作
この式の意味を簡単に説明すると、状態\(s\)にいるときに取れる全ての行動\(a\)について、即時報酬\(R(s,a)\)と次の状態\(s’\)における価値の期待値を考え、その中で最も高い価値を持つ行動を選ぶということです。この反復を繰り返すことで、価値関数は最適な値に収束します。
以下は、単純なMDPの価値反復のPython実装例です。ここでは状態と行動が小さな有限集合で定義されています。
# 状態と行動の定義
states = [0, 1, 2]
actions = [0, 1]
# 遷移確率 P[s][a][s']
P = {
0: {0: {0: 0.7, 1: 0.3, 2: 0.0},
1: {0: 0.1, 1: 0.9, 2: 0.0}},
1: {0: {1: 0.8, 2: 0.2, 0: 0.0},
1: {1: 0.0, 2: 1.0, 0: 0.0}},
2: {0: {2: 1.0, 0: 0.0, 1: 0.0},
1: {2: 1.0, 0: 0.0, 1: 0.0}},
}
# 報酬関数 R[s][a]
R = {
0: {0: 5, 1: 10},
1: {0: -1, 1: 2},
2: {0: 0, 1: 0},
}
gamma = 0.9
V = {s: 0 for s in states} # 初期価値関数を0に設定
for _ in range(100): # 反復回数
new_V = {}
for s in states:
action_values = []
for a in actions:
expected_value = R[s][a] + gamma * sum(P[s][a][s_next] * V[s_next] for s_next in states)
action_values.append(expected_value)
new_V[s] = max(action_values)
V = new_V
print("最終的な状態価値関数:", V)
このコードは、ベルマン方程式に基づいて状態価値関数を繰り返し更新し、最終的に最適な価値を出力します。MDPの基本的な枠組みを理解することで、価値反復法のアルゴリズムがどのように動作しているかがイメージしやすくなります。
価値関数と行動価値関数の違い
強化学習において、「価値関数」と「行動価値関数」は非常に重要な概念です。特に価値反復法を理解する上で、この2つの違いを正確に把握することが不可欠です。ここでは初心者の方にもわかりやすく、それぞれの意味と使い方を解説します。
価値関数(State Value Function)とは?
価値関数は、ある状態 \( s \) にいるときに、「将来得られる報酬の期待値」を示す関数です。具体的には、ある方策(ポリシー) \(\pi\) に従った場合の期待値を表します。数式で表すと次のようになります。
価値関数 \( V^\pi(s) \) は、
\[
V^\pi(s) = \mathbb{E}_\pi \left[ \sum_{t=0}^{\infty} \gamma^t R_{t} \mid S_0 = s \right]
\]
ここで、
- \( \gamma \) は割引率(0から1の間の値)
- \( R_t \) は時刻 \( t \) に得られる報酬
- \( S_0 = s \) は初期状態が \( s \) であること
つまり、「今の状態から始めて、将来的にどれだけの報酬が期待できるか」を示す指標です。
行動価値関数(Action Value Function)とは?
一方で、行動価値関数は「ある状態 \( s \) で特定の行動 \( a \) をとった場合に、将来得られる報酬の期待値」を示します。方策 \(\pi\) に従う場合の期待値は以下の通りです。
行動価値関数 \( Q^\pi(s,a) \) は、
\[
Q^\pi(s,a) = \mathbb{E}_\pi \left[ \sum_{t=0}^{\infty} \gamma^t R_{t} \mid S_0 = s, A_0 = a \right]
\]
この関数は、「状態と行動の組み合わせに対して、どれだけの報酬が期待できるか」を示し、行動選択の基準となります。
価値関数と行動価値関数の関係性
価値関数は状態に依存し、行動価値関数は状態と行動のペアに依存します。価値関数は行動価値関数を使って次のように表せます。
\[
V^\pi(s) = \sum_{a} \pi(a \mid s) Q^\pi(s,a)
\]
つまり、価値関数は方策に基づいて、その状態での行動価値関数の期待値を取ったものです。
Pythonによる簡単な実装例
価値関数と行動価値関数の違いをコードでイメージすると以下のようになります。
# 例: 状態s=0で行動a=1をとった場合の行動価値を計算
def Q_pi(s, a, policy, reward_func, gamma=0.9):
# reward_func(s, a) は即時報酬を返す関数
immediate_reward = reward_func(s, a)
next_state = s + 1 # 簡単のため遷移はs+1と仮定
# 次状態の価値を計算(価値関数V)
V_next = sum(policy(a_next, next_state) * Q_pi(next_state, a_next, policy, reward_func, gamma)
for a_next in [0,1]) # 行動は0か1の2択と仮定
return immediate_reward + gamma * V_next
def V_pi(s, policy, Q_func):
# 価値関数は行動価値関数の期待値
return sum(policy(a, s) * Q_func(s, a, policy) for a in [0,1])
この例では、行動価値関数 \( Q^\pi(s,a) \) を再帰的に計算し、価値関数 \( V^\pi(s) \) がその期待値であることを示しています。実際には状態数や行動数が多くなるため、価値反復法などのアルゴリズムで効率的に計算します。
まとめると、価値関数は「状態の価値」を、行動価値関数は「状態と行動の価値」を表し、どちらも価値反復法で最適方策を導く基盤となる重要な指標です。
価値反復法の数式による定義
価値反復法は、強化学習における代表的なアルゴリズムの一つで、最適な行動価値関数(または状態価値関数)を求めるための反復的な方法です。ここでは、価値反復法の基本的な数式定義をわかりやすく解説します。
強化学習の問題はマルコフ決定過程(MDP)でモデル化され、状態 \( s \) と行動 \( a \) の組み合わせに対して報酬や遷移確率が定義されています。価値反復法では、価値関数 \( V(s) \) を更新することで最適な価値を求めます。更新式は次のように表されます:
\[
V_{k+1}(s) = \max_{a \in \mathcal{A}} \left( R(s,a) + \gamma \sum_{s’} P(s’|s,a) V_k(s’) \right)
\]
- \( V_k(s) \):ステップ \( k \) における状態 \( s \) の価値
- \( \mathcal{A} \):可能な行動の集合
- \( R(s,a) \):状態 \( s \) で行動 \( a \) を取ったときの報酬
- \( \gamma \):割引率(0から1の間の値)、将来の報酬の重要度を調整
- \( P(s’|s,a) \):状態遷移確率、状態 \( s \) で行動 \( a \) を取ったときに次の状態が \( s’ \) となる確率
この式の意味は、現在の状態 \( s \) における価値を、すべての行動 \( a \) の中から「即時報酬 \( R(s,a) \)」と「次の状態 \( s’ \) の価値 \( V_k(s’) \) の期待値の割引和」を足したものの最大値として更新する、ということです。繰り返しこの更新を行うことで、価値関数は最適値に収束します。
それでは、この数式をPythonで実装するイメージを簡単に示します。
def value_iteration(states, actions, P, R, gamma, theta=1e-6):
V = {s: 0 for s in states}
while True:
delta = 0
for s in states:
v = V[s]
action_values = []
for a in actions:
expected_value = sum(P(s, a, s_next) * V[s_next] for s_next in states)
action_values.append(R(s, a) + gamma * expected_value)
V[s] = max(action_values)
delta = max(delta, abs(v - V[s]))
if delta < theta:
break
return V
ここで、P(s, a, s_next) は状態遷移確率、R(s, a) は報酬関数を表す関数として実装されています。価値関数 V は辞書で管理し、各状態で最大の価値を持つ行動を見つけるために、行動ごとの期待値を計算し比較しています。
まとめると、価値反復法は「状態ごとに、すべての行動を試し、その行動の即時報酬と将来の価値の期待値の合計を計算し、最大の値を採用する」ことを繰り返すことで、最適な価値関数を求める手法です。この数式と実装を理解することが、強化学習の基礎を固める第一歩となります。
ベルマン方程式の役割と意味
価値反復法を理解するうえで欠かせないのが「ベルマン方程式」です。これは強化学習やマルコフ決定過程(MDP)における基本的な考え方を示す数式で、状態の価値(あるいは行動の価値)を再帰的に定義します。初心者の方には少し難しく感じるかもしれませんが、順を追って説明していきます。
ベルマン方程式は、ある状態 \(s\) における価値関数 \(V(s)\) を、その状態から次に遷移する状態の価値の期待値を使って表現します。具体的には、割引率 \(\gamma\) と報酬関数 \(R(s, a, s’)\) を用いて、以下のように書けます。
状態価値関数に対するベルマン方程式:
\[
V(s) = \max_{a} \sum_{s’} P(s’|s,a) \left[ R(s, a, s’) + \gamma V(s’) \right]
\]
ここで
- \(P(s’|s,a)\) は状態 \(s\) で行動 \(a\) を取ったときに次の状態が \(s’\) になる確率
- \(R(s, a, s’)\) はその遷移で得られる報酬
- \(\gamma\) は未来の報酬をどれだけ重視するかを示す割引率(0 < \(\gamma\) < 1)
この式の意味は、「現在の状態の価値は、選べる行動の中で最も良い(最大の)期待価値に等しい」ということです。価値反復法では、このベルマン方程式を使って価値関数を繰り返し更新し、最終的に最適価値関数を求めます。
次に、Pythonで価値反復法の核心部分を簡単に実装してみましょう。ここでは価値関数 \(V\) を辞書で管理し、1回の更新を行うコード例です。
def value_iteration_update(V, states, actions, P, R, gamma):
new_V = {}
for s in states:
action_values = []
for a in actions:
expected_value = 0
for s_prime, prob in P[s][a].items():
reward = R[s][a][s_prime]
expected_value += prob * (reward + gamma * V[s_prime])
action_values.append(expected_value)
new_V[s] = max(action_values)
return new_V
このコードのポイントは、ベルマン方程式の右辺をそのまま計算していることです。各状態 \(s\) について、すべての行動 \(a\) を試し、その期待値を計算し、最大のものを新しい価値として更新しています。これを繰り返すことで、価値反復法は最適な価値関数に収束していきます。
まとめると、ベルマン方程式は「価値関数を再帰的に定義し、最適な行動選択の基準を与える」役割を担っています。価値反復法はこの式を使い、価値を更新しながら最適解を見つける強力なアルゴリズムなのです。
価値反復法のアルゴリズム手順
価値反復法は強化学習の基本的なアルゴリズムの一つで、環境の状態ごとに最適な価値関数を反復的に更新していく方法です。ここでは、初心者にも分かりやすいように、価値反復法の具体的なアルゴリズムの手順を数学的な式とPythonコードで解説します。
価値反復法の中心となる考え方は、ベルマン方程式に基づく価値関数の更新です。価値関数 \(V(s)\) は状態 \(s\) における「将来得られる最大の報酬」を表します。更新式は以下のように表されます:
V_{k+1}(s) = \max_{a \in \mathcal{A}} \sum_{s’} P(s’|s,a) \left[ R(s,a,s’) + \gamma V_k(s’) \right]
\]
この式を解釈すると、現在の状態 \(s\) で選択可能な行動 \(a\) の中から、次の状態 \(s’\) に遷移する確率 \(P(s’|s,a)\) と報酬 \(R(s,a,s’)\)、割引率 \(\gamma\) を考慮した将来の価値 \(V_k(s’)\) の期待値を計算し、最大のものを価値関数の新しい値とします。これをすべての状態に対して繰り返し更新することで、最終的に最適価値関数が得られます。
具体的なアルゴリズムの手順は以下の通りです:
- 初期化:すべての状態の価値関数 \(V_0(s)\) をゼロやランダムな値で初期化する。
- 価値関数の更新:上記のベルマン更新式を用いて、すべての状態の価値関数を更新する。
- 収束判定:価値関数の更新前後の差が十分小さくなったら終了。そうでなければ手順2に戻る。
以下はPythonで簡単に価値反復法を実装した例です。ここでは状態数と行動数が小さい環境を想定しています。
import numpy as np
def value_iteration(P, R, gamma=0.9, theta=1e-6):
"""
P: 遷移確率。形状は (状態数, 行動数, 状態数)
R: 報酬関数。形状は (状態数, 行動数, 状態数)
gamma: 割引率
theta: 収束判定の閾値
"""
num_states = P.shape[0]
num_actions = P.shape[1]
V = np.zeros(num_states)
while True:
delta = 0
for s in range(num_states):
v = V[s]
# 各行動ごとの期待価値を計算
Q_values = np.zeros(num_actions)
for a in range(num_actions):
Q_values[a] = np.sum(P[s, a, :] * (R[s, a, :] + gamma * V))
V[s] = np.max(Q_values)
delta = max(delta, abs(v - V[s]))
if delta < theta:
break
return V
このコードでは、状態 \(s\) ごとに各行動 \(a\) の期待価値を計算し、その最大値を新しい価値関数として更新しています。収束判定は前回の価値関数との変化量 \(\delta\) が小さくなったときにループを抜けます。
まとめると、価値反復法は価値関数を反復的に更新しながら最適解に近づける方法であり、数学的なベルマン方程式の理解と、その実装が強化学習の基礎を築きます。次のステップでは、得られた価値関数から最適な方策を導出する方法も学んでいきましょう。
Pythonで価値反復法を実装する準備
価値反復法は、強化学習における基本的なアルゴリズムの一つで、最適な行動価値関数を計算するために用いられます。Pythonで実装する前に、必要な数学的背景と準備すべき環境について理解しておきましょう。
まず、価値反復法の核心となる更新式は以下のように表されます。
現在の状態 \(s\) における価値関数 \(V(s)\) を、新しい価値関数 \(V'(s)\) に更新する式は:
\[
V'(s) = \max_{a} \sum_{s’} P(s’|s,a) \bigl[ R(s,a,s’) + \gamma V(s’) \bigr]
\]
ここで、
- \(a\):状態 \(s\) で選択可能な行動
- \(P(s’|s,a)\):状態 \(s\) で行動 \(a\) を取ったときに次の状態が \(s’\) となる確率
- \(R(s,a,s’)\):状態遷移の際に得られる報酬
- \(\gamma\):割引率(未来の報酬をどれだけ重視するかを示すパラメータ)
この式は、「ある状態で最適な行動を選ぶことで得られる期待報酬の最大値を価値関数として更新する」ことを意味します。
Pythonで実装するにあたっては、以下の準備をおすすめします。
- Python 3系の環境を用意する(Anacondaやvenvなどで仮想環境を作成すると管理しやすい)
- NumPyを利用して、行列演算や確率計算を効率的に行う
- 環境(状態と行動の空間)、遷移確率、報酬関数をデータ構造として定義する
簡単な価値反復法の雛形コードを以下に示します。ここでは、状態空間と行動空間が小さい例を想定しています。
import numpy as np
# 状態数と行動数の定義
num_states = 3
num_actions = 2
# 遷移確率 P[s, a, s']
P = np.array([
[[0.8, 0.2, 0.0],
[0.1, 0.9, 0.0]],
[[0.0, 0.7, 0.3],
[0.0, 0.0, 1.0]],
[[0.0, 0.0, 1.0],
[0.0, 0.0, 1.0]]
])
# 報酬 R[s, a, s']
R = np.array([
[[5, 10, 0],
[-1, 2, 0]],
[[0, 0, 1],
[0, 0, 2]],
[[0, 0, 0],
[0, 0, 0]]
])
# 割引率
gamma = 0.9
# 価値関数の初期化
V = np.zeros(num_states)
このコードは、状態・行動・次状態の組み合わせに対する遷移確率と報酬を3次元のNumPy配列で表現しています。これにより、価値反復の計算が行いやすくなります。
以上の準備が整えば、次のステップとして価値反復のループ処理を実装し、収束するまで価値関数を更新していくことが可能です。初心者の方はまずは小さな環境で試し、動作を理解しながらステップアップしていくことをおすすめします。
環境設定と必要なライブラリの紹介
価値反復法をPythonで実装するためには、まず環境設定と必要なライブラリの準備が欠かせません。特に初心者の方は、Pythonの基本的なインストール方法から始め、主要なデータ処理や数値計算に役立つライブラリを揃えることが重要です。
価値反復法は強化学習の基礎的なアルゴリズムの一つで、状態価値関数 \( V(s) \) を更新して最適な方策を見つけます。更新式は以下のように表されます。
価値反復法の更新式:
\[
V_{k+1}(s) = \max_a \sum_{s’} P(s’|s,a) \left[ R(s,a,s’) + \gamma V_k(s’) \right]
\]
ここで、
- \( s \):現在の状態
- \( a \):行動
- \( s’ \):次の状態
- \( P(s’|s,a) \):遷移確率
- \( R(s,a,s’) \):報酬
- \( \gamma \):割引率(0 < \gamma < 1)
- \( V_k \):k回目の価値関数
この数式をPythonで効率的に扱うために、以下のライブラリを用意します。
- NumPy: 配列計算や行列演算に不可欠です。遷移確率や価値関数の計算で高速に処理できます。
- Matplotlib: 学習過程の可視化に使います。価値関数の変化をグラフで確認できます。
それでは、ライブラリのインストール方法と簡単なコード例を示します。
!pip install numpy matplotlib
import numpy as np
import matplotlib.pyplot as plt
このようにインポートした後、価値反復の更新式をコードで表現すると以下のようになります。
def value_iteration(P, R, gamma, theta=1e-6):
V = np.zeros(len(P)) # 状態数に応じた価値関数の初期化
while True:
delta = 0
for s in range(len(P)):
v = V[s]
V[s] = max(sum(P[s][a][s_next] * (R[s][a][s_next] + gamma * V[s_next]) for s_next in range(len(P))) for a in range(len(P[s])))
delta = max(delta, abs(v - V[s]))
if delta < theta:
break
return V
この関数は、遷移確率 \( P \) と報酬 \( R \)、割引率 \( \gamma \) を入力として価値関数を反復的に更新し、収束したら結果を返します。ここでのポイントは、数式の「最大化」と「期待値計算」をコードの「max」と「sum」で忠実に再現していることです。
Pythonコードで価値反復法を実装する方法
価値反復法は、強化学習における基本的なアルゴリズムの一つで、状態の価値関数を反復的に更新して最適な方策を見つけ出します。ここでは、数式の意味を簡単に説明し、それをPythonコードでどのように実装するかを示します。
価値反復法の中心的な更新式は次の通りです:
\[
V_{k+1}(s) = \max_a \sum_{s’,r} p(s’,r|s,a) \left[r + \gamma V_k(s’) \right]
\]
- 解釈:状態 \( s \) の価値 \( V(s) \) は、すべての行動 \( a \) の中で、次の状態 \( s’ \) と報酬 \( r \) の期待値(確率 \( p(s’,r|s,a) \) に基づく)を計算し、割引率 \(\gamma\) を使って将来の価値も考慮した最大値をとることで更新されます。
この更新を状態すべてに対して繰り返し、価値関数が収束するまで行います。以下は、簡単なマルコフ決定過程(MDP)を例にしたPythonコードの実装例です。
import numpy as np
# 状態数と行動数を定義
num_states = 3
num_actions = 2
# 遷移確率と報酬の定義(例として固定値)
# P[s][a] = [(prob, next_state, reward), ...]
P = {
0: {
0: [(1.0, 0, 0)],
1: [(1.0, 1, 5)]
},
1: {
0: [(1.0, 0, 0)],
1: [(1.0, 2, 10)]
},
2: {
0: [(1.0, 2, 0)],
1: [(1.0, 2, 0)]
}
}
gamma = 0.9 # 割引率
theta = 1e-4 # 収束判定の閾値
V = np.zeros(num_states) # 価値関数の初期化
while True:
delta = 0
for s in range(num_states):
v = V[s]
# 各行動の期待値を計算
action_values = []
for a in range(num_actions):
expected_value = 0
for prob, next_state, reward in P[s][a]:
expected_value += prob * (reward + gamma * V[next_state])
action_values.append(expected_value)
# 最大の価値を次の価値として更新
V[s] = max(action_values)
delta = max(delta, abs(v - V[s]))
if delta < theta:
break
print("収束した価値関数:", V)
このコードでは、各状態と行動の遷移確率・報酬を辞書で管理し、価値関数を更新しています。価値がほとんど変化しなくなるまで繰り返すことで、最適な価値関数が得られます。初心者の方は、この基本的な流れを理解し、実際に手を動かしながら試してみるとよいでしょう。
実装コードの詳細解説
価値反復法の実装では、状態価値関数 \( V(s) \) を更新しながら最適な方策を求めます。まず、価値反復法の基本的な更新式は以下の通りです。
状態 \( s \) における価値関数は、すべての行動 \( a \) と次状態 \( s’ \) の期待報酬の和を最大化する形で更新されます:
\[
V_{k+1}(s) = \max_a \sum_{s’} P(s’|s,a) \left[ R(s,a,s’) + \gamma V_k(s’) \right]
\]
ここで、
- \( P(s’|s,a) \):状態遷移確率
- \( R(s,a,s’) \):報酬関数
- \( \gamma \):割引率
この式の意味は、「ある状態で最適な行動を選んだときに得られる即時報酬と、次の状態の価値の割引和の期待値の最大値が、その状態の新しい価値」となります。
実装では、この式を状態ごとに繰り返し計算し、価値関数の変化が十分小さくなるまで続けます。以下にPythonでの簡単な実装例を示します。
def value_iteration(states, actions, transition_probs, rewards, gamma=0.9, theta=1e-4):
V = {s: 0.0 for s in states}
while True:
delta = 0
for s in states:
v = V[s]
action_values = []
for a in actions:
expected_value = 0
for next_s, prob in transition_probs[s][a].items():
r = rewards[s][a][next_s]
expected_value += prob * (r + gamma * V[next_s])
action_values.append(expected_value)
V[s] = max(action_values)
delta = max(delta, abs(v - V[s]))
if delta < theta:
break
return V
このコードのポイントは以下の通りです:
Vは各状態の価値を格納した辞書で、初期値は0に設定。- 各状態で可能なすべての行動について、次状態の価値と報酬の期待値を計算し、最大値を新しい価値に代入。
- 価値関数の変化
deltaが閾値thetaより小さくなるまで繰り返す。
このように、数式の意味を理解した上でコードに落とし込むことで、価値反復法の動作を直感的に捉えやすくなります。特に状態遷移確率や報酬の構造を整理しながら実装することが重要です。
価値反復法の収束条件と確認方法
価値反復法はマルコフ決定過程(MDP)において最適な方策を求める強力な手法ですが、きちんと収束させるためにはいくつかの条件を満たす必要があります。ここでは、価値反復法が収束するための基本的な条件と、その結果を実際に確認する方法について初心者向けに解説します。
価値反復法の収束条件
価値反復法は価値関数 \( V \) を繰り返し更新していく方法であり、更新式は以下のように表されます。
\[
V_{k+1}(s) = \max_a \sum_{s’, r} p(s’, r|s, a) \Bigl[r + \gamma V_k(s’)\Bigr]
\]
ここで、
- \( s \) は状態
- \( a \) は行動
- \( p(s’, r|s, a) \) は状態遷移確率と報酬の確率分布
- \( \gamma \in [0,1) \) は割引率
この更新が収束するためには、割引率 \(\gamma\) が1未満であることが重要です。これは将来の報酬を適切に割り引くことで、価値関数が発散しないようにするためです。さらに、状態数と行動数が有限であることも収束を保証する前提条件となります。
収束の確認方法
実装上では、価値関数の変化が十分小さくなった時点で収束したと判断します。例えば、あるイテレーション \( k \) における最大状態価値の変化量を
\[
\Delta = \max_s |V_{k+1}(s) – V_k(s)|
\]
と定義し、これがあらかじめ定めた閾値(たとえば \(10^{-4}\))を下回れば収束したとみなします。
以下にPythonでの簡単な収束判定の例を示します。
def value_iteration(env, gamma=0.9, theta=1e-4):
V = [0.0 for _ in range(env.n_states)]
while True:
delta = 0
for s in range(env.n_states):
v = V[s]
V[s] = max(sum(p * (r + gamma * V[s_next])
for p, s_next, r, _ in env.P[s][a])
for a in range(env.n_actions))
delta = max(delta, abs(v - V[s]))
if delta < theta:
break
return V
このコードでは、状態ごとに価値関数を更新し、その差分が閾値以下になったらループを抜けます。これにより価値反復法が収束したことを確認できます。
まとめると、価値反復法の収束には「割引率が1未満であること」「状態・行動数が有限であること」が基本条件であり、実装では価値関数の変化量を監視することで収束を確認します。これらを意識することで、安定した最適方策の推定が可能になります。
実装例:簡単な迷路問題での価値反復法
価値反復法は、マルコフ決定過程(MDP)における最適方策を求めるための基本的な手法です。ここでは、簡単な迷路問題を例に取り、価値反復法の数式とPythonコードを通じて理解を深めましょう。
迷路は4×4のグリッドで、あるセルから上下左右に移動可能とします。各状態 \( s \) において、行動 \( a \) を選ぶと次の状態 \( s’ \) に遷移し、報酬 \( R(s,a,s’) \) を受け取ります。目標地点に到達すると報酬が高く、それ以外は移動に小さなコストがかかる設定です。
価値反復法の基本式は以下のベルマン期待方程式の更新です:
\[
V_{k+1}(s) = \max_{a} \sum_{s’} P(s’|s,a) \left[ R(s,a,s’) + \gamma V_k(s’) \right]
\]
ここで、\( V_k(s) \) は反復回数 \( k \) における状態価値関数、\( P(s’|s,a) \) は遷移確率、\( \gamma \) は割引率です。状態価値関数を更新し続けることで、最適な価値関数に収束します。
以下は非常にシンプルな迷路問題に対するPython実装例です。状態空間は16マス、行動は上下左右の4方向で、遷移は確実に隣接セルに移動すると仮定しています。
import numpy as np
# 迷路のサイズ
grid_size = 4
states = grid_size * grid_size
actions = ['up', 'down', 'left', 'right']
gamma = 0.9 # 割引率
theta = 1e-4 # 収束判定の閾値
# 報酬関数の初期化(すべて-1、ゴールは+10)
rewards = -1 * np.ones(states)
goal_state = states - 1
rewards[goal_state] = 10
def step(state, action):
row, col = divmod(state, grid_size)
if action == 'up':
row = max(row - 1, 0)
elif action == 'down':
row = min(row + 1, grid_size - 1)
elif action == 'left':
col = max(col - 1, 0)
elif action == 'right':
col = min(col + 1, grid_size - 1)
next_state = row * grid_size + col
return next_state
def value_iteration():
V = np.zeros(states)
while True:
delta = 0
for s in range(states):
if s == goal_state:
continue # ゴールは価値固定
v = V[s]
v_list = []
for a in actions:
s_next = step(s, a)
v_list.append(rewards[s_next] + gamma * V[s_next])
V[s] = max(v_list)
delta = max(delta, abs(v - V[s]))
if delta < theta:
break
return V
V_optimal = value_iteration()
print("最適価値関数:\n", V_optimal.reshape((grid_size, grid_size)))
このコードは以下の流れで動作します:
- すべての状態の価値関数を初期化(0からスタート)
- 各状態で4つの行動の価値を計算し、最大の価値で更新
- 価値関数の変化量が閾値以下になるまで繰り返す
- 最終的に各状態の最適価値が得られる
今回の例は遷移確率が1で単純化されていますが、確率的な遷移にも拡張可能です。価値反復法は直感的かつ計算効率が良いため、強化学習や最適制御の基礎として非常に重要です。迷路問題のように状態と行動が有限の場合は特に有効で、今回のコードをベースに拡張していくことができます。
価値反復法のメリットとデメリット
価値反復法は強化学習における基本的なアルゴリズムの一つで、最適な方策(ポリシー)を見つけるために状態の価値関数を反復的に更新します。ここでは、価値反復法のメリットとデメリットを初心者の方にも分かりやすく解説します。
価値反復法のメリット
- 収束が保証されている
価値反復法はベルマン最適性方程式に基づいており、理論的に必ず最適な価値関数に収束します。これにより、安定した学習が期待できます。 - 実装がシンプルで理解しやすい
アルゴリズムの基本構造が単純で、状態ごとに価値を更新するだけなので、初心者でも取り組みやすいです。 - 小規模な問題に適している
状態数や行動数が少ない問題では高速に最適解が求まるため、小規模環境の学習に最適です。
価値反復法のデメリット
- 状態空間が大きいと計算量が膨大になる
価値反復法は全ての状態の価値を更新するため、状態数が増えると計算時間やメモリ使用量が急激に増えます。これが「状態空間の呪い」と呼ばれる問題です。 - 連続状態や高次元状態には不向き
状態が連続的または高次元の場合、全状態を列挙できないため、直接的な価値反復は困難です。 - モデル(遷移確率&報酬関数)が既知である必要がある
価値反復法は環境モデルを使って価値を更新するため、遷移確率や報酬が不明な場合は適用できません。
例えば、価値反復法の更新式は以下のように表されます。
V_{k+1}(s) = \max_{a} \sum_{s’} P(s’|s,a) \left[ R(s,a,s’) + \gamma V_k(s’) \right]
\]
ここで、
\(V_k(s)\) は状態 \(s\) の価値関数の k 回目の更新値、
\(P(s’|s,a)\) は状態 \(s\) で行動 \(a\) を取ったときに次の状態 \(s’\) に遷移する確率、
\(R(s,a,s’)\) はその遷移で得られる報酬、
\(\gamma\) は将来の報酬をどれだけ重視するかを示す割引率です。
この式の意味は、「ある状態 \(s\) から取れる行動の中で、次の状態 \(s’\) に遷移したときの報酬と割引価値の期待値が最大になる行動を選び、その期待値を新しい状態価値とする」ということです。
Pythonでの簡単な価値反復法の更新コード例を示します。
# 状態数と行動数
num_states = 5
num_actions = 2
gamma = 0.9
# 遷移確率と報酬(例: P[s][a] = [(prob, next_state, reward), ...])
P = {
0: {0: [(1.0, 1, 5)], 1: [(1.0, 2, 10)]},
1: {0: [(1.0, 3, 0)], 1: [(1.0, 4, 1)]},
2: {0: [(1.0, 3, 2)], 1: [(1.0, 4, 0)]},
3: {0: [(1.0, 3, 0)], 1: [(1.0, 4, 0)]},
4: {0: [(1.0, 4, 0)], 1: [(1.0, 4, 0)]}
}
V = [0.0] * num_states # 価値関数の初期化
for _ in range(100): # 反復回数
new_V = V.copy()
for s in range(num_states):
action_values = []
for a in range(num_actions):
val = 0
for prob, next_s, reward in P[s][a]:
val += prob * (reward + gamma * V[next_s])
action_values.append(val)
new_V[s] = max(action_values)
V = new_V
このように、価値反復法は理論的な裏付けがあり、実装も比較的容易ですが、規模が大きくなると計算負荷が高くなる点に注意が必要です。実際の応用では、これらのメリットとデメリットを理解した上でアルゴリズム選択を行いましょう。
他の強化学習手法との比較
価値反復法は、強化学習の中でも特に基本的かつ理論的にしっかりした手法です。ここでは代表的な他の強化学習手法と比較しながら、価値反復法の特徴を初心者向けに解説します。
- 価値反復法 (Value Iteration)
状態価値関数 \( V(s) \) を繰り返し更新し、最適方策を導きます。
更新は以下のベルマン最適方程式に基づきます:
\[
V_{k+1}(s) = \max_a \sum_{s’} P(s’|s,a) \big[ R(s,a,s’) + \gamma V_k(s’) \big]
\]
これにより、状態ごとの価値を精密に計算し、最適行動を決定します。計算負荷は状態・行動空間の大きさに依存しますが、理論的な収束保証があります。 - 方策反復法 (Policy Iteration)
方策を評価(Policy Evaluation)して状態価値関数を求め、その後方策改善(Policy Improvement)を行う手法です。
価値反復法は方策評価と改善を一度に行うのに対し、方策反復法は明確に分離しています。
実装や理解の面で価値反復法より少し複雑ですが、収束は速い場合があります。 - Q学習 (Q-Learning)
価値反復法はモデルベース(環境の遷移確率 \(P\) と報酬関数 \(R\) を知っている前提)ですが、Q学習はモデルフリーであり、環境の詳細を知らなくても学習可能です。
Q学習の更新式は以下のようになります:
\[
Q(s,a) \leftarrow Q(s,a) + \alpha \Big( r + \gamma \max_{a’} Q(s’,a’) – Q(s,a) \Big)
\]
実際の環境で試行錯誤しながら学習する場面で強力です。
まとめると、価値反復法は環境のモデルが既知で、計算リソースが許す場合に最適解を理論的に導ける強力な手法です。一方で、環境モデルが不明な実世界の問題にはQ学習などのモデルフリー手法が適しています。
以下は価値反復法の簡単なPython実装例です。状態・行動空間が小さい場合に有効です。
import numpy as np
# 状態数と行動数の設定
num_states = 3
num_actions = 2
gamma = 0.9 # 割引率
# 遷移確率P[s,a,s'] と報酬R[s,a,s']の例
P = np.array([
[[0.8, 0.2, 0.0], [0.1, 0.9, 0.0]],
[[0.0, 0.9, 0.1], [0.0, 0.2, 0.8]],
[[0.0, 0.0, 1.0], [0.0, 0.0, 1.0]]
])
R = np.array([
[[5, 10, 0], [0, 0, 0]],
[[0, 5, 10], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0]]
])
V = np.zeros(num_states)
theta = 1e-4 # 収束判定の閾値
while True:
delta = 0
for s in range(num_states):
v = V[s]
Q_sa = np.zeros(num_actions)
for a in range(num_actions):
Q_sa[a] = sum(P[s,a,s_next]*(R[s,a,s_next] + gamma*V[s_next]) for s_next in range(num_states))
V[s] = max(Q_sa)
delta = max(delta, abs(v - V[s]))
if delta < theta:
break
print("最適状態価値関数:", V)
価値反復法を使った応用例
価値反復法は強化学習の基本的なアルゴリズムであり、様々な問題に応用できます。ここでは、初心者でも理解しやすい簡単な迷路問題を例に、価値反復法の応用を解説します。
迷路問題では、エージェントがスタート地点からゴール地点まで最適な経路を見つけることが目的です。状態は迷路内の位置、行動は上下左右の移動、報酬はゴールに到達したときに得られる正の値、それ以外は小さな罰則(例:-0.1)とします。
価値反復法の中心となる更新式は以下の通りです。
式:
\[
V_{k+1}(s) = \max_{a} \sum_{s’} P(s’|s,a) \left[ R(s,a,s’) + \gamma V_k(s’) \right]
\]
ここで、
– \(V_k(s)\) は状態 \(s\) の価値関数の推定(k回目の更新)
– \(a\) は行動
– \(P(s’|s,a)\) は状態遷移確率
– \(R(s,a,s’)\) は遷移時の報酬
– \(\gamma\) は割引率(0〜1の値)
です。
この式は「現在の状態から行動を選び、次の状態の価値と報酬を考慮して価値関数を更新する」ことを意味します。つまり、エージェントは将来の報酬を見越して現在の行動の価値を計算しています。
次に、Pythonでの実装例を示します。ここでは状態遷移確率を単純化し、確定的な遷移のみを考えます。
import numpy as np
# 迷路のサイズ
height, width = 4, 4
# 割引率
gamma = 0.9
# 報酬の定義
reward = np.full((height, width), -0.1)
reward[3, 3] = 1.0 # ゴールの報酬
# 価値関数の初期化
V = np.zeros((height, width))
# 行動(上下左右)
actions = [(-1,0), (1,0), (0,-1), (0,1)]
def is_valid(s):
return 0 <= s[0] < height and 0 <= s[1] < width
for _ in range(100): # 反復回数
new_V = np.copy(V)
for i in range(height):
for j in range(width):
values = []
for a in actions:
ni, nj = i + a[0], j + a[1]
if is_valid((ni,nj)):
values.append(reward[ni,nj] + gamma * V[ni,nj])
else:
values.append(reward[i,j] + gamma * V[i,j]) # 壁にぶつかった場合は現状維持
new_V[i,j] = max(values)
V = new_V
print(np.round(V, 2))
このコードは、各状態からとり得る行動を評価し、最も価値の高い行動を選択することで価値関数を更新しています。実行後、迷路の各セルにおける価値関数が表示され、ゴールに近づくほど価値が高くなることが確認できます。
このように、価値反復法は迷路の最適経路探索やロボットの移動計画など、多様な応用が可能です。数式の理解とシンプルな実装を通して、価値反復法の基本的な仕組みを身につけましょう。
価値反復法の学習を深めるための参考文献
価値反復法を理解し、実際にPythonで実装するためには、基本的な理論から応用まで幅広くカバーした参考文献に触れることが重要です。ここでは、初心者の方が段階的に学習を進められるおすすめの書籍やオンラインリソースを紹介します。
-
書籍:『強化学習(Reinforcement Learning)導入』
強化学習の基礎から価値反復法まで丁寧に解説。数式とともにアルゴリズムの理論的背景を学べます。特に価値反復法の更新式
\[
V_{k+1}(s) = \max_{a} \sum_{s’, r} p(s’, r \mid s, a) \left( r + \gamma V_k(s’) \right)
\]
の意味を理解するのに役立ちます。ここで、\(V_k(s)\)は状態\(s\)の価値関数の第\(k\)回更新後の推定値、\(\gamma\)は割引率です。 -
オンラインチュートリアル:OpenAI Spinning Up
Pythonでの強化学習実装の入門に最適な無料リソース。価値反復法の概念やコード例が実践的に紹介されています。例えば、以下のようなPythonの価値反復法の更新ステップ例が参考になります。for s in states: v = V[s] V[s] = max( sum( prob * (reward + gamma * V[next_state]) for prob, next_state, reward in transitions[s][a] ) for a in actions ) delta = max(delta, abs(v - V[s])) -
論文・解説記事:強化学習の基礎をわかりやすく解説したWeb記事
数式の解説だけでなく、具体的な例題を交えながら価値反復法の動作原理を丁寧に説明。初心者でも理論と実装のつながりを直感的に掴めます。
これらの文献やリソースを活用し、数式の意味を理解した上で、自分でPythonコードを書いてみることが価値反復法の習得には欠かせません。理論と実装を往復しながら学習を進めることで、より深い理解が得られるでしょう。
まとめ:価値反復法の理解と実装のポイント
価値反復法は強化学習の基本的かつ重要なアルゴリズムであり、状態価値関数を繰り返し更新することで最適な方策を求めます。ここまでの解説で、数式による理論的な背景からPythonでの実装までを通じて、その仕組みを具体的に理解できたと思います。
価値反復法の要点を振り返ると以下の通りです。
- 価値関数の更新式:価値反復法はベルマン最適方程式を利用します。具体的には、状態 \( s \) の価値を次のように更新します。
\[
V_{k+1}(s) = \max_{a} \sum_{s’, r} p(s’, r | s, a) \left[ r + \gamma V_k(s’) \right]
\]
- ここで、\( p(s’, r | s, a) \) は状態遷移確率と報酬の確率分布、\( \gamma \) は割引率を表します。
- この式は「今の価値を、行動の中で期待される最大の将来価値+即時報酬に更新する」という意味です。
- 実装では、この更新を全ての状態に対して繰り返し行い、価値関数が収束するまで続けます。
具体的なPython実装例を一部示すと以下のようになります。
def value_iteration(states, actions, transition_prob, rewards, gamma, theta):
V = {s: 0 for s in states}
while True:
delta = 0
for s in states:
v = V[s]
V[s] = max(
sum(
transition_prob[(s, a)][s_next] * (rewards[(s, a, s_next)] + gamma * V[s_next])
for s_next in states
)
for a in actions
)
delta = max(delta, abs(v - V[s]))
if delta < theta:
break
return V
このコードは状態と行動の集合、遷移確率、報酬、割引率、収束判定の閾値を用い、価値関数の更新を繰り返します。収束判定は価値関数の変化量が小さくなったかで判定しています。
価値反復法の理解と実装のポイントは、数式の意味をしっかり捉え、状態・行動・遷移の関係性を整理することにあります。これができると、コードを書く際にも迷わずに済み、アルゴリズムの応用や拡張にも柔軟に対応できるようになります。
最後に、価値反復法は環境のモデル(遷移確率や報酬)が分かっている場合に有効です。モデルフリーな手法と組み合わせることで、より幅広い問題に対応可能ですので、ぜひ基本を押さえた上で他の強化学習アルゴリズムにも挑戦してみてください。