リサンプリング

学業がひと段落したので、久々に更新。

ちょっとパーティクルフィルタを実装する必要があって、pythonでコードを書いているところです。 今回はその時に調べたことのメモ。 パーティクルフィルタの説明はgoogle大先生にお伺いするといろいろ出てきますが、MISTのチュートリアルが実装も書いてあって わかりやすいかと思います。

Tutorial/Practice0 – MIST Project

パーティクルフィルタでは各パーティクルに尤度に基づいた重みをつけ、イテレートのたびに重みに従ってパーティクルをリサンプリングします。

重みに従ったリサンプリングの簡単な実装方法としては累積重みを使った方法がありますが(MISTのチュートリアルもこのやり方)、numpyに都合のいい関数がありそうなので調べてみたらrandomモジュールのchoicを使えば楽に行けそう。

Scipyのドキュメントを見てみると

numpy.random.choice(a, size=None, replace=True, p=None)
Generates a random sample from a given 1-D array

とある。 ふーん一次元配列から適当に要素を選び取ってくれるわけね。

引数についてみてみると
- aは一次元配列かintで、配列の場合要素から適当にchoiceして値が返ってくる。intの場合np.arange(a)からchoiceしてくる
- sizeはintかintのタプルで戻り値のshapeを指定する。intが与えられた場合は指定された数だけ要素を選んで一次元配列として返す - replaceは非復元抽出か復元抽出かのフラグ(非復元は配列から同じ要素をchoiceすることを認めない)
- pは配列aの各要素が取り出される際の確率分布を表す。指定しない場合は一様にchoiceする

というわけでパーティクルの重みをpにあたえれば重みに基づいた非復元抽出ができるはず。 pythonはこういう痒いところに手が届く関数がいろいろ用意されてて助かりますね。 この方向でパーティクルフィルタを実装してみようと思いますが、それは次回。 また、非復元抽出のアルゴリズムは累積重みを使う方法のほかにもいろいろあるっぽいのでそっちも今後調べたいと思います。