カルマンフィルタとEMアルゴリズム

この辺りの話についての記事が恐ろしくWEB上では枯渇しているようだ。中にはMATLABによる実装なども見つけることができるが、私がMATLABが好きではないという至極個人的な理由で、そのようなものは受け入れられない(そもそもあんなに言語として欠陥のある物を、高い金を出して購入するという風習を理解できない)。

今回、諸事情でカルマンフィルタと、それのオフライン実装、加えてEMアルゴリズムによるパラメータの推定までを行う必要があった。そこで、そのコードに多少の説明を加えて公開しようと思ったわけである。ただし、私は別に専門家でもなんでもないので、場合によっては内容に不備や間違いが含まれている可能性がある。したがって、ここに記載された内容により何か不利益を被るようなことになったとしても、私は責任を取ることは出来ない。よって、読者は内容を鵜呑みにせず自分の目で正しいかどうかをよく確かめてほしい。また、なにか気づいたことがあれば、些細な事でも連絡をいただけるとありがたい。

まずは定義式を確認しよう。

$${\bf z}_n = {\bf A}{\bf z}_{n-1} + {\bf w}_n$$

$${\bf x}_n = {\bf C}{\bf z}_{n} + {\bf v}_n$$

$${\bf z}_1 = {\bf \mu}_{0} + {\bf u}$$

ただしここで

$$p({\bf w}) = {\cal N}({\bf w|0,\Gamma})$$

$$p({\bf v}) = {\cal N}({\bf v|0,\Sigma})$$

$$p({\bf u}) = {\cal N}({\bf u|0},{\bf P}_0)$$

さてカルマンフィルタの目的は、観測値$${\bf x}_n$$から内部状態$${\bf z}_n$$を導くことである。詳しい説明は他のページに譲るとして,この問題はガウス性ノイズが邪魔となり簡単には求めることは出来ない。しかし、うまいことやることでこれは計算可能である.

ここまでの話はどこにでも乗っていることだ。重要なのはここからで、今までの枠組みでは$$\bf \Gamma$$や$$\bf \Sigma$$などは事前に知っている必要がある。しかし、世の中そんな都合のいい話ばかりではない。私たちは問題に取り組む際、パラメータを都合よく知っているといつでも仮定できるわけではない。実際問題としては、観測値$${\bf x}_n$$から内部パラメータを推定できることが最善だろう。そのための解決策としてここではEMアルゴリズムを使用する。これについても詳細は省略するが(知りたければコメントを書いてほしい)、要約すれば初期値を与えたあとに、そこから反復計算を行い、収束した頃にはだいたいちょうどよいパラメータ値になるというものである(超雑)。詳細は置いといて、実際のコードを下に示そう。

これがクラスファイルである。と言ってもstructかつすべての変数がpulicなので到底まともなクラスとはいえないが。使い方は次の通り

ここではノイズの乗ったsin関数について、そのノイズ除去を行っている。実際の出力結果をgnuplotで表示したものがこれ

test

色が気持ち悪いことを除けば、特に問題はなさそうだ。

内容についてどう思いますか?
  • いいね (3)
  • だめ (0)

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA