マルコフ決定過程(Markov Decision Process, MDP)は、強化学習や最適化問題で基盤となる数学的枠組みです。状態、行動、報酬、遷移確率を組み合わせて、エージェントが最適な行動方針(ポリシー)を見つけるためのモデルを提供します。初心者にとっては抽象的に感じることも多いですが、Pythonで実際にプログラムを書いてみることで理解が一気に深まります。
本記事では、Pythonのシンプルなコードを通じてマルコフ決定過程の基本構造と動作を学びます。理論だけでなく、実装を通して「なぜその数式が必要なのか」「コードでどう表現されるのか」を丁寧に解説することで、初心者の方でも着実に理解を進められる内容となっています。
この記事で学べることは以下の通りです。
- マルコフ決定過程の基本要素(状態、行動、報酬、遷移確率)
- MDPを表現するPythonプログラムの構造
- 簡単な例で価値関数や方策評価の実装
例えば、マルコフ決定過程では次のような期待累積報酬の定義が重要です。
\[
V^\pi(s) = \mathbb{E}_\pi \left[ \sum_{t=0}^\infty \gamma^t r_t \mid s_0 = s \right]
\]
ここで、\( V^\pi(s) \) は状態 \( s \) における方策 \( \pi \) の価値、\( \gamma \) は割引率、\( r_t \) は時刻 \( t \) の報酬を表します。この数式の意味と計算方法をPythonで追っていきましょう。
今回紹介したPythonプログラムを通して、マルコフ決定過程の本質的な理解が進んだと思います。状態遷移や報酬、割引率を組み合わせて価値関数を計算する流れは、強化学習の基礎として非常に重要な概念です。実際に手を動かしてコードを書くことで、理論と実装のギャップを埋められたのではないでしょうか。
マルコフ決定過程を理解することで、強化学習アルゴリズムの土台が見えてきます。次のステップでは、今回学んだ価値関数の計算をもとに具体的な方策改善や、Q学習などのアルゴリズムに挑戦してみるのがおすすめです。
次に読むと良い関連記事候補の観点としては、「強化学習における方策評価と方策改善の実装解説」が挙げられます。MDPの基礎を踏まえたうえで、実際に最適方策を探索する方法に触れることで、より実践的な知識が身につくでしょう。
- 価値反復法や方策反復法のPython実装
- Q学習やSARSAなどのモデルフリー強化学習アルゴリズム
- OpenAI Gymを使った簡単な強化学習環境の構築
マルコフ決定過程とは何か
マルコフ決定過程(Markov Decision Process、MDP)は、強化学習や最適化問題でよく使われる数学的モデルです。簡単に言うと、「ある状態から次にどう行動すべきか」を考えるための枠組みで、未来の行動の決定に役立ちます。特にPythonを使ったデータサイエンスの現場では、MDPを用いてエージェントの行動選択や報酬の最大化をシミュレーションすることが多いです。
MDPは以下の4つの要素で構成されています:
- 状態(State) \( S \): エージェントがいる環境の状況を表します。
- 行動(Action) \( A \): エージェントが取れる選択肢の集合。
- 遷移確率(Transition Probability) \( P(s’|s,a) \): 状態 \(s\) で行動 \(a\) をしたときに次の状態 \(s’\) に移る確率。
- 報酬(Reward) \( R(s,a) \): 状態 \(s\) で行動 \(a\) を取ったときに得られる即時の報酬。
この中でも特に重要なのが「遷移確率」で、これはマルコフ性(過去の状態ではなく現在の状態だけが未来に影響する)を表しています。つまり、次の状態は「現在の状態と行動」にのみ依存し、過去の状態の履歴は関係ありません。
MDPの数学的な表現としては、エージェントがある状態から行動を選び、報酬を受け取りながら次の状態に移る一連の流れを以下のように表します:
状態遷移の確率
\[
P(s’|s,a) = \Pr(S_{t+1} = s’ | S_t = s, A_t = a)
\]
ここで、\(S_t\) は時点 \(t\) の状態、\(A_t\) は時点 \(t\) の行動を意味します。この性質を使って、エージェントは将来的な報酬の期待値を最大化しようと行動を選びます。
PythonでMDPの簡単な例を実装すると、状態と行動、遷移確率を辞書や配列で表現できます。以下は、2つの状態と2つの行動を持つMDPの遷移確率の一部を示したコード例です。
transition_probabilities = {
'state1': {
'actionA': {'state1': 0.7, 'state2': 0.3},
'actionB': {'state1': 0.4, 'state2': 0.6}
},
'state2': {
'actionA': {'state1': 0.9, 'state2': 0.1},
'actionB': {'state1': 0.2, 'state2': 0.8}
}
}
このようにMDPはシンプルながら、未来の不確実性を扱いながら最適な行動を決定できる強力なモデルです。次の章で、Pythonを使った具体的なMDPの解法やシミュレーション例を見ていきましょう。
マルコフ決定過程の基本用語解説
マルコフ決定過程(Markov Decision Process, MDP)は、強化学習や最適化問題でよく使われる数学的枠組みです。初心者の方でも理解しやすいように、重要な用語を順に説明します。
- 状態(State, \(s\)): システムがある時点で置かれている状況を表します。例えば、ロボットの位置やゲームの盤面などが状態にあたります。
- 行動(Action, \(a\)): エージェントが状態に応じて選択できる操作や決定のことです。状態から行動を選ぶことでシステムの遷移が起こります。
- 遷移確率(Transition Probability, \(P(s’|s,a)\)): 状態 \(s\) で行動 \(a\) を取ったとき、次の状態が \(s’\) になる確率です。マルコフ性により、この確率は現在の状態と行動だけに依存します。
- 報酬(Reward, \(R(s,a)\)): 状態 \(s\) で行動 \(a\) を取ることで得られる即時の利益や評価値です。エージェントは報酬を最大化することを目指します。
- 方策(Policy, \(\pi(a|s)\)): 状態 \(s\) において、行動 \(a\) を選ぶ確率分布です。最適な方策を見つけることがMDPの目的です。
これらを踏まえたMDPの基本的な数式は以下のように表されます:
状態価値関数 \(V^\pi(s)\) は、方策 \(\pi\) に従ったときの状態 \(s\) からの期待報酬の総和を示します。
\[
V^\pi(s) = \mathbb{E}_\pi \left[ \sum_{t=0}^\infty \gamma^t R(s_t, a_t) \mid s_0 = s \right]
\]
ここで、\(\gamma\) は割引率(0から1までの値)で、将来の報酬の重要度を調整します。
Pythonで状態価値関数を簡単に計算する例を示します。ここでは、状態と行動の組み合わせごとの報酬と遷移確率が与えられたと仮定します。
import numpy as np
# 状態数と行動数
num_states = 3
num_actions = 2
# 割引率
gamma = 0.9
# 報酬行列 R[s, a]
R = np.array([
[5, 10],
[0, -1],
[2, 2]
])
# 遷移確率 P[s, a, s']
P = np.array([
[[0.7, 0.3, 0.0],
[0.4, 0.6, 0.0]],
[[0.1, 0.0, 0.9],
[0.0, 0.8, 0.2]],
[[0.6, 0.4, 0.0],
[0.3, 0.3, 0.4]]
])
# 方策 π[s, a](ここでは均等に選択)
pi = np.ones((num_states, num_actions)) / num_actions
# 価値関数の初期化
V = np.zeros(num_states)
# 価値関数の更新(ベルマン期待方程式)
for _ in range(100):
V_new = np.zeros(num_states)
for s in range(num_states):
for a in range(num_actions):
expected_value = np.sum(P[s, a] * V)
V_new[s] += pi[s, a] * (R[s, a] + gamma * expected_value)
if np.allclose(V, V_new):
break
V = V_new
print("状態価値関数 V:", V)
このコードは、方策に基づく状態価値関数の期待値を反復的に計算しています。実際の強化学習では、これを基に最適方策を探索していきます。
このように、マルコフ決定過程の基本用語と数式、そしてPythonコードを理解することで、強化学習や最適化問題への応用が見えてきます。
状態(State)とは
マルコフ決定過程(MDP)における「状態(State)」とは、システムや環境の現在の状況を表す情報のことを指します。簡単に言うと、状態は「今この瞬間の環境の特徴」を数値や記号で表現したものです。Pythonでマルコフ決定過程を扱う際も、この状態を正しく理解し、モデル化することが重要です。
状態は、将来の行動や報酬に大きく影響を与えます。MDPの基本的な考え方として、次の状態は現在の状態と行動によって決まるという「マルコフ性」があります。これは、過去の状態に依存せず、現在の状態だけで未来が決定されることを意味します。
数式で表すと、状態 \( s_t \) は時間 \( t \) における環境の情報を示し、次の状態 \( s_{t+1} \) は現在の状態 \( s_t \) と行動 \( a_t \) によって確率的に決まります。つまり、遷移確率は以下のように表されます:
\[
P(s_{t+1} | s_t, a_t)
\]
この式は「状態 \( s_t \) で行動 \( a_t \) を取ったときに、次の状態が \( s_{t+1} \) になる確率」です。Pythonでこれを扱うときは、状態を変数や配列、辞書などで表現し、遷移確率を行列や関数で管理します。
以下は簡単なPythonコード例です。ここでは状態を文字列で表し、遷移確率を辞書で管理しています。
states = ['晴れ', '雨']
actions = ['傘を持つ', '傘を持たない']
# 遷移確率の例:current_state, action -> {next_state: probability}
transition_prob = {
('晴れ', '傘を持つ'): {'晴れ': 0.8, '雨': 0.2},
('晴れ', '傘を持たない'): {'晴れ': 0.7, '雨': 0.3},
('雨', '傘を持つ'): {'晴れ': 0.4, '雨': 0.6},
('雨', '傘を持たない'): {'晴れ': 0.1, '雨': 0.9},
}
このように、状態はMDPの基盤となる情報単位であり、Pythonプログラムでは扱いやすいデータ構造で表現します。状態を適切に設計することで、より現実的かつ効率的なマルコフ決定過程のモデル構築が可能になります。
行動(Action)とは
マルコフ決定過程(MDP)における行動(Action)は、エージェントが環境に対して取ることのできる選択肢のことを指します。簡単に言えば、ある状態(State)にいるときにできる操作や決定のことです。行動は環境の状態に影響を与え、次の状態や報酬に繋がります。PythonでMDPを理解する際にもこの行動の概念は非常に重要です。
MDPでは、状態の集合を \( S \)、行動の集合を \( A \) と表記します。例えば、現在の状態が \( s \in S \) のとき、エージェントは行動 \( a \in A \) を選択します。この行動の選択が、次の状態 \( s’ \) と報酬 \( r \) に影響を与えます。
具体的には、行動を選ぶことで確率的に次の状態が決まります。これを数式で表すと、遷移確率は以下のようになります。
\[
P(s’ \mid s, a) = \Pr(\text{次の状態が } s’ \text{ である} \mid \text{現在の状態 } s, \text{行動 } a)
\]
この式は「今の状態 \( s \) と行動 \( a \) に基づいて、次の状態が \( s’ \) となる確率」を表しています。ここで重要なのは、行動によって環境の動きが変わるという点です。つまり、異なる行動をとることで、異なる結果や報酬が得られる可能性があります。
Pythonでの簡単な例を見てみましょう。以下のコードは、状態と行動の組み合わせに対して遷移確率を定義したものです。
# 状態s0で可能な行動a0, a1を定義
states = ['s0', 's1', 's2']
actions = ['a0', 'a1']
# 遷移確率の辞書 (状態, 行動) -> 次の状態の確率分布
transition_probabilities = {
('s0', 'a0'): {'s1': 0.8, 's2': 0.2},
('s0', 'a1'): {'s2': 1.0},
('s1', 'a0'): {'s0': 1.0},
('s1', 'a1'): {'s2': 1.0},
('s2', 'a0'): {'s2': 1.0},
('s2', 'a1'): {'s0': 0.5, 's1': 0.5}
}
このように、状態と行動の組み合わせごとに次の状態の確率が決まっています。エージェントはどの行動を選ぶかによって、環境の未来の状態が変わるため、行動選択はMDPの中核的役割を担います。
まとめると、マルコフ決定過程における行動(Action)は、エージェントが環境に対して取る操作や選択肢であり、状態遷移や報酬に直接影響を与えます。PythonでMDPを実装する際も、行動の定義とその影響を理解することが不可欠です。
報酬(Reward)とは
マルコフ決定過程(MDP)における「報酬」とは、エージェント(プログラム)がある状態で特定の行動を取った結果として得られる価値や利益を指します。報酬はエージェントの行動を評価し、目標達成に向けて学習を促す重要な要素です。PythonでMDPを扱う際も、この報酬を正しく理解し設計することが、効果的なモデル構築につながります。
具体的には、報酬は以下のように定義されます。
ある状態 \( s \) で行動 \( a \) を取ったときの報酬を \( R(s, a) \) と表すと、
\[
R(s, a) = \text{その行動によって得られる即時の価値}
\]
この式はシンプルですが、実際には問題設定によって報酬の値はさまざまです。例えば、迷路の出口にたどり着いたときに高い報酬を与えたり、不要な動作には罰則的な負の報酬を与えたりします。
Pythonで報酬関数を実装する簡単な例を見てみましょう。ここでは、状態が「ゴール」に達した場合に+10、それ以外は0の報酬を返す例です。
def reward_function(state, action):
if state == "goal":
return 10
else:
return 0
このように報酬関数は、状態と行動の組み合わせに基づいて数値を返す関数として設計されます。MDPの学習アルゴリズム(例えば強化学習)では、この報酬を最大化する行動方針を見つけることが目的となります。
まとめると、報酬は「どの行動がどれだけ良いか」を数値化した指標であり、マルコフ決定過程における意思決定の根幹をなす概念です。PythonでMDPを扱う際は、まずこの報酬を適切に定義することから始めましょう。
遷移確率(Transition Probability)とは
マルコフ決定過程(MDP)における「遷移確率」とは、ある状態から別の状態へ移る確率のことを指します。具体的には、「現在の状態」と「取った行動」に基づいて次にどの状態に遷移するかが確率的に決まるため、これを定量的に表したものが遷移確率です。
数学的には、状態集合を \( S \)、行動集合を \( A \) とすると、遷移確率は以下のように表されます。
式:
\[
P(s’ \mid s, a) = \text{状態 } s \text{ で行動 } a \text{ を選択したとき、次の状態が } s’ \text{ となる確率}
\]
この式の意味は、「今の状態 \( s \) で行動 \( a \) をしたら、次の状態が \( s’ \) になる確率は \( P(s’ \mid s, a) \) である」ということです。マルコフ決定過程の重要な特徴は、この確率が「現在の状態と行動の組み合わせ」にのみ依存し、過去の状態には依存しないという点です。
例えば、Pythonで遷移確率を表現する場合は、辞書(ディクショナリ)を使って以下のように書けます。
transition_probabilities = {
('状態1', '行動A'): {'状態1': 0.7, '状態2': 0.3},
('状態2', '行動B'): {'状態1': 0.4, '状態3': 0.6},
}
このコードは、「状態1で行動Aを取ると、70%の確率で状態1に、30%の確率で状態2に遷移する」という意味になります。こうした遷移確率を使って、次の状態の予測や最適な行動選択を行うのがMDPの基本的な考え方です。
Pythonでマルコフ決定過程を扱う準備
マルコフ決定過程(MDP)は、状態と行動の組み合わせから最適な意思決定を導くための数学的フレームワークです。PythonでMDPを扱うには、基本的なライブラリのインストールと、数式の理解から始めることが重要です。ここでは初心者向けに、MDPの基本構成要素とPython環境の準備について解説します。
マルコフ決定過程の基本構成
MDPは以下の4つの要素で定義されます。
- 状態空間 \( S \):システムが取りうる状態の集合
- 行動空間 \( A \):各状態で選択可能な行動の集合
- 遷移確率 \( P(s’|s,a) \):状態 \( s \) で行動 \( a \) を取ったとき、次の状態が \( s’ \) になる確率
- 報酬関数 \( R(s,a) \):状態 \( s \) で行動 \( a \) を取ったときに得られる報酬
これらをまとめて、MDPは「状態の遷移と報酬を確率的にモデル化したもの」と表現できます。Pythonで取り扱う際には、これらの要素をデータ構造で表現する必要があります。
Python環境の準備
まずは、MDPの実装に役立つライブラリをインストールしましょう。代表的なものに以下があります。
numpy:数値計算用ライブラリmatplotlib:グラフ描画用ライブラリ(結果の可視化に便利)gym(OpenAI Gym):強化学習環境の提供
インストールは以下のコマンドで行います。
!pip install numpy matplotlib gym
これらを使うことで、MDPの状態や遷移確率を効率的に扱い、シミュレーションや学習が行いやすくなります。
数式の理解からコードへの落とし込み
例えば、遷移確率は以下のように表されます。
\[ P(s’|s,a) = \text{次の状態 } s’ \text{ への遷移確率} \]
この確率をPythonで表現する場合、状態と行動の組み合わせに対して辞書や多次元配列を使います。例えば、3つの状態と2つの行動がある場合、遷移確率は以下のように定義できます。
import numpy as np
# 状態数と行動数
num_states = 3
num_actions = 2
# 遷移確率 P[s, a, s']
P = np.zeros((num_states, num_actions, num_states))
# 例:状態0で行動1を取った場合の遷移確率
P[0, 1, 0] = 0.7 # 同じ状態に戻る確率
P[0, 1, 1] = 0.3 # 状態1に遷移する確率
# 状態2へは遷移しないため0のまま
このように数式の意味を理解した上で、Pythonの配列にデータを格納することで、マルコフ決定過程のモデルをプログラムで扱えるようになります。
Pythonでの状態と行動の定義方法
マルコフ決定過程(MDP)をPythonで扱う際、まずは「状態(state)」と「行動(action)」をどのように定義するかが重要です。状態は環境の現在の状況を表し、行動はエージェントがとりうる選択肢を示します。初心者にも分かりやすく、シンプルな例とともに解説します。
まず、状態と行動は一般的に集合として扱われます。これを数式で表すと、状態空間 \( S \)、行動空間 \( A \) として定義されます。
例えば、状態を整数のリスト、行動を文字列のリストで表現することができます。
式としては以下のように表せます。
\[
S = \{s_1, s_2, \ldots, s_n\} \quad,\quad A = \{a_1, a_2, \ldots, a_m\}
\]
ここで、Pythonコードでの定義例を示します。
states = ['状態1', '状態2', '状態3']
actions = ['行動A', '行動B']
このようにリストで管理することで、後から状態や行動を追加・変更しやすくなります。さらに、状態や行動に意味を持たせたい場合は、辞書やクラスを使って詳細を持たせる方法もあります。
例えば状態をタプルで表現し、位置情報などを含める場合は:
states = [(0, 0), (0, 1), (1, 0), (1, 1)]
actions = ['上', '下', '左', '右']
このように定義した状態と行動を元に、遷移確率や報酬関数を設計していくことになりますが、まずは基本の定義をしっかり理解することがMDP実装の第一歩です。
遷移確率行列の作成方法
マルコフ決定過程(MDP)において、遷移確率行列は次の状態への遷移確率を定量的に表現する重要な要素です。遷移確率行列は、状態と行動の組み合わせに対して、次の状態への確率を示す行列で、これを正確に作成することがMDPのモデル化では欠かせません。
まず、遷移確率行列は一般的に以下のように定義されます。状態集合を \( S = \{s_1, s_2, \ldots, s_n\} \)、行動集合を \( A = \{a_1, a_2, \ldots, a_m\} \) としたとき、遷移確率は
\[
P(s’|s, a) = \Pr(s_{t+1} = s’ \mid s_t = s, a_t = a)
\]
ここで、\( P(s’|s, a) \) は「状態 \( s \) で行動 \( a \) を取ったとき、次の状態が \( s’ \) になる確率」を示しています。
Pythonでこの遷移確率行列を作成するには、まず状態と行動のインデックスを用意し、3次元の配列や辞書で確率を管理する方法が一般的です。以下は、簡単な例として3つの状態と2つの行動を持つMDPの遷移確率行列をnumpyで作成するコードです。
import numpy as np
# 状態数と行動数
num_states = 3
num_actions = 2
# 遷移確率行列の初期化(状態, 行動, 次状態)
P = np.zeros((num_states, num_actions, num_states))
# 状態0で行動0を取ったときの遷移確率
P[0, 0, :] = [0.8, 0.2, 0.0]
# 状態0で行動1を取ったときの遷移確率
P[0, 1, :] = [0.1, 0.9, 0.0]
# 状態1で行動0を取ったときの遷移確率
P[1, 0, :] = [0.0, 0.7, 0.3]
# 状態1で行動1を取ったときの遷移確率
P[1, 1, :] = [0.4, 0.6, 0.0]
# 状態2で行動0を取ったときの遷移確率
P[2, 0, :] = [0.3, 0.0, 0.7]
# 状態2で行動1を取ったときの遷移確率
P[2, 1, :] = [0.5, 0.0, 0.5]
この例では、3次元の配列 P の要素 P[s, a, s'] が遷移確率 \( P(s’|s,a) \) に対応しています。各状態と行動の組み合わせについて、次の状態への遷移確率の合計が1になるように設定します。
実際の問題では、遷移確率はデータに基づいて推定したり、専門家の知見から設定したりします。Pythonでは他にも辞書型で表現する方法や、Pandasを用いて管理する方法もあり、状況に応じて使い分けると良いでしょう。
報酬関数の実装方法
マルコフ決定過程(MDP)において、報酬関数はエージェントがどの状態や行動を取るべきかを判断する重要な基準です。報酬関数は一般に、ある状態 \( s \) と行動 \( a \) の組み合わせに対して数値的な「報酬」\( R(s, a) \) を与えます。これにより、エージェントは将来的に得られる報酬の最大化を目指して行動を選択します。
具体的には、報酬関数は以下のように定義されます。
\[
R: S \times A \rightarrow \mathbb{R}
\]
ここで、\( S \) は状態空間、\( A \) は行動空間を表します。例えば、迷路探索の問題では、ゴールに到達する状態では高い正の報酬を与え、壁にぶつかる行動では負の報酬を与えるなど、状況に応じた設計が必要です。
Pythonで報酬関数を実装する際は、辞書や関数を使って簡単に表現可能です。以下は、状態と行動をキーとした辞書を用いた例です。
# 状態と行動の組み合わせに対する報酬を定義
rewards = {
('状態1', '行動A'): 10,
('状態1', '行動B'): -1,
('状態2', '行動A'): 0,
('状態2', '行動B'): 5,
}
def reward_function(state, action):
return rewards.get((state, action), 0) # デフォルト報酬は0
上記のコードでは、例えば状態1で行動Aを取ると報酬が10、行動Bだと-1となります。未定義の組み合わせは0として扱います。このようにシンプルに設定できるため、初心者でも扱いやすい実装です。
さらに複雑な問題では、報酬関数が状態の属性や行動の効果から動的に計算される場合もあります。その際は関数内で計算ロジックを組み込み、数式的な関係を反映させることも可能です。
まとめると、報酬関数はエージェントの行動指針を示すための数値的評価基準であり、Pythonでは辞書や関数を活用して柔軟に実装できます。これがマルコフ決定過程での学習や最適化の第一歩となります。
“`html
Pythonでの方策(Policy)とは
マルコフ決定過程(MDP)における「方策(Policy)」とは、エージェントがどの状態でどの行動を取るかを決定するルールや戦略のことを指します。簡単に言うと、エージェントが環境内でどう動くかを定める設計図のようなものです。
方策は通常、状態を入力として行動を出力する関数として表されます。数学的には、方策 \(\pi\) は以下のように定義されます。
\[
\pi(a|s) = P(A_t = a \mid S_t = s)
\]
ここで、\(\pi(a|s)\) は「状態 \(s\) にいるとき、行動 \(a\) を取る確率」を示します。確率的な方策の場合、複数の行動を選ぶ可能性がありますが、決定的な方策では最も良い行動を1つだけ選びます。
Pythonで方策を表現するときは、辞書や関数で状態と行動の対応を表すことが多いです。例えば、決定的な方策を辞書で実装する場合は以下のようになります。
policy = {
'状態1': '行動A',
'状態2': '行動B',
'状態3': '行動C',
}
また、状態を引数に取り、適切な行動を返す関数として定義することも可能です。
def policy(state):
if state == '状態1':
return '行動A'
elif state == '状態2':
return '行動B'
else:
return '行動C'
このように、方策はエージェントの行動選択の根幹をなすものであり、マルコフ決定過程における最適化の対象となります。Pythonを用いることで、方策の定義や更新、評価を柔軟に実装し、MDPの理解を深められます。
“`
方策評価の基本とPython実装
マルコフ決定過程(MDP)における「方策評価」とは、ある方策(policy)に従ったときの状態の価値関数(Value Function)を計算するプロセスです。価値関数は、今いる状態から始めて、その方策に従うことで将来得られる報酬の期待値を表します。これにより、方策の良し悪しを定量的に評価できます。
具体的には、状態価値関数 \( V^\pi(s) \) は以下のベルマン期待方程式で定義されます。
式:
\[
V^\pi(s) = \sum_{a} \pi(a|s) \sum_{s’} P(s’|s,a) \left[ R(s,a,s’) + \gamma V^\pi(s’) \right]
\]
ここで、
- \( \pi(a|s) \):状態 \( s \) で行動 \( a \) を選ぶ確率(方策)
- \( P(s’|s,a) \):状態 \( s \) で行動 \( a \) をとったときに次の状態 \( s’ \) に遷移する確率
- \( R(s,a,s’) \):状態 \( s \) で行動 \( a \) をとり、状態 \( s’ \) に遷移したときの報酬
- \( \gamma \):割引率(0 ≤ \( \gamma \) < 1)で将来の報酬をどれだけ重視するかを決定
この式は再帰的であるため、実際の計算は反復的に行います。Pythonでの実装例を以下に示します。ここでは簡単のため、方策は確定的であり状態と行動の空間も小さいものとします。
import numpy as np
# 状態数と行動数
num_states = 3
num_actions = 2
# 方策 π(s) = a (確定的方策の例)
policy = np.array([0, 1, 0]) # 各状態で選ぶ行動
# 遷移確率 P(s'|s,a)
P = np.array([
[[0.7, 0.3, 0.0], [0.4, 0.6, 0.0]], # s=0 の場合のa=0, a=1
[[0.1, 0.9, 0.0], [0.5, 0.0, 0.5]], # s=1 の場合
[[0.0, 0.0, 1.0], [0.0, 0.0, 1.0]] # s=2 の場合(終端状態)
])
# 報酬 R(s,a,s')
R = np.array([
[[5, 10, 0], [0, 0, 0]],
[[-1, 2, 0], [1, 0, 4]],
[[0, 0, 0], [0, 0, 0]]
])
gamma = 0.9 # 割引率
def policy_evaluation(policy, P, R, gamma, theta=1e-5):
V = np.zeros(num_states)
while True:
delta = 0
for s in range(num_states):
a = policy[s]
v = V[s]
V[s] = sum(P[s, a, s_prime] * (R[s, a, s_prime] + gamma * V[s_prime]) for s_prime in range(num_states))
delta = max(delta, abs(v - V[s]))
if delta < theta:
break
return V
V = policy_evaluation(policy, P, R, gamma)
print("方策評価による状態価値関数:", V)
このコードは、指定された方策に従って状態価値関数を反復的に計算しています。評価が収束すると、各状態における将来の期待報酬が得られ、方策の効果を直感的に理解できます。初心者の方は、実際にコードを動かしながら、方策や割引率を変えて結果の違いを試すことで、マルコフ決定過程の基礎を深く学べるでしょう。
方策改善の考え方とコード例
マルコフ決定過程(MDP)における「方策改善」とは、現在の方策(policy)を評価し、それをより良い方策へと更新するプロセスです。具体的には、状態ごとに最も価値の高い行動を選び直すことで、報酬を最大化する方向へと方策を改善します。
方策改善の基本的な考え方は以下の通りです。
- 現在の方策に基づく状態価値関数 \( V^{\pi}(s) \) を求める(方策評価)
- その価値関数を使って、各状態で取るべき最適な行動を見つける
- 新たな方策 \( \pi’ \) は、各状態で最も価値の高い行動を選択する方策となる
この手順は、数式で表すと以下のようになります。状態 \( s \) における新しい方策は、行動 \( a \) の価値(行動価値関数)を比較し、最大のものを選びます。
\[
\pi'(s) = \arg\max_a \sum_{s’, r} p(s’, r \mid s, a) \left[ r + \gamma V^{\pi}(s’) \right]
\]
ここで、
– \( p(s’, r \mid s, a) \) は状態 \( s \) で行動 \( a \) を取ったときの遷移確率と報酬の確率分布
– \( \gamma \) は割引率(0 < \( \gamma \) < 1)
– \( V^{\pi}(s’) \) は次状態の価値関数
を意味します。
次に、Pythonでの簡単な方策改善のコード例を示します。ここでは、既に状態価値関数 \( V \) が計算されていると仮定し、環境の遷移確率を辞書形式で管理しています。
def policy_improvement(V, states, actions, transition_probs, gamma):
new_policy = {}
for s in states:
action_values = {}
for a in actions:
value = 0
for (prob, next_state, reward) in transition_probs[(s, a)]:
value += prob * (reward + gamma * V[next_state])
action_values[a] = value
# 最も価値の高い行動を選択
best_action = max(action_values, key=action_values.get)
new_policy[s] = best_action
return new_policy
この関数のポイントは、各状態 \( s \) で可能な行動 \( a \) をすべて評価し、その期待値が最大となる行動を選んでいる点です。これにより、方策は段階的に最適解へと近づいていきます。
初心者の方は、まず環境の遷移確率や報酬の構造を理解し、状態価値関数の計算から実装してみることをお勧めします。そうすることで、方策改善の意味と効果がより実感しやすくなるでしょう。
価値反復法の理論とPython実装
マルコフ決定過程(MDP)における価値反復法は、最適な行動方針(ポリシー)を見つけるための基本的なアルゴリズムです。価値反復法では、状態ごとの「価値関数」を繰り返し更新し、最終的に最適価値関数を求めます。
価値反復法の核となる数式はベルマン方程式で、状態 \(s\) の価値 \(V(s)\) は次のように表されます。
まず、現在の価値関数 \(V_k(s)\) を使って、次の価値関数 \(V_{k+1}(s)\) を更新します:
\[
V_{k+1}(s) = \max_{a \in A} \sum_{s’} P(s’|s,a) \left[ R(s,a,s’) + \gamma V_k(s’) \right]
\]
- \(A\):可能な行動の集合
- \(P(s’|s,a)\):状態 \(s\) で行動 \(a\) を取ったとき、次の状態が \(s’\) になる確率
- \(R(s,a,s’)\):状態遷移に伴う報酬
- \(\gamma\):割引率(0から1の値で将来の報酬の重要度を調整)
この式は、「現在の状態でどの行動を選べば将来的な報酬の期待値が最大になるか」を示しており、価値関数の更新を通じて最適解へ収束します。
以下はPythonでの簡単な実装例です。状態数や行動数を小さく設定して、価値関数を反復的に更新しています。
import numpy as np
# 状態数と行動数の定義
num_states = 3
num_actions = 2
gamma = 0.9
# 遷移確率 (状態, 行動, 次状態)
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, 0, 0], [10, 0, 0]],
[[0, 1, 0], [0, 2, 3]],
[[0, 0, 0], [0, 0, 0]]
])
# 価値関数の初期化
V = np.zeros(num_states)
# 価値反復法の反復回数
num_iterations = 100
for _ in range(num_iterations):
V_new = np.zeros(num_states)
for s in range(num_states):
action_values = []
for a in range(num_actions):
value = 0
for s_prime in range(num_states):
value += P[s, a, s_prime] * (R[s, a, s_prime] + gamma * V[s_prime])
action_values.append(value)
V_new[s] = max(action_values)
V = V_new.copy()
print("最適価値関数:", V)
このコードでは、遷移確率と報酬を3状態・2行動の小さなモデルで定義し、100回の反復計算により状態ごとの価値を更新しています。最終的に得られた価値関数は、どの状態が将来的に期待値の高い報酬をもたらすかを示しています。
価値反復法は、強化学習の基礎であり、Pythonを使って理解するとマルコフ決定過程の理論が具体的にイメージしやすくなります。ぜひ自分でパラメータを変えて試し、動きを観察してみてください。
方策反復法の理論とPython実装
マルコフ決定過程(MDP)における方策反復法は、最適な行動方針(方策)を見つけるための代表的なアルゴリズムです。方策反復法は、方策評価と方策改善の2つのステップを交互に繰り返すことで、最適方策に収束します。
方策反復法の理論
まず、現在の方策 \(\pi\) に対して、その価値関数 \(V^\pi(s)\) を求めます。これは「方策評価」と呼ばれ、以下のベルマン方程式を満たします:
\[
V^\pi(s) = \sum_{a} \pi(a|s) \sum_{s’,r} p(s’,r|s,a) \left[ r + \gamma V^\pi(s’) \right]
\]
ここで、
- \(s\):状態
- \(a\):行動
- \(\pi(a|s)\):状態 \(s\) で行動 \(a\) を選択する確率
- \(p(s’,r|s,a)\):状態遷移確率と報酬の分布
- \(\gamma\):割引率(0 < \(\gamma\) < 1)
次に「方策改善」として、状態ごとに次の方策を更新します:
\[
\pi'(s) = \arg\max_a \sum_{s’,r} p(s’,r|s,a) \left[ r + \gamma V^\pi(s’) \right]
\]
方策評価と方策改善を繰り返すことで、方策は最適方策に収束します。
Pythonでの簡単な実装例
以下は、状態数と行動数が小さい場合の方策反復法のシンプルな実装例です。ここでは遷移確率と報酬を辞書で管理し、割引率 \(\gamma = 0.9\) としています。
import numpy as np
# 状態数と行動数
num_states = 3
num_actions = 2
# 割引率
gamma = 0.9
# 遷移確率と報酬の定義 (例)
# P[state][action] = [(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, 0, 0)]
}
}
# 初期方策(ランダム)
policy = np.zeros(num_states, dtype=int)
def policy_evaluation(policy, P, gamma, theta=1e-6):
V = np.zeros(num_states)
while True:
delta = 0
for s in range(num_states):
v = 0
a = policy[s]
for prob, next_s, reward in P[s][a]:
v += prob * (reward + gamma * V[next_s])
delta = max(delta, abs(V[s] - v))
V[s] = v
if delta < theta:
break
return V
def policy_improvement(V, P, gamma):
policy_stable = True
new_policy = np.zeros(num_states, dtype=int)
for s in range(num_states):
action_values = np.zeros(num_actions)
for a in range(num_actions):
for prob, next_s, reward in P[s][a]:
action_values[a] += prob * (reward + gamma * V[next_s])
best_action = np.argmax(action_values)
new_policy[s] = best_action
if best_action != policy[s]:
policy_stable = False
return new_policy, policy_stable
# 方策反復法のメインループ
while True:
V = policy_evaluation(policy, P, gamma)
policy, stable = policy_improvement(V, P, gamma)
if stable:
break
print("最適方策:", policy)
print("価値関数:", V)
このコードでは、初期方策から価値関数を評価し、方策改善で方策を更新します。安定(変化なし)になった時点でループを終了し、最適方策とその価値関数を出力します。初心者の方は、この流れを理解しながら、実際に手を動かして試してみることをおすすめします。
マルコフ決定過程のシミュレーション例
マルコフ決定過程(MDP)を理解するためには、実際にPythonで簡単なシミュレーションを行うことが非常に有効です。ここでは、状態と行動が限られたシンプルな環境を想定し、状態遷移確率や報酬を定義して動作を確認します。
まず、MDPの基本は以下の4つの要素です。
- 状態集合 \( S \)
- 行動集合 \( A \)
- 遷移確率 \( P(s’|s,a) \) : 状態 \( s \) で行動 \( a \) を取ったときに次の状態が \( s’ \) になる確率
- 報酬関数 \( R(s,a,s’) \) : 状態遷移に伴う報酬
例えば、状態が2つ(0, 1)、行動が2つ(0, 1)ある環境を考え、遷移確率を以下のように定義します。
具体的には、状態0で行動0を取ると状態0に90%、状態1に10%遷移し、報酬は状態1に遷移したときに1、それ以外は0とします。
この遷移確率は数式で表すと、
\[
P(s’|s=0,a=0) = \begin{cases}
0.9 & s’ = 0 \\
0.1 & s’ = 1
\end{cases}
\quad,\quad
R(s=0,a=0,s’) = \begin{cases}
1 & s’ = 1 \\
0 & \text{else}
\end{cases}
\]
これをPythonで表現し、簡単なシミュレーションを実装してみます。
class SimpleMDP:
def __init__(self):
# 遷移確率の定義 (状態, 行動) → {次状態: 確率}
self.P = {
(0, 0): {0: 0.9, 1: 0.1},
(0, 1): {1: 1.0},
(1, 0): {0: 0.5, 1: 0.5},
(1, 1): {1: 1.0}
}
# 報酬関数 (状態, 行動, 次状態) → 報酬値
self.R = {
(0, 0, 1): 1,
(0, 1, 1): 1,
(1, 0, 0): 0,
(1, 0, 1): 0,
(1, 1, 1): 0,
(0, 0, 0): 0,
}
def step(self, state, action):
import random
transitions = self.P.get((state, action), {})
next_states = list(transitions.keys())
probabilities = list(transitions.values())
next_state = random.choices(next_states, probabilities)[0]
reward = self.R.get((state, action, next_state), 0)
return next_state, reward
# シミュレーション例
mdp = SimpleMDP()
state = 0
for i in range(10):
action = 0 # ここでは行動0を連続で選択
next_state, reward = mdp.step(state, action)
print(f"Step {i}: 状態 {state} → 行動 {action} → 状態 {next_state}、報酬 {reward}")
state = next_state
このコードは、ある状態から行動を選択し、確率的に次の状態へ遷移、その際に報酬を取得する流れを示しています。初心者でも理解しやすい形でMDPの動きを確認でき、実際の強化学習アルゴリズムの基礎を掴む手助けとなるでしょう。
Pythonでのマルコフ決定過程の可視化方法
マルコフ決定過程(MDP)を理解するうえで、状態遷移や報酬構造を視覚的に把握することは非常に有効です。Pythonでは、状態空間や遷移確率をグラフとして表現することで、どのように状態が遷移していくのかを直感的に理解できます。
まず、MDPの基本的な数式として、状態$s$から状態$s’$へ遷移する確率を表す遷移行列$P$があります。これは以下のように定義されます。
P(s, s’) = \Pr(s_{t+1} = s’ \mid s_t = s, a_t = a)
\]
ここで、$s_t$は時刻$t$の状態、$a_t$は時刻$t$に選択した行動です。Pythonでこの遷移行列を可視化するには、ネットワークグラフを使う方法が一般的です。たとえば、networkxとmatplotlibを利用して、状態をノード、遷移確率をエッジの重みとして表現します。
以下に簡単な例を示します。4つの状態とそれぞれの遷移確率を辞書形式で定義し、それを基に有向グラフを描画します。
import networkx as nx
import matplotlib.pyplot as plt
# 状態遷移の定義(状態sから状態s'への遷移確率)
transitions = {
0: {1: 0.8, 2: 0.2},
1: {2: 0.6, 3: 0.4},
2: {3: 1.0},
3: {}
}
G = nx.DiGraph()
# ノード追加
for s in transitions.keys():
G.add_node(s)
# エッジ追加
for s, next_states in transitions.items():
for s_prime, prob in next_states.items():
G.add_edge(s, s_prime, weight=prob)
pos = nx.spring_layout(G)
# エッジラベル(遷移確率)を作成
edge_labels = {(s, s_prime): f"{prob:.2f}" for s, next_states in transitions.items() for s_prime, prob in next_states.items()}
nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=1500, arrowsize=20)
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_color='red')
plt.title("マルコフ決定過程の状態遷移図")
plt.show()
このコードでは、transitions辞書で各状態からの遷移先とその確率を管理し、networkxで有向グラフを生成しています。エッジには遷移確率をラベルとして表示し、グラフ全体で状態遷移のイメージを掴みやすくしています。
このような可視化は、MDPの解析や方策改善を行う際に、現在のモデルの挙動を確認するための重要なステップです。初心者の方も、まずはこのような小規模な例から試し、状態遷移の感覚を掴むことをおすすめします。
実践!簡単な迷路問題にマルコフ決定過程を適用
ここでは、Pythonを使って簡単な迷路問題にマルコフ決定過程(MDP)を適用する方法を初心者向けに解説します。MDPは「状態」「行動」「報酬」「遷移確率」の4つの要素から成り立ち、迷路のような環境で最適な行動を決定するための強力なモデルです。
迷路問題の設定
まず、3×3の小さな迷路を考えます。各マスが状態で、上下左右に移動する行動が可能です。迷路の端では移動できない方向もあります。報酬はゴールに到達したときに+10、それ以外は-1とします。
MDPの数式表現とコード例
状態を \( s \)、行動を \( a \)、遷移確率を \( P(s’|s,a) \)、報酬を \( R(s,a,s’) \) と表すと、価値関数 \( V(s) \) は以下のベルマン期待方程式で定義されます。
式:
\[ V(s) = \max_a \sum_{s’} P(s’|s,a) \left[ R(s,a,s’) + \gamma V(s’) \right] \]
ここで、割引率 \( \gamma \) は将来の報酬の重要度を示します。
この式は、状態 \( s \) で最適な行動 \( a \) を選ぶことで得られる最大の期待総報酬を表しています。
以下はPythonで価値反復法を使ってこの迷路の価値関数を求める簡単なコード例です。
import numpy as np
# 迷路サイズ
n = 3
states = [(i, j) for i in range(n) for j in range(n)]
actions = ['up', 'down', 'left', 'right']
gamma = 0.9 # 割引率
reward_goal = 10
reward_step = -1
def next_state(state, action):
i, j = state
if action == 'up' and i > 0:
return (i-1, j)
elif action == 'down' and i < n-1:
return (i+1, j)
elif action == 'left' and j > 0:
return (i, j-1)
elif action == 'right' and j < n-1:
return (i, j+1)
return state
goal = (0, 2)
V = {s: 0 for s in states} # 価値関数の初期化
# 価値反復法
for _ in range(100):
new_V = V.copy()
for s in states:
if s == goal:
new_V[s] = reward_goal
continue
values = []
for a in actions:
s_next = next_state(s, a)
r = reward_goal if s_next == goal else reward_step
values.append(r + gamma * V[s_next])
new_V[s] = max(values)
V = new_V
# 結果表示
for i in range(n):
for j in range(n):
print(f'{V[(i,j)]:6.2f}', end=' ')
print()
このコードは各状態での最適な価値を計算し、迷路のどの位置からでもゴールに向かう最も効率的な経路を示す指標となります。Pythonでの簡単な実装で、マルコフ決定過程の基本的な考え方を体感できるでしょう。
マルコフ決定過程と強化学習の関係
マルコフ決定過程(MDP)は、強化学習の理論的な基盤として非常に重要な役割を果たします。強化学習は、エージェントが環境と相互作用をしながら最適な行動方針(ポリシー)を学習する手法ですが、その環境の動的な変化や報酬の受け取り方を数理的にモデル化するのがMDPです。
具体的には、MDPは以下の要素で構成されます。
- 状態集合 \( S \):エージェントがいる環境の状況
- 行動集合 \( A \):エージェントがとれる行動
- 遷移確率 \( P(s’|s,a) \):状態 \( s \) で行動 \( a \) をとったとき、次の状態が \( s’ \) になる確率
- 報酬関数 \( R(s,a) \):状態 \( s \) で行動 \( a \) をとった際に得られる報酬
- 割引率 \( \gamma \):将来の報酬の現在価値を決めるパラメータ(0から1の間)
このMDPの枠組みの中で、強化学習は最適なポリシー \( \pi^* \) を求めます。最適ポリシーとは、将来の報酬の期待値を最大化する行動選択のルールです。価値関数 \( V^\pi(s) \) は、状態 \( s \) からポリシー \( \pi \) に従って行動したときに得られる期待報酬の合計を表します。以下のベルマン方程式が成り立ちます。
式:
\[
V^\pi(s) = \sum_{a \in A} \pi(a|s) \left[ R(s,a) + \gamma \sum_{s’ \in S} P(s’|s,a) V^\pi(s’) \right]
\]
解釈:現在の状態での価値は、そこからとる行動の選択確率に基づき、得られる即時報酬と割引後の次の状態の価値の期待値の和として表されます。
Pythonで簡単に価値関数の更新を行う例を示します。ここでは状態価値を反復的に計算していく方法(価値反復)を用います。
import numpy as np
# 状態数と行動数の設定
num_states = 3
num_actions = 2
# 遷移確率 P[s, a, s']
P = np.array([
[[0.7, 0.3, 0.0],
[0.4, 0.6, 0.0]],
[[0.0, 0.8, 0.2],
[0.0, 0.9, 0.1]],
[[0.0, 0.0, 1.0],
[0.0, 0.0, 1.0]]
])
# 報酬 R[s, a]
R = np.array([
[5, 10],
[-1, 2],
[0, 0]
])
gamma = 0.9 # 割引率
V = np.zeros(num_states) # 初期状態価値
for _ in range(100): # 反復回数
V_new = np.zeros(num_states)
for s in range(num_states):
action_values = []
for a in range(num_actions):
expected_value = R[s, a] + gamma * np.dot(P[s, a], V)
action_values.append(expected_value)
V_new[s] = max(action_values) # 最適行動の価値を採用
if np.allclose(V, V_new, atol=1e-4):
break
V = V_new
print("最適価値関数:", V)
このように、マルコフ決定過程の概念と数式を理解することは、Pythonで強化学習アルゴリズムを実装し、その動作を解析する上で不可欠です。強化学習はMDPを基盤として、エージェントがどのように環境から学び行動を最適化していくかを示す強力なフレームワークです。
よくあるエラーとトラブルシューティング
マルコフ決定過程(MDP)をPythonで実装する際、初心者が陥りやすいエラーや問題をいくつか紹介します。これらは理解を深める上で重要なポイントであり、トラブルシューティングの参考にしてください。
1. 状態遷移確率の合計が1にならない
MDPでは、ある状態 \( s \) から次の状態 \( s’ \) へ遷移する確率の総和は必ず1でなければなりません。式で表すと、
\[
\sum_{s’ \in S} P(s’|s,a) = 1
\]
ここで、\( P(s’|s,a) \) は状態 \( s \) で行動 \( a \) を取った時に次の状態 \( s’ \) へ遷移する確率です。この合計が1でない場合、プログラムは期待通りに動作しません。
原因としては、遷移確率の設定ミスやリスト・配列の初期化忘れが考えられます。以下のように確認してみましょう。
for s in states:
for a in actions:
total_prob = sum(transition_probs[s][a].values())
if abs(total_prob - 1.0) > 1e-6:
print(f"状態{s}、行動{a}の遷移確率の合計が1ではありません: {total_prob}")
2. 割引率 \(\gamma\) の設定ミス
MDPの価値関数では、将来の報酬を割引率 \(\gamma\) を使って現在価値に換算します。式は
\[
V(s) = \max_a \sum_{s’} P(s’|s,a) \left( R(s,a,s’) + \gamma V(s’) \right)
\]
割引率 \(\gamma\) は通常0以上1以下の値をとり、1を超えると計算が発散する恐れがあります。初心者は0や1を超える値を設定してしまいがちなので注意しましょう。
3. 配列や辞書のキーエラー
状態や行動を辞書のキーとして使う際、存在しないキーを指定するとKeyErrorが発生します。例えば、
value = V[state] # stateがVに存在しないとKeyErrorになる
対策としては、dict.get()メソッドを使うか、事前にキーの存在を確認することです。
value = V.get(state, 0.0)# 存在しなければ0.0を返すif state in V:で存在チェックを行う
これによりプログラムの突然の停止を防げます。
4. まとめ
MDPの実装で多いのは「確率の合計が1でない」「割引率の範囲外」「辞書のキーエラー」などです。これらは基本的な部分ですが、正しく理解・確認することが安定したPythonプログラムの作成には不可欠です。エラー時はエラーメッセージをよく読み、上記のポイントをチェックしてみてください。
まとめ:Pythonで学ぶマルコフ決定過程のポイント
マルコフ決定過程(MDP)は、状態遷移と報酬の関係をモデル化し、最適な行動戦略を導き出すための強力な枠組みです。Pythonを使って実装することで、理論だけでなく実践的な理解も深めることができます。初心者でも理解しやすいように、以下のポイントを押さえておきましょう。
- 状態と行動の定義:MDPは「状態(state)」と「行動(action)」の集合から成り立ちます。Pythonではこれらをリストや辞書で表現し、遷移確率や報酬を数値で管理します。
- 遷移確率の理解:状態\( s \)で行動\( a \)を選択したとき、次の状態\( s’ \)に遷移する確率は\( P(s’|s,a) \)で表されます。これがMDPの核となる部分です。
- 価値関数と方策改善:価値関数\( V(s) \)は状態の「良さ」を評価し、ベルマン方程式で次のように定義されます。
\[
V(s) = \max_a \sum_{s’} P(s’|s,a) \left[ R(s,a,s’) + \gamma V(s’) \right]
\]
ここで、\( R(s,a,s’) \)は報酬、\( \gamma \)は割引率です。Pythonでの実装では、この式を反復計算で近似します。
簡単な価値反復(Value Iteration)の実装例を示します。
def value_iteration(states, actions, P, R, gamma=0.9, theta=1e-6):
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
このコードでは、すべての状態に対して行動ごとの期待価値を計算し、最大値を価値関数の更新に用いています。収束条件は価値関数の変化が十分小さくなったときです。
PythonでMDPを学ぶことで、理論的な数式とアルゴリズムの関係を直感的に理解でき、データサイエンスの応用範囲を広げることができます。ぜひ、自分で環境や報酬設計を試しながら実装を進めてみてください。