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)