본문 바로가기
machine learning

[TENSORFLOW] Hidden Markov Model

by 유주원 2017. 4. 14.

Hidden Markov Model에 대해 살펴보자.

기계학습하면 가장 많이 언급된 단어가 바로 HMM이며, 아래 그림을 통해 HMM에 대해 알아보자.

Markov Model은 현재 일어날 확률이 바로 이전의 확률에만 영향을 받는 확률 모델을 말한다. Hidden Markov Model과의 차이점은 단지 관찰할 상태가 있으냐 없으냐에 따라 결정된다. (관찰할 상태가 있으면 Hidden Markov Model)

위의 그림에서는 Rainy와 Sunny의 두 가지 hidden state가 존재한다. 비가 오거나 맑음의 두 가지 상태는 알지만 현재 비가 오는지 아니면 맑은지에 대한 상태를 전혀 알 수 없기 때문에 해당 상태를 hidden state라고 정의한다.

그리고 최초의 state 확률을 정의한다. 여기서는 Rainy가 0.6, Sunny가 0.4로 정의되어 있으며, 이 지역은 대체적으로 비가 더 많이 왔음을 통계적으로 확인시켜 준다.

transition probability 역시 필요한데, 만약에 해당 지역이 어제 비과 왔는데 오늘 또 비가 올 확률이 0.7, 어제 비가 오고 오늘 맑을 확률이 0.3... 이런 식으로 각각 상태가 전이될 때의 확률을 정의해준다.

마지막으로 각각의 상태(rainy, sunny)는 각각이 방출할 수 있는 관측 결과를 낼 수가 있는데 이를 emission_probability라고 한다. 위의 그림에서는 비가 올때 걸을 확률이 0.1, 쇼핑할 확률이 0.4, 청소할 확률이 0.5가 된다.

이렇게 3가지의 확률 변수 값이 존재한다면 우리는 어떤 결과가 예측되었을 때의 확률을 찾아낼 수가 있을 것이다.

이제 아래의 코드를 통해 우리는 Walk -> Shop -> Shop -> Clean -> Shop할 확률 값을 찾아보자.

위에서 언급했듯이 우리는 Walk -> Shop -> Shop -> Clean -> Shop할 확률을 찾을 것이며, 이를 코드에서는 [0, 1, 1, 2, 1]로 나타내고 있다.

initial_prob는 초기 발생 확률로 0.6(비가올 확률), 0.4(맑을 확률)를 나타내고 있고, trans_prob는 각각 [0.7, 0.3], [0.4, 0.6]을 나타내고 있다. 이는 언급했듯이 비가 왔는데 또 비올 확률 (0.7), 비왔는데 맑을 확률(0.3), 맑았는데 비올 확률(0.4), 맑고 또 맑을 확률(0.6)을 나타낸다. 마지막으로 obs_prob는 방출 확률로 각 상태에서의 Walk, Shop, Clean할 확률을 각각 저장하고 있다.

이렇게 확률 값들을 정의한 후 HMM 클래스를 생성해서 각각의 확률 값들을 클래스 내의 변수로 저장을 해 놓는다.

그런 다음 session에서는 forward_algorithm을 실행하는데 이 알고리즘은 단순하게 해당 결과가 나타났을 때의 확률 값들을 곱하고 더함으로써 최종 확률을 얻는 단순한 함수이다. 차근차근 살펴보도록 하자.

우선 hmm.forward_init_op()를 호출한다. 파라미터로 observations[0] 값이 들어가는데 여기서 observations[0]은 Walk 상태를 말한다.

forward_init_op() 함수 내에서 get_emission() 함수를 호출하는데 이 함수는 Rainy일 때의 observation 확률 Sunny일 때의 observation 확률을 행렬로 리턴한다. 여기서는 [[0.1], [0.6]]의 2x1행렬이 리턴된다. 

이렇게 리턴된 방출 확률과 초기 확률을 각각 곱한다. 결국 [[0.1 * 0.6], [0.6 * 0.4]] 가 된다.

최초에는 상태 변화가 일어나지 않았기 때문에 transition 확률은 따로 계산하지 않는다. 본격적으로 hmm.forward_op()가 실행되면서 transition 확률이 계산이 된다.

forward_init_op에서 구한 확률에 이번에는 두번 째 방출 확률을 행렬 곱 한다. 여기서는 Shop일 때의 확률이 되고 값은 [[0.4],[0.3]]이 된다. 즉 [[0.06], [0.24]] 와 [[0.4 , 0.3]]의 행렬 곱이 되며 결과는 2x2 행렬이 나타난다.

여기서 2x2의 의미는 결국 [[Rainy -> Rainy, Rainy -> Sunny], [Sunny -> Rainy, Sunny -> Sunny]] 확률 행렬이 되며, 각각의 상태 변화를 trans_prob로 곱해준다. 마지막으로 [Rainy, Sunny] 확률 값만을 남기기 위해 y축을 기준으로 reduce_sum을 하며 이 과정을 반복해서 나온 [Rainy, Sunny] 확률 값을 reduce_sum을 해서 최종 확률 값을 구한다.


참고로 tensorflow의 reduce_sum은 인자가 약간 헷갈리게 설정되어 있는데 0은 y축 1은 x축 2는 z축이라고 생각하면 되고 아래의 그림을 토대로 이해하면 쉽다.

봐도 헷갈린다..