강화학습 모델로 주식 매매 에이전트를 개발하던 중 들었던 의문점들과
해결해 나간 부분을 따로 정리하려고 한다.
먼저 내가 만들어야 하는 알고리즘은 Policy based Algorithm이다.
크게 두 가지 뿌리로 나뉘는데,
Q-Learning과 SARSA와 같이 Value-function을 기반으로 하는 Value-based Algorithm과
Policy Gradient를 활용한 Policy-based Algorithm으로 나뉜다.
두 알고리즘의 차이는 아래와 같다.
Value-based : $ Q(S_{t}, a_{t}) $ < 현재 state와 action이 주어졌을 때 앞으로 기대할 수 있는 보상 > 을 Maximize하는 기법
Policy-based : $ P(a_{t}, | S_{t}) $ 현재 state에서 가장 적절한 action을 찾을 수 있는 확률 분포를 찾으려는 기법
내 프로젝트는 주식 시장에서 매수와 매도, 관망이라는 3가지 action을
에이전트가 잘 결정할 수 있도록 Neural Network를 이용한 최적의 Policy를 찾는 방향이다.
여기까지는 사실 표면적으로 Policy Gradient가 단지 Policy에 최적화되는
즉, object function에 Policy parameter만 학습하는 모양새인가 싶었다.
그런데 강화학습은 에이전트에게 주어지는 보상이 있어야하고
Agent가 내린 결정에 대한 보상을 최대화하려는 Greedy한 움직임이 있어야한다는
내 기존 지식과 충돌했다. 목적함수에는 보상함수가 있어야한다. <만약 없다면 그냥 딥러닝이다>
그래서 Policy based가 생겨난 뿌리부터 좀 알아봤다
들어가기에 앞서 알고가면 좋을 것이 있다.
강화학습의 본질은 Reward를 최대화 하는 것이다.
Reward를 최대화하는 방법을 알기 위해선
주어진 state에서 취할 수 있는 가장 적절한 행동이 무엇인지 알아야한다.
예를 들면, 오목에서 상대방을 가장 빨리 이길 수 있는 수를 두는 것이다.
주식시장에서는 가장 저점에서 매수하고 고점에서 파는 액션을 하는 것이다.
Reinforce Algorithm
강화학습의 Object Function은
$ J = E[G_{0}] $
$ = \int_{\tau}G_{0}P(\tau) d\tau$
※ notation
$ \tau = (S_{t}, a_{t}) , t = [0,\infty) $
$ G_{t} = R_{t} + \gamma R_{t+1} + \gamma^{2}R_{t+2} ... $
$ G_{t} \to $ t시점 이후 부터 얻을 수 있는 보상의 합
Policy Gradient의 Object Function은 Policy network의 파라미터인 $\Theta$를 최적화해야하기 때문에,
Object Function이 다음과 같이 표현된다.
$J({\Theta}) = \int_{\tau} P_{\Theta}(\tau) G_{0} d\tau$
이 목적함수는 보상극대화를 목표로하기 때문에 Gradient ascent를 해야한다.
따라서 $ J_{\Theta} \leftarrow J_{\Theta} + \partial\Theta J_{\Theta} $를 따라야한다.
$ \partial J_{\Theta} = \partial_{\Theta} \int_{\tau} P_{\Theta}(\tau)G_{0}d\tau $
$ = \int_{\tau} \partial_{\Theta} P_{\Theta}(\tau)G_{0}d\tau $
$ \tau $ 안에는 수 많은 state와 action이 있다.
이 변수들에 대한 적분이 완료되어야 미분 값을 구할 수 있는데,
참 비효율적인 일이다.
그래서 아래와 같이 식을 변형해서 연산을 줄일 수가 있다.
$ \partial J_{\Theta} = \int G_{0} \partial_{\Theta} P_{\Theta}(\tau)d\tau $
$ = \int G_{0} \partial_{\Theta} ln P_{\Theta}(\tau) P_{\Theta}(\tau) d\tau $ ... <1>
$ =\int (R_{0} + \gamma R_{1} + \gamma^{2} R_{2} + ... ) \partial_{\Theta}(ln P_{\Theta}(s_{0}, a_{0}, s_{1}, a_{1} ...) P_{\Theta}(\tau) d\tau $ ... <2>
$ = \int (R_{0} + \gamma R_{1} + \gamma^{2} R_{2} + ... ) \partial_{\Theta} (ln P_{\Theta}(a_{0} | s_{0} + ln P_{\Theta}(a_{1} | s_{1}) + ...) P_{\Theta}(\tau) d\tau$ ... <3>
$ = \int \sum_{t=0}^{\infty} \partial_{\Theta} ln P_{\Theta}(a_{t} | s_{t}) (\sum_{k=t}^{\infty} \gamma^{k}R_{k}) P_{\Theta}(\tau) d\tau $
$ = \int (\sum_{t=0}^{\infty} \partial_{\Theta} ln P_{\Theta}(a_{t} | s_{t}) G_{t} )P_{\Theta}(\tau) d\tau $ ... <4>
$ = \int (\sum_{t=0}^{\infty} G_{t} \partial_{\Theta} ln P_{\Theta}(a_{t} | s_{t})) P_{\Theta}(\tau) $
여기까지가 REINFORCE ALGORITHM이다.
마지막을 보면 $ \sum_{t=0}^{\infty} G_{t} \partial_{\Theta} ln P_{\Theta}(a_{t} | s_{t}) $ 까지가
1개의 에피소드에서 나오는 Sample이라고 생각하면된다.
이 방식은 Monte carlo를 따르는데 그 이유는 $ G_{t} $는
모든 t를 거쳐야 계산이 가능하기 때문이다.
즉, $ \tau = (s_{0}, a_{0}, s_{1}, a_{1}...) $ 이 진행되는 동안
Policy Network에서 뽑힌 액션과 $Gt$의 곱이 $P_{\Theta}(\tau)$와 곱해져 Gradient가 되는 것이다
※ notation
$ \partial_{\Theta} ln P_{\Theta}(\tau) = \frac{\partial_{\Theta}P_{\Theta}(\tau)}{P_{\Theta}(\tau)}$ <1>
$ P_{\Theta}(s_{0}, a_{0}, s_{1}, a_{1} ...) = P_{\Theta}(s_{0}) P_{\Theta}(a_{0}, s_{1}, a{1} .... | s_{0}) Bayesian Rule $ <2>
$ \partial_{\Theta} P(s_{0}) = 0, $ $P(s_{t})$ is Not Parameter of $\Theta $ <3>
$ P_{\Theta}(a_{1} | s_{1}) $ 에서의 행동은 $ R_{0} $시점의 보상을 수반하지 않기 때문에 사라진다
즉, 현재 상태에서부터 얻는 보상만 바라본다 <4>
Actor - Critc
Actor - Critc은 REINFORCE ALGORITHM의 Monte carlo 방식을 Temporal difference로 바꾼데에 의의가 있다.
다시 말해, 끝까지 해보고 보상을 측정한 뒤, Policy를 업데이트 하는 것이 아니라,
다음 State까지만 보상을 측정한 뒤 step별로 업데이트 하는 것이다.
비유하자면 징검다리를 건너는 데, 모든 돌다리를 건너면서 빠져보고, 건너는 걸 반복하는 것이 아니라,
돌다리 하나씩 뛰어가서 어떤 경로가 안전한 계속 체크하는 것이다.

Actor - Critic의 핵심은 TD를 썼다는 것, Critic이라는 Value function이 필요해졌다는 것이다.
다음 스텝의 가치<$Q(s_{t},a_{t})$>를 평가하는 네트워크를 도입했다는 것.
REINFORCE ALGORITHM에 이어서 Gradient는 다음과 같이 변한다.
$ \partial J_{\Theta} = \int (\sum_{t=0}^{\infty} G_{t} \partial_{\Theta} ln P_{\Theta}(a_{t} | s_{t})) P_{\Theta}(\tau) d\tau$
$ = \int (\sum_{t=0}^{\infty} G_{t} \partial_{\Theta} ln P_{\Theta}(a_{t} | s_{t})) P_{\Theta}(s_{0}, a_{0}, ... s_{t}, a_{t})P_{\Theta}(s_{t+1}, a_{t+1}, ... | s_{t}, a_{t}) d\tau $ ... <1>
$ = \sum_{t=0}^{\infty} \int_{s_{0}, a_{0} ... s_{t}, a_{t}} \partial_{\Theta} ln P_{\Theta}(a_{t} | s_{t}) \int_{(s_{t+1}, a_{t+1} .. )} G_{t} P_{\Theta} (s_{t+1}, a_{t+1}, ... | s_{t}, a_{t}) d(s_{t+1}, a_{t+1}, ...) d(s_{t+1}, a_{t+1}, s_{t+2}, a_{t+2}... )P_{\Theta}(s_{0}, a_{0}, ... s_{t}, a_{t}) d( s_{0}, a_{0}, ... s_{t}, a_{t}) $
$ = \sum_{t=0} ^{\infty} \int_{s_{t}, a_{t}} \partial_{\Theta} ln P_{\Theta}(a_{t} | s_{t}) Q(s_{t}, a_{t}) P_{\Theta}(s_{t}, a_{t})d(s_{t}, a_{t}) $ ... <2>
REINFORCE와 다른 점은 $G_{t}$를 Q-value로 나타내었고 $\tau$까지 전개해야했던
Monte carlo 방식에서 한 스텝씩 업데이트 할 수 있도록 Time difference를 썼다는 것이다
Monte carlo는 한 에피소드를 모두 전개해야하기 때문에 전역적인 수렴값에 도달하는 것은 유리하지만,
각 에피소드의 전개가 너무 제각각이라 에피소드간의 분산이 크다는 단점이 있다.
Time Difference는 다음 스텝의 Q 값만 샘플링해도 되기 때문에 Monte carlo보단 분산이 적지만,
편향이 커서 Local optima에 빠질 가능성이 있다.
※ notation
$ P_{\Theta}(\tau) = P_{\Theta}(s_{0}, a_{0}, ... s_{t}, a_{t})P_{\Theta}(s_{t+1}, a_{t+1}, ... | s_{0}, a_{0}, ... s_{t}, a_{t}) $
$ = P_{\Theta}(\tau) = P_{\Theta}(s_{0}, a_{0}, ... s_{t}, a_{t})P_{\Theta}(s_{t+1}, a_{t+1}, ... |s_{t}, a_{t}) $ <1>
$ Q(s_{t}, a_{t}) = \int_{s_{t+1}, a_{t+1}...} G_{t}P(s_{t+1}, a_{t+1}, ... | s_{t}, a_{t}) d( s_{t+1}, a_{t+1}...) $ <2>
A2C <Advantage Actor Critic>
A2C는 Actor Critic 모델에서 Advantage를 준 모델이다.
여기서 주는 Advantage는 $Q(s_{t}, a_{t})$를 $Q(s_{t}, a_{t}) - V(s_{t})$로 치환한 것인데,
핵심은 Advantage를 줄 경우 기존보다 Variance를 더 낮춰줄 수 있다는 것이다.
Q를 Q-V로 바꿀 수 있는 이유는 아래와 같다
Q function을 임의의 state에 대한 $B(s_{t})$라고 했을 때
즉, action에 대한 함수가 아니라고 가정했을 때 다음 식이 성립한다.
$ \sum_{t=0} ^{\infty} \int_{s_{t}, a_{t}} \partial_{\Theta} ln P_{\Theta}(a_{t} | s_{t}) Q(s_{t}, a_{t}) P_{\Theta}(s_{t}, a_{t})d(s_{t}, a_{t}) $
$ = \sum_{t=0} ^{\infty} \int_{s_{t}, a_{t}} \partial_{\Theta} ln P_{\Theta}(a_{t} | s_{t}) B(s_{t}) P_{\Theta}(s_{t}, a_{t})d(s_{t}, a_{t}) $
$ = \sum_{t=0} ^{\infty} \int_{s_{t}, a_{t}} \partial_{\Theta} ln P_{\Theta}(a_{t} | s_{t}) B(s_{t}) P_{\Theta}(a_{t} | s_{t} ) P_{\Theta}(s_{t}) d(s_{t}, a_{t}) $
$ = \sum_{t=0} ^{\infty} \int_{s_{t}} \int_{a_{t}} \partial_{\Theta} ln P_{\Theta}(a_{t} | s_{t}) P_{\Theta}(a_{t} | s_{t}) d a_{t} B(s_{t}) P_{\Theta}(s_{t}) d s_{t} $
$ = \sum_{t=0} ^{\infty} \int_{s_{t}} \int_{a_{t}} \partial_{\Theta} P_{\Theta}(a_{t} | s_{t}) d a_{t} B(s_{t}) P_{\Theta}(s_{t}) d s_{t} $ ... <1>
$ = 0 $
때문에 Q function 자리에 어떤 state에 대한 함수가 들어와도 식은 바뀌지 않는다는 논리다.
여기서의 $ B(s_{t}) = V(s_{t}) $는 $ s_{t} $에서 얻을 수 있는 Value의 baseline이라고 생각하면 되겠고,
$ Q(s_{t}, a_{t}) - V(s_{t}) $를 해줌으로 분산을 낮춰보겠다는 시도이다.
$ \partial_{\Theta} \int_{a_{t}} P_{\Theta}(a_{t} | s_{t}) d a_{t} = 0 $ <1>
$ \sum_{t=0} ^{\infty} \int_{s_{t}, a_{t}} \partial_{\Theta} ln P_{\Theta}(a_{t} | s_{t}) Q(s_{t}, a_{t}) P_{\Theta}(s_{t}, a_{t})d(s_{t}, a_{t}) $
$ = \sum_{t=0} ^{\infty} \int_{s_{t}, a_{t}} \partial_{\Theta} ln P_{\Theta}(a_{t} | s_{t}) (Q(s_{t}, a_{t}) - V(s_{t})) P_{\Theta}(s_{t}, a_{t})d(s_{t}, a_{t}) $
까지는 유도가 되었는데, 문제는 P, Q, V는 모두 function으로 파라미터화 되어야한다.
여기서 파라미터의 개수를 줄이기 위해 Q를 V에 대한 함수로 변환시키는 작업이 들어간다.
$ = \sum_{t=0} ^{\infty} \int_{s_{t}, a_{t}} \partial_{\Theta} ln P_{\Theta}(a_{t} | s_{t}) (Q(s_{t}, a_{t}) - V(s_{t})) P_{\Theta}(s_{t}, a_{t})d(s_{t}, a_{t}) $
$ = \sum_{t=0} ^{\infty} \int_{s_{t}, a_{t}} \partial_{\Theta} ln P_{\Theta}(a_{t} | s_{t}) \int_{s_{t+1}}(R_{t} + \gamma V(s_{t+1}) - V(s_{t})) P_{\Theta}(s_{t+1} | s_{t}, a_{t}) ds_{t+1} P_{\Theta}(s_{t}, a_{t})d(s_{t}, a_{t}) $
$ = \sum_{t=0}^{\infty} \int_{s_{t}, a_{t}, s_{t+1}} \partial_{\Theta} ln P_{\Theta}(a_{t} | s_{t}) (R_{t} + \gamma V(s_{t+1}) - V(s_{t})) P_{\Theta}(s_{t+1} | s_{t}, a_{t}) P_{\Theta}(a_{t} | s_{t}) P_{\Theta}(s_{t}) d s_{t}, a_{t}, s_{t+1} $
SAMPLE과 Probability Term을 알아보기 쉽게 $ \int xP(x) dx $로 식 변형을 해주었다.
$ \partial_{\Theta} ln P_{\Theta}(a_{t} | s_{t}) (R_{t} + \gamma V(s_{t+1}) - V(s_{t})) $의 샘플이
$ P(s_{t})P(a_{t} | s_{t})P(s_{t+1} | s_{t}, a_{t}) $로 발생할 확률의 곱이 A2C의 Gradient이다.
복습
$ Q(s_{t}, a_{t})$는 현재 state에서 action을 취했을 때의 expectation reward, Action - Value Function
$V(s_{t})$는 현재 state로부터의 expectation reward, State-Value Functino
$Q(s_{t}, a_{t})$는 $V(s{t+1})$으로 바꿀 수 있다
$Q(s_{t}, a_{t}) = \int_{s_{t+1}} G_{t} P(s_{t+1}, a_{t+1}, ... | s_{t}, a_{t}) d(s_{t+1}...)$
$ = \int_{s_{t+1}...} G_{t} P(a_{t+1}, ... | s_{t+1}) P(s_{t+1} | s_{t}, a_{t}) d(s_{t+1}...) d(s_{t+1}...) $ > MDP
$ = \int_{s_{t+1}...} (R_{t} + \gamma G_{t+1}) P(a_{t+1}, ... | s_{t+1}) P(s_{t+1} | s_{t}, a_{t}) d(s_{t+1}...) d(s_{t+1}...) $
$ = \int_{s_{t+1}} \int_{a_{t+1}...} (R_{t} + \gamma G_{t+1}) P(a_{t+1}, ... | s_{t+1}) d a_{t+1} P(s_{t+1} | s_{t}, a_{t}...) d(s_{t+1}) $
$ = \int_{s_{t+1}} (R_{t} + \gamma V(s_{t+1})) P(s_{t+1} | s_{t}, a_{t}) d(s_{t+1}) $
$ = E_{s_{t+1}}[R_{t} + \gamma V(s_{t+1}) | s_{t}, a_{t}] $
정리
정리하면,
Monte carlo 방식의 REINFORCE ALGORITHM은 가장 처음 나온 알고리즘으로
Object function에 $G_{t}$를 넣어 에피소드가 끝난 후 가치를 계산해야만 했다.
이후에 나온 Actor - Critic은
REINFORCE ALGORITHM의 목적함수를 수식으로 전개하여
$G_{t}P(\tau)$ 를 $ Q(s_{t}, a_{t}) P(s_{t}, a_{t}) $로 변형했다.
즉, Monte Carlo에서 Temporal Difference 방식으로 변형했고
현재 Policy의 액션이 얼마나 가치가 있는지 알려주는 Critic 모델을 도입해
두 개의 Parameter를 쓰는 문제로 접근했다
Biased - low Variance 모델로 바꿨다.
A2C는 $Q(s_{t}, a_{t})$에 baseline인 $V(s_{t})$를 빼줌으로
State Value의 분산을 낮추고자 했다.
$ Q(s_{t}, a_{t}) $ 파라미터를 쓸 필요가 없기 때문에
t 시점의 action을 받지 않아도 된다.
Actor - Critic 구조의 모델들은 모두 On-policy이며,
매 스템 Policy에서 뽑은 샘플들로 학습을 시키고,
업데이트된 Policy에서 새로운 샘플을 뽑아야하기 때문에
Data - inefficiency가 발생하는 단점이 있다.
즉, DQN에서 사용했던 Replay Memory를 사용할 수 없다
투자에선 어떤 에이전트가 승리할까
주식 에어전트는 어떤 상황에서 가장 잘 학습하게 될까?
Policy Network에서는 매매 의사결정 이전 N일에 대한 데이터가 state로 들어가게되며,
매수, 매도, 관망 중 하나의 액션을 취하게 될 것이다.
action이 결정되면 Next state와 Reward가 결정이 된다.
이 때 $s_{t}, s_{t+1}$은 Value Network에 들어가 $ V(s_{t}), V(s_{t+1}) $를 가져온다
<무작위로 initalize 되었기 때문에 실제 Value 값은 아니다>
이때 Critic Network는 $ (R_{t} + V(s_{t+1}) - V(s_{t}))^{2} $를 loss function으로 설정해 최적화한다.
TD Target인 $ R_{t} + V(s_{t+1}) $ 과 현재 상태의 상태 추정치 $V(s_{t})$의 차이를 줄이면
무한한 에피소드를 학습시켰을 때, 현재 State가 보상을 극대화하는 TD - Target 쪽으로 fitting 될 것이다.
<마치 SARSA와 같다>
그리고 Actor Network는 $ P_{\Theta_{t+1}} = P_{\Theta_{t}} + \eta(\partial_{\Theta}lnP_{\Theta}(a_{t} | s_{t}) (R_{t} + \gamma V(s_{t+1}) - V(s_{t})) $를 Gradient ascent로 최적화한다
선택한 행동이 가지는 가치가 중요할 수록 ascent 시키는 방향이다.
결론적으론 A2C가 가장 적합해보였는데,
주식 시장의 state는 무한대의 경우의 수를 가지고 있기 때문에
모델이 학습한 state와 근사한 state에 대한 action을 뽑아내는 것이 더 효과적이라고 생각했다.
Policy Network를 LSTM 모델을 사용함으로 시계열 추론이 더 정확해지도록 만들었고,
단기 투자를 하는 사람이 1주일 혹은 2주일간의 추세를 보는 것처럼
모델에게 한정적인 Window만 보게하여 행동하는 것을 기대하고있다.
+Policy가 선택할 수 있는 action은 매수, 매도, 관망으로 제한하였는데
OpenAI Gym의 프로젝트에서 보니 관망이라는 액션을 넣었을 때
학습에 효과가 없었다는 분석을 보았는데 다시 생각해봐야겠다.
주식시장에서 행동만 해서는 무엇이 좋은 행동인지 모른다.
이 행동이 좋은 행동인지 평가하는 단계가 꼭 필요하다.
나는 그 역할을 강화학습이 한다고 보고,
특히 Actor - Critic 모델에서 Critic이 상태에 대한 가치를 잘 매겨줄 것이라고 본다.
마지막으로 투자는 Monte carlo 방식을 따르면 안된다는 생각이 들었다.
진득하게 10년 내내 멋대로 투자하고 본인의 투자에 대해 피드백하는 사람과
바로바로 피드백을 해가며 투자 전략을 바꾸는 사람을 비교했을 때,
후자가 투자 도메인에서 더 유용한 전략을 쓰는 사람이라고 할 수 있기 때문이다.
'Data Analysis > [Project] Financial Reinforce Agent' 카테고리의 다른 글
| 주식 강화학습 에이전트 만들기 - 전체 리뷰 (7) | 2023.12.05 |
|---|---|
| 즉각 보상을 계산할 수 없는 상황일 때, 과연? (5) | 2023.11.14 |
| 강화학습 REINFORCE ALGORITHM의 업데이트 (3) | 2023.10.23 |
| Financial Time-Series Overview<1> (0) | 2023.08.18 |
| 투자 용어 간단 정리 - 물가연동국채, 전환사채, 권리락 (1) | 2023.07.11 |