반응형
지난 몬테카를로 시뮬레이션 관련 포스트들은 모두 독립 확률 변수에 기초한 것입니다. 독립 확률 변수란 확률 변수들 사이에 상관관계가 없어 각 확률 변수를 독립적으로 만들 수 있다는 말이죠. 수식으로는 두 확률 변수 $X, Y$에 대해 $p(X,Y)=p(X)*p(Y)$와 같이 표현할 수 있을 겁니다. 하지만 확률 변수들을 독립적이지 않을 때는 어떨까요? 다시 말해서 $n$개의 확률 변수 $x_1, ..., x_n$에 대해서 다음 수식처럼 확률 변수를 독립적으로 분해할 수 없다는 것이죠. 이럴 때에는 메트로폴리스 (metropolis) 알고리즘을 사용할 수 있습니다.
$p(x_1, ..., x_n) !=p(x_1)...p(x_n)$
메트로폴리스 알고리즘은 다음과 같이 동작합니다.
- 정의역에 있는 독립 난수의 집합 $(x_1^1, x_2^1, ..., x_n^1)$ 로부터 시작합니다.
- 정의역에 있는 다른 독립 난수의 집합 $x^{i+1}=(x_1^{i+1}, ..., x_n^{i+1})$을 만들고 이는 임의의 확률 함수 $Q(x^{i})$를 사용해서 만들 수 있습니다. 함수 $Q$의 유일한 조건은 현재 점 $x$에서 새로운 점 $y$로 갈 확률과 현재 점 $y$에서 새로운 점 $x$로 이동하는 확률이 같아야 한다는 것입니다. (간단하게 균등 함수로 구현할 수 있겠죠)
- 균등 난수 $z$를 만듭니다.
- 만일 $p(x^{i+1})/p(x^{i}) < z$ 라면, $x^{i+1}=x^{i}$ 이고 2 단계로 다시 돌아갑니다.
- 매우 큰 수 $i$에 대해 이 과정을 반복하면 $x^i$의 집합은 목표로 하는 확률 질량 함수 $p(x)$를 가지게 됩니다.
파이썬 구현
예를 들어 확률 질량 함수가 $p(x_1, x_2)=6(x_0-x_1)^2$이고 $[0,1]$에 있는 두 난수 $x_1, x_2$를 만들어내는 간단한 경우에 대해 파이썬으로 구현해보도록 하겠습니다.
import random
def metropolis(p, q, x=None):
while True:
x_old = x
x = q(x)
if x_old is None:
x_old = [0, 1]
if p(x) / p(x_old) < random.random():
x = x_old
yield x
def P(x):
return 6.*(x[0]-x[1])**2
def Q(x):
return [random.random(), random.random()]
for i, x in enumerate(metropolis(P, Q)):
print(x)
if i == 100: break
- x_old 변수는 처음에 x가 None 객체이므로 임의의 값을 지정합니다.
- $Q$는 정의역 $[0,1]\times[0,1]$에서 무작위 점을 만들어내는 함수입니다. return 대신에 생성자 yield 함수를 사용하여 모든 계산을 한 번에 하지 않고 생성된 값으로 반복합니다.
실제로 이 코드를 돌려보면 반복된 값을 많이 만들어냅니다. 즉, 만들어낸 벡터가 이전의 벡터와 두터운 상관관계를 가질 수 있다는 것이죠. 이런 이유로 메트로폴리스 알고리즘에서는 일부를 건너 뛰어서 벡터들간의 상관관계를 없애야 합니다. 이전의 벡터로부터 독립적인 다음 벡터를 만들기 위해 충분히 큰 값을 갖는 decorrelation length 를 설정하고 이 길이에 다다를 때마다 벡터를 샘플링합니다.
def metropolis_decorrelate(p, q, x=None, ds=100):
k = 0
for x in metropolis(p, q, x):
k += 1
if k % ds == ds -1:
yield x
for i, x in enumerate(metropolis_decorrelate(P,Q)):
print(x)
if i == 100: break
반응형
'Theory > Algorithms' 카테고리의 다른 글
자료구조 - 리스트와 튜플 (List, Tuple) (0) | 2022.08.07 |
---|---|
방정식 해 찾기 - 고정점 반복법 (0) | 2022.04.02 |
몬테카를로 시뮬레이션 (5) - 적분 계산하기 (0) | 2022.03.20 |
몬테카를로 시뮬레이션 (4) - 범용 몬테카를로 엔진 (0) | 2022.03.09 |
몬테카를로 시뮬레이션 (3) - 부트스트랩 알고리즘 (bootstrap) (0) | 2022.03.09 |