Hidden Markov Model (HMM)
隠れマルコフモデル(HMM)は、ノイズを含む観測値から隠れ状態の系列を推定します。パラメーター、ビタビアルゴリズム、応用例について解説します。
隠れマルコフモデル (HMM) は、システムが直接観測できない状態間を遷移し、各隠れ状態が観測可能な結果を生成する系列の確率モデルです。音声フレームやDNA文字などの観測系列が与えられると、HMMは、音声の背後にある音素や文字列の背後にある遺伝子領域など、各隠れ状態系列の尤度を計算します。「マルコフ」は、次の状態が現在の状態だけに依存するという中核的な仮定を指します。Leonard Baumらが1960年代後半に理論を発展させ、HMMはその後、数十年にわたり音声認識を支えました。明示的な確率だけで構成されるHMMは、現在も時系列分析やバイオインフォマティクスの標準的な手法であり、統計的AIの古典的な例でもあります。
HMMの構成要素#
隠れ状態がN個あるHMMは、次の3つの確率集合で定義されます。
- 初期確率 (π): 各隠れ状態から開始する確率です。
- 遷移確率 (A): N × N行列で、その要素
A[i, j]は、1ステップで状態iから状態jへ遷移する確率です。これにより隠れ状態はマルコフ連鎖を構成します。 - 出力確率 (B): 現在の状態が与えられたときの各観測の確率です。離散観測には表を使い、音響特徴量などの連続観測にはガウス混合分布などを使います。
モデルを扱いやすくするため、各状態は直前の状態だけに依存し、各観測は現在の状態だけに依存すると仮定します。時間軸に沿って展開すると、各隠れ状態が1つの観測を出力する連鎖になります。
HMMに関する3つの古典的問題#
広く引用されているLawrence Rabinerの1989年のチュートリアルでは、HMMの利用を3つの問いに整理しています。それぞれに動的計画法による解法があり、状態系列はNᵀ通りある一方、計算量はT個の観測に対してN² × Tで増加します。
- 評価: 与えられたモデルの下で、観測系列が得られる尤度はどの程度でしょうか。前向きアルゴリズムはすべての隠れ経路を合計します。これにより、認識器は発話を最もよく説明する単語モデルを選びます。
- デコーディング: 観測を最もよく説明する隠れ状態系列はどれでしょうか。Viterbiアルゴリズムは、畳み込み符号のデコーディング向けにAndrew Viterbiが1967年に発表したもので、最尤経路を1つ求めます。前向き・後ろ向きアルゴリズムでは、各時刻における各状態の確率を求めます。
- 学習: 観測系列の集合に最もよく適合するパラメーターはどれでしょうか。Baum-Welchアルゴリズムは期待値最大化法の一種で、ラベルなしの系列からπ、A、Bを推定します。状態系列にラベルが付いている場合は、遷移と出力を数えれば十分です。
Viterbiデコーディングは、NumPyを使って数行で実装できます。このモデルでは、人の活動(歩行または走行)が隠れ状態であり、トラッカーが各フレームで1つの速度測定値を出力します。また、活動状態はフレーム間で持続する傾向があります。
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] # # フレームごとの速度測定値
# # Viterbi: 各状態に到達する最良の対数確率とバックポインター
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の高速測定値は「歩行」のままです。走行に切り替えてから戻るには、確率の低い遷移が2回必要だからです。フレーム6と9の中速測定値は、前後の高速フレームの影響で「走行」になります。遷移を考慮しないフレーム単位の分類器では、フレーム3を走行と分類していたでしょう。
HMMと関連モデルの比較#
- カルマンフィルター: 線形ダイナミクスとガウスノイズを持つ連続状態に対して、同じ予測・更新の再帰処理を行います。離散状態ではHMMの前向きアルゴリズムがこれに相当します。
- ベイジアンネットワーク: HMMは、各時刻に隠れ変数と観測変数を1つずつ持つ、最も単純な動的ベイジアンネットワークです。
- マルコフ決定過程 (MDP): 観測可能な状態を持つマルコフ連鎖に行動と報酬を加えた枠組みで、強化学習の基盤となります。
- リカレントニューラルネットワークとTransformer: 大規模なデータセットから長距離の非線形依存関係を学習し、ほとんどの音声・言語タスクでHMMに取って代わりました。HMMは必要なデータがはるかに少なく、それぞれの確率を直接確認できます。
- 状態空間モデル (SSM): Mambaなどのディープラーニング層は、制御理論の状態空間の考え方を共有し、学習済みの決定論的なダイナミクスで連続的な隠れベクトルを更新します。
実際のアプリケーション#
- 音声認識: 1980年代から2010年代初頭まで、ほとんどの音声認識器は、各音素をガウス混合分布の出力を持つ小さなHMMとしてモデル化していました。その後、ハイブリッドシステムではディープニューラルネットワークが出力モデルに使われるようになり、さらに後年にはエンドツーエンドモデルがHMM全体に取って代わりました。
- バイオインフォマティクス: プロファイルHMMは、関連するタンパク質配列やDNA配列のファミリーを記述します。HMMERはこれを使って配列データベースから遠縁の配列を検索します。HMMERはタンパク質ファミリーデータベースPfamの基盤でもあり、遺伝子予測器はHMMでゲノム領域をコード領域または非コード領域に分類します。
- 品詞タグ付け: 初期の統計的な自然言語処理では、タグ系列に対するViterbiデコーディングにより、単語を名詞、動詞などの品詞に分類していました。
- 活動認識: 身体の姿勢やウェアラブルセンサーの測定値の系列を、立つ、歩く、転ぶなどの活動にデコードします。Ultralyticsのワークアウト監視ソリューションは、この種の2状態系列を追跡します。YOLO26のポーズ推定キーポイントから得られる関節角度(デフォルトでは肘)に基づいて各人を「上」または「下」と分類し、145°を超えたときと90°を下回ったときに状態を切り替え、「上」から「下」への変化ごとに1回としてカウントします。










