길레스피 확률 시뮬레이션 알고리즘
알고리즘 1
에 대해 와 같이 표현되는 연속마코프체인 의 실현을 구하는 시뮬레이션 방법을 길레스피 알고리즘gillespie Stochastic Simulation Algorithm, 짧게는 SSAstochastic Simulation Algorithm이라 부른다.
Input
초기값 과 을 받는다.
Step 1.
를 계산한다.
Step 2.
지수분포 에서 를 샘플링한다. 가 크면 클수록 의 기대값은 작아지고, 사건은 빈번하게 일어나게 된다.
Step 3.
의 확률로 를 선택한다. 가 크면 클수록 사건 가 일어날 확률이 높아진다.
Step 4.
를 기록하고 와 같이 갱신한다. 는 연속시간 마코프체인이므로 Step 1.으로 돌아가 반복할 수 있다. 원하는만큼 데이터를 얻으면 알고리즘을 멈춘다.
Output
주어진 의 실현을 얻는다.
설명
예시
알고리즘에 수식이 너무 일반적으로 적혀 있어서 좀 어려워 보이는데 알고보면 사실 굉장히 쉽다.
간단한 탄생-죽음 프로세스birth-Death process를 생각해보자. 이 프로세스는 명의 인구에서 시작해 번식계수 와 사망계수 에 따라 인구의 증감을 나타낸다. 가 보다 크냐 작으냐에 따라 다른 양상이 나타나겠지만, 일단 사건이 일어나는 빈도 자체는 이들의 절대적인 값에 달려있다. 생존이든 죽음이든 그 시점에서의 개체수에 비례해서 자주 발생하는 것이 타당하고, 인구수 일 때 사건이 일어나는 간격은 을 따른다. 일단 사건이 일어나는 시점을 정했으니 이제 탄생과 죽음 중 어떤 사건이 일어나는지를 선택하면 된다. 시점의 인구수가 일 때 시점에서 번식한다는 것은 , 사망한다는 것은 을 의미한다. 이들은 각각 계수 와 시점의 인구수 에 비례하므로 이다. Step 3에 따라 이들을 정규화normalize해서 구해지는 확률로 어떤 사건이 일어날지 결정하면 된다.
코드
다음은 위 예시를 그대로 코드로 옮긴 줄리아 코드다. 위의 파라미터가 주어져 있을 때, 초기 인구 로 시작한 시뮬레이션을 만 번 반복하고 에서 평균을 계산해 이론적인 예측치와 비교한다. 효율보다는 읽기 쉽게 써놓았으니 알고리즘이 예시의 설명대로 구현되어 있는지 확인해보자.
using Distributions
using Plots
b = 2.0
d = 1.0
θ = b/(b+d)
result = plot(xlims = (0,2), ylims = (0, Inf))
Y = Int64[]
@time for _ in 1:10000
y = [2]
t = [0.0]
while t[end] < 2 && y[end] > 0
push!(t, t[end] + rand(Exponential(1/((b+d) * y[end]))))
if rand() < θ
push!(y, y[end] + 1)
else
push!(y, y[end] - 1)
end
end
if t[end] > 2
push!(Y, y[end-1])
else
push!(Y, 0)
end
plot!(result, t,y, label = :none, alpha = 0.01, color = :black)
end
plot!(result, 0:0.1:2,2exp.((b-d) .* 0:0.1:2), label = :none, color = :red, linewidth = 4, linestyle = :dot)
result
abs(mean(Y) - 2exp.(2(b-d)))
실행 결과를 시각화해보면 위와 같다. 이론적인 예측값 과의 차이는 0.1정도로 꽤 정확하게 계산되었음을 확인할 수 있다.