LoginSignup
81

More than 5 years have passed since last update.

隠れマルコフモデルを実現するPythonライブラリ hmmlearnの使い方

Last updated at Posted at 2016-05-19

hmmlearnの日本語情報が見当たらなかったので最低限の使い方をまとめました。
※Tutorial + α 程度です。

hmmlearnはHMM(隠れマルコフモデル)を実現するscikit-learnライクなPythonライブラリです。
http://hmmlearn.readthedocs.org

セットアップ

以下の導入が必須になります。
※Pythonは3系でも動作確認済みです。

  • Python >= 2.6
  • NumPy(tested to work with >= 1.9.3)
  • SciPy(tested to work with >= 0.16.0)
  • scikit-learn >= 0.16

インストール

hmmlearnはpipでインストールすることができます。

$ pip install -U --user hmmlearn

使い方

今回はGaussianHMMを利用します。

GaussianHMMとは

モデルの出力が連続値となる隠れマルコフモデルです。

必要なパラメータ

以下の方法でmodelのインスタンスを作成します。

from hmmlearn import hmm

model = hmm.GaussianHMM(n_components=3, covariance_type="full")

引数のn_componetsは状態数を指定して、covariance_typeは共分散の種類を指定します。

指定が必須となる属性は以下となります。

  • startprob_
    • 初期状態の遷移確率を指定します。(状態数 * 1)
  • transmat_
    • 状態遷移確率を指定します。(状態数 * 状態数)
  • means_
    • 各状態の平均を指定します。(状態数 * 特徴数)
  • covars_
    • 共分散を指定します。(covariance_typeによる)

今回は例で状態数を5個としてパラメータを入れました。

import numpy as np
from hmmlearn import hmm


startprob = np.array([0.0, 0.1, 0.8, 0.1, 0.0])
transmat = np.array([[0.9, 0.1, 0.0, 0.0, 0.0],
                     [0.4, 0.3, 0.3, 0.0, 0.0],
                     [0.1, 0.2, 0.4, 0.3, 0.0],
                     [0.0, 0.1, 0.3, 0.3, 0.3],
                     [0.0, 0.0, 0.3, 0.1, 0.6]])

means = np.array([[1.0, 1.0],
                  [2.0, 2.0],
                  [3.0, 3.0],
                  [4.0, 4.0],
                  [5.0, 5.0]])

covars = 0.1 * np.tile(np.identity(2), (5, 1, 1))

model = hmm.GaussianHMM(n_components=5, covariance_type="full")

model.startprob_ = startprob
model.transmat_ = transmat
model.means_ = means
model.covars_ = covars

予測

サンプルデータで状態系列を予測してみます。

>>> X, Z = model.sample(10)

>>> print(X)
[[ 3.42184743  2.84259768]
 [ 1.83591345  2.60456015]
 [ 3.0610817   3.67242462]
 [ 3.88970955  3.94599461]
 [ 4.99679025  5.21663028]
 [ 5.05294062  4.80691392]
 [ 5.25836686  5.08960965]
 [ 5.49849546  5.00469741]
 [ 5.31740667  4.77140169]
 [ 4.1283215   5.06959465]]

>>> print(Z)
[2 1 2 3 4 4 4 4 4 4]

これはサンプルデータがXのとき状態系列はZと予測された結果です。

サンプルではないデータから状態系列を予測してみます。
ある出力系列をもとに状態系列を予測する場合はpredictメソッドを使用します。

>>> model.predict([[1.3], [2.0], [4.3], [4.2]])
array([1, 2, 3, 3])

学習

パラメータを学習によって推定する方法を紹介します。

fitメソッドによって学習を行いパラメータ推定を行います。
今回はXを学習データとしています。

import numpy as np
from hmmlearn import hmm

model = hmm.GaussianHMM(n_components=5, covariance_type="full")
X = np.array([[1.2], [2.3], [1.1], [4.2], [3.3]])
model.fit(X)

学習によってパラメータが入力されていることが確認できます。

>>> model.startprob_
array([  2.06946712e-292,   0.00000000e+000,   3.13184994e-003,
         1.27702612e-300,   9.96868150e-001])

>>> model.means_
array([[ 2.3       ],
       [ 4.2       ],
       [ 1.10171369],
       [ 3.3       ],
       [ 1.15485602]])

>>> model.covars_
array([[[ 0.01      ]],
       [[ 0.01      ]],
       [[ 0.05488646]],
       [[ 0.01      ]],
       [[ 0.00797925]]])

>>> model.transmat_
array([[  1.27206138e-223,   1.57268167e-192,   1.79623272e-001,
          9.10036066e-211,   8.20376728e-001],
       [  5.88225536e-075,   2.07494122e-025,   1.88590294e-063,
          1.00000000e+000,   5.18696363e-119],
       [  1.71368655e-002,   9.82863134e-001,   6.65061859e-190,
          9.25847733e-045,   3.48719264e-293],
       [  1.79414943e-074,   2.06495338e-025,   3.28132831e-011,
          1.00000000e+000,   1.50081312e-010],
       [  5.48560165e-001,   4.51439835e-001,   1.32144625e-190,
          6.49028218e-045,   0.00000000e+000]])

評価

モデルを評価するために対数尤度を求めます。

scoreメソッドによってモデルの評価を行います。
評価するための出力系列をXに指定します。

>>> X = np.array([[3.2], [2.4], [3.1], [3.2], [3.0], [3.9], [4.0]])
>>> model.score(X)
0.11878179338435844

書き出しと読み込み

モデルの書き出しと読み込みを行います。

sklearnのjoblibを使うことによってモデルを書き出すことができます。

>>> from sklearn.externals import joblib
>>> joblib.dump(remodel, "filename.pkl")
["filename.pkl"]

読み込みも同じようにjoblibを使ってloadメソッドにより読み込みができます。

>>> from sklearn.externals import joblib
>>> joblib.load('filename.pkl')
GaussianHMM(algorithm='viterbi', covariance_type='full', covars_prior=0.01,
      covars_weight=1, init_params='stmc', means_prior=0, means_weight=0,
      min_covar=0.001, n_components=5, n_iter=10, params='stmc',
      random_state=None, startprob_prior=1.0, tol=0.01, transmat_prior=1.0,
      verbose=False)

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
81