Hidden Markov Model (HMM)
은닉 마르코프 모델(HMM)은 노이즈가 있는 관측값에서 은닉 상태의 시퀀스를 추론합니다. 매개변수, 비터비 알고리즘, 응용 사례를 다룹니다.
은닉 마르코프 모델 (HMM)은 시스템이 직접 관측할 수 없는 상태 사이를 이동하고 각 은닉 상태가 관측 가능한 결과를 생성하는 시퀀스의 확률 모델입니다. 오디오 프레임이나 DNA 염기와 같은 관측 시퀀스가 주어지면 HMM은 각 은닉 상태 시퀀스의 가능성을 계산합니다. 예를 들어 오디오를 구성하는 음소나 염기 서열 뒤에 있는 유전자 영역을 추정합니다. "마르코프"는 다음 상태가 현재 상태에만 의존한다는 핵심 가정을 가리킵니다. Leonard Baum과 동료들이 1960년대 후반에 이 이론을 개발했으며, HMM은 이후 수십 년간 음성 인식의 기반이 되었습니다. 명시적 확률만으로 구성된 HMM은 시계열 분석과 생물정보학에서 여전히 표준 도구이며, 통계적 AI의 고전적인 사례입니다.
HMM의 구성 요소#
은닉 상태가 N개인 HMM은 세 가지 확률 집합으로 정의됩니다.
- 초기 확률 (π): 각 은닉 상태에서 시작할 확률입니다.
- 전이 확률 (A): N × N 행렬이며, 원소
A[i, j]은 한 단계에서 상태 i에서 상태 j로 이동할 확률입니다. 이 때문에 은닉 상태는 마르코프 체인을 구성합니다. - 방출 확률 (B): 현재 상태가 주어졌을 때 각 관측값이 발생할 확률입니다. 이산 관측값에는 표를 사용하고, 음향 특성과 같은 연속 관측값에는 가우시안 혼합과 같은 분포를 사용합니다.
두 가지 가정으로 모델의 계산을 다루기 쉽게 만들 수 있습니다. 각 상태는 이전 상태에만 의존하고, 각 관측값은 현재 상태에만 의존합니다. 시간축으로 펼치면 각 은닉 상태가 하나의 관측값을 생성하는 체인이 됩니다.
HMM의 세 가지 고전 문제#
Lawrence Rabiner의 널리 인용되는 1989년 튜토리얼은 HMM의 활용을 세 가지 질문으로 정리했습니다. 각 문제는 관측값이 T개일 때 Nᵀ개의 가능한 상태 시퀀스 전체를 계산하는 대신 N² × T에 비례하는 비용의 동적 계획법으로 해결할 수 있습니다.
- 평가: 주어진 모델에서 관측 시퀀스가 나올 가능성은 얼마나 됩니까? 전방 알고리즘은 모든 은닉 경로의 확률을 합산합니다. 이를 통해 인식기는 발화를 가장 잘 설명하는 단어 모델을 선택합니다.
- 디코딩: 어떤 은닉 상태 시퀀스가 관측값을 가장 잘 설명합니까? Andrew Viterbi가 1967년에 컨볼루션 코드 디코딩을 위해 발표한 비터비 알고리즘은 가능성이 가장 높은 단일 경로를 찾고, 전방-후방 알고리즘은 각 시점의 각 상태가 가질 확률을 계산합니다.
- 학습: 어떤 파라미터가 관측 시퀀스 집합에 가장 잘 맞습니까? 기댓값 최대화의 한 종류인 Baum-Welch 알고리즘은 레이블이 없는 시퀀스에서 π, A, B를 추정합니다. 상태 시퀀스에 레이블이 지정되어 있다면 전이와 방출 횟수를 세는 것만으로 충분합니다.
비터비 디코딩은 NumPy 몇 줄로 구현할 수 있습니다. 이 모델에서는 사람의 활동인 걷기 또는 달리기가 은닉 상태이고, 트래커가 프레임마다 속도 측정값을 하나씩 보고하며, 활동은 프레임이 바뀌어도 계속되는 경향이 있습니다.
import numpy as np
states = ["walk", "run"]
start = np.array([0.8, 0.2]) # 초기 상태 확률
trans = np.array([[0.9, 0.1], [0.1, 0.9]]) # 활동은 프레임 사이에도 이어지는 경향이 있습니다.
emit = np.array([[0.7, 0.25, 0.05], [0.1, 0.3, 0.6]]) # 느림, 보통, 빠름에 대한 P(speed | state)
obs = [0, 0, 2, 0, 0, 1, 2, 2, 1, 2] # 프레임별 속도 측정값
# 비터비: 각 상태에 도달하는 최적 로그 확률과 역추적 포인터
logp = np.log(start) + np.log(emit[:, obs[0]])
back = []
for o in obs[1:]:
scores = logp[:, None] + np.log(trans) # 행: 이전 상태, 열: 다음 상태
back.append(scores.argmax(axis=0))
logp = scores.max(axis=0) + np.log(emit[:, o])
# 가장 가능성이 높은 최종 상태에서 역방향으로 상태 시퀀스를 추적합니다.
path = [int(logp.argmax())]
for pointers in reversed(back):
path.insert(0, int(pointers[path[0]]))
print("Speeds: ", " ".join(["slow", "medium", "fast"][o] for o in obs))
print("Decoded:", " ".join(states[s] for s in path))이 모델은 walk walk walk walk walk run run run run run을 디코딩합니다. 3번째 프레임의 빠른 측정값은 계속 "걷기"로 분류됩니다. 달리기로 전환한 뒤 다시 걷기로 돌아오려면 가능성이 낮은 전이를 두 번 거쳐야 하기 때문입니다. 6번째와 9번째 프레임의 보통 속도 측정값은 주변 프레임이 빠르므로 "달리기"로 분류됩니다. 전이를 무시하는 프레임별 분류기는 3번째 프레임을 달리기로 분류했을 것입니다.
HMM과 관련 모델 비교#
- 칼만 필터: 선형 동역학과 가우시안 노이즈가 있는 연속 상태에 동일한 예측 및 업데이트 재귀를 적용합니다. HMM의 전방 알고리즘은 이산 상태에서 이에 대응합니다.
- 베이지안 네트워크: HMM은 각 시점에 은닉 변수 하나와 관측 변수 하나를 두는 가장 단순한 동적 베이지안 네트워크입니다.
- 마르코프 결정 과정 (MDP): 관측 가능한 상태를 가진 마르코프 체인에 행동과 보상을 추가한 것으로, 강화 학습의 기반이 됩니다.
- 순환 신경망 및 트랜스포머: 대규모 데이터셋에서 장거리 비선형 종속성을 학습하며 대부분의 음성 및 언어 작업에서 HMM을 대체했습니다. HMM은 훨씬 적은 데이터만 필요하고 모든 확률을 직접 확인할 수 있습니다.
- 상태 공간 모델 (SSM): Mamba와 같은 딥러닝 레이어는 제어 이론의 상태 공간 개념을 공유하며, 학습된 결정론적 동역학으로 연속 은닉 벡터를 업데이트합니다.
실제 적용 사례#
- 음성 인식: 1980년대부터 2010년대 초까지 대부분의 인식기는 각 음소를 가우시안 혼합 방출을 가진 작은 HMM으로 모델링했습니다. 이후 하이브리드 시스템에서 심층 신경망이 방출 모델을 대체했고, 나중에는 엔드투엔드 모델이 HMM 자체를 대체했습니다.
- 생물정보학: 프로파일 HMM은 서로 연관된 단백질 또는 DNA 시퀀스의 계열을 설명합니다. HMMER는 이를 사용해 시퀀스 데이터베이스에서 먼 친척 시퀀스를 검색하며 Pfam 단백질 계열 데이터베이스의 기반이 됩니다. 유전자 탐지기는 HMM을 사용해 게놈의 영역을 코딩 또는 비코딩으로 표시합니다.
- 품사 태깅: 초기 통계적 자연어 처리는 태그 시퀀스에 비터비 디코딩을 적용해 단어를 명사, 동사 및 기타 품사로 분류했습니다.
- 활동 인식: 신체 자세 시퀀스나 웨어러블 센서 측정값을 디코딩해 서기, 걷기 또는 넘어지기와 같은 활동을 파악합니다. Ultralytics의 운동 모니터링 솔루션은 이러한 2상태 시퀀스를 추적합니다. YOLO26 자세 추정 키포인트의 관절 각도(기본값은 팔꿈치)를 바탕으로 각 사람을 "위" 또는 "아래"로 분류하고, 각도가 145°를 넘거나 90° 아래로 내려갈 때 상태를 전환하며, 위에서 아래로 바뀔 때마다 반복 횟수를 셉니다.










