앞에서, 디리슐레 분포와 다항분포의 켤레관계에 대해서 살펴보았다. 디리슐레 분포는 고정된 k개의 클러스터 (선택지)에 대한 확률을 모델링하는 분포로 사전분포로 쓰였다.,디리슐레 과정 (DP; Dirichlet Process)은 디리슐레 분포의 무한대 확장판으로, 고정되지 않은 클러스터에 대한 확률을 모델링하는 분포이다. 명확한 정의는 다음과 같다.
Definition
α>0, H를 S에서 정의된 probability measure라 하자. 이 두 모수 (α,H)를 가지는 디리슐레 과정은 S에서 정의된 random probability measure G이다. Random probability measure라는 뜻은 G가 유한한 집합 A=(A1,…,Ar)에 확률 G(A)=(G(A1),…,G(Ar))을 정해줌을 의미한다.
H는 S에 정의된 base probability measure로, 연속인 확률분포를 가진다.
α>0는 concentration 모수라 불린다. 이는 디리슐레 과정에서 나온 표본들이 얼마나 base 함수 H와 얼마나 가까운지를 조절하는 모수이다.
Properties of Dirichlet Process
유한 집합 A=(A1,…,Ar)는 exclusive & exhaustive한 성질을 가진 파티션이다. exclusive하고 exhaustive하다는 말은 아래의 사진처럼, A1,…,A6은 겹치지 않고 (A1∩A2∩⋯∩Ar=∅), 전체의 합집합이 전체집합 (A1∪A2∪⋯∪Ar=A))임을 의미한다.
DP에서는 무한대 확률 벡터를 r개로 나누어 무한개의 이산형의 분포를 가진다. 따라서, DP를 다음과 같이 정의할 수 있다.
여기서 πr는 r번째 클러스터로 분류된 확률 질량 (probability mass)이고 θr는 r번째 클러스터의 평균, δ는 디랙 델타 함수이다. 또한 ∑r=1∞πr=1이다.
DP의 평균과 분산은 다음과 같다.
E[G(A)]=H(A)
V[G(A)]=α+1H(A)(1−H(A))
Stick-Breaking Process
DP와 짝꿍으로 나오는 설명은 항상 Stick-breaking process이다. 필자는 처음에 왜 이게 갑자기 나오나 하는 생각이 들었지만, KAIST Youtube 강의
에서 그 해답을 찾을 수 있었다.
DP는 무한대에서 정의되는 과정이기 때문에 이 과정에서 표본을 추출하기 위한 알고리즘 (sampling schemes/construction scheme)이 필요하다. 즉, 위의 DP의 정의에서 θr과 πr을 construct하기 위한 방법론이 필요하다. 우리가 살펴볼 방법은 세 가지이다.
Chinese restaurant process
Polya-Urn Scheme
Stick-breaking process
그 중 Stick-breaking process를 먼저 쓰는 이유는 이해하기 가장 직관적이였기 때문이다.
Stick-Breaking Process
β1,β2,…∣α∼Beta(1,α)를 따르는 무한 개의 β가 있을 때, Stick-breaking process를 통해 πr=βr∏i=1r−1(1−βi)=βr(1−β1)(1−β2)⋯(1−βr−1)를 만든다. βi는 베타분포를 따르기 때문에 0과 1사이의 값는 비율로 해석할 수 있다.
방법을 설명하면 다음과 같다.
1의 길이를 가진 막대가 있다.
이 막대를 π1=β1의 비율로 두 개로 자르면, 두 개는 각각 π1=β1과 1−β1의 길이를 갖는다.
β1길이의 막대는 냅두고, 1−β1의 길이의 막대만 β2의 비율로 나누면, π2=β2(1−β1) 길이의 막대와 (1−β1)(1−β2) 길이의 막대로 나눌 수 있다.
%matplotlib inline from matplotlib import pyplot as plt import numpy as np import pymc3 as pm import scipy import seaborn as sns from statsmodels.datasets import get_rdataset from theano import tensor as T
파이썬의 모듈이란 R 상의 패키지의 개념이다.
%matplotlib inline은 Jupyter notebook 내에서 그림을 출력하기 위한 magic command이다.
seaborn 모듈은 Matplotlib을 기반으로 다양한 색상 테마와 통계용 차트 등의 기능을 추가한 시각화 패키지이다.
get_rdataset 모듈은 R패키지에 내장되어 있는 데이터셋을 불러올 수 있는 모듈이다.
파이썬으로 그래프를 그릴 때는 matplotlib.pyplot을 자주 사용한다. 이를 위한 과정은 다음과 같다.
x_plot: 그래프를 그릴 때 필요한 x의 grid를 그려준다.
pi[...,np.newaxis]: π는 β와 같은 차원인 (20,30)의 배열이었다. 이에 np.newaxis를 사용하면 2차원의 배열이 3차원 (20,30,1)로 차원이 하나 늘어난다. 이런 과정을 거친 이유는 np.less.outer(omega,x_plot)의 3차원의 배열과 곱해주기 위해서이다.
np.less.outer(omega,x_plot): 이 부분이 이해하기 가장 어려웠다. 기존의 np.outer(x,y)는 x=(x1,…,xn)와 y=(y1,…,ym)의 외적인 (n,m)행렬을 반환한다.
그러나 np.less.outer(x,y)는 더이상 외적에 대한 내용이 아니다. 이는 x와 y의 원소들끼리 비교했을 때 xi<yj이면 TRUE (1)를 반환하고, xi≥yj이면 FALSE(0)을 반환한다. 여기서 omega는 (20,30)의 배열이고, x_plot은 (200,)의 배열이었기 때문에, omega의 원소 값이 x_plot의 원소 값보다 작으면 1을 반환하는 (20,30,200)의 차원을 계산해준다.