確率フィルタの特性を直観的に理解するためのツールを作ってみた

# はじめに
本投稿は，[数学 Advent Calendar 2016](http://qiita.com/advent-calendar/2016/math) 4日目の記事です．

確率フィルタを直観的に理解するためのツールを開発しましたので，ご紹介致します．数学☓プログラミング，という観点から，こちらに投稿することに致しました．

公開しようしようと思っていたのですがきっかけを掴めずにいたので，この場をお借りして公開することに致しました．

# アプリ概要
拙著，[シンプルなモデルとイラストでカルマンフィルタを直感的に理解してみる](http://qiita.com/MoriKen/items/0c80ef75749977767b43)，[なぜパーティクルフィルタの推定値に「重み付き平均」が使われるのかを考察してみた](http://qiita.com/MoriKen/items/da8d290dcefad81b478d#_reference-e5be0549f93d1b775a46)でも触れているように，ロボットの位置推定や画像内物体追跡等によく用いられるカルマンフィルタ(KF)やパーティクルフィルタ(PF)と言った確率フィルタは，直観的な特性の把握が難しい傾向があるように感じていました．

皆が使っているから，先生が使えといったから，先輩のプログラムで使われていたから，という理由（？）で何となく使われているような気がしなくもない，と言った印象です（私はそうです笑）．

そこで，こういった確率フィルタの特性をグラフィカルに描画するためのツールを作ったら，もっと理解できるようになるんじゃないかな？と思い立ち，***StefAny(State Estimation Filter Simulator for Any Practical Model)***を開発しました．

クリックするとデモ動画を閲覧できます．
　　　↓
[![スクリーンショット 2016-12-03 15.44.28.png](https://qiita-image-store.s3.amazonaws.com/0/110138/fae66f3b-e915-90de-201e-19a032c2f3bf.png)](https://youtu.be/2ilg-UH_IyE)

# 実績
という好奇心むき出しで作ったツールを学会で発表したところ，受賞をしてしまったり，ジャーナルにアクセプトされてしまったりで，意外と教育用途にも使えるのではないかと思い始めたりしました．
 
# バイナリ公開
というわけで，***StefAay***のバイナリを下記にて公開しています．

## GitHub リポジトリ
- [MoriKen254/StefAny_release](https://github.com/MoriKen254/StefAny_release)

## 公開条件
- 「研究/教育用途に限定」となります．
- コードは色々な事情で公開できません．はひー．

## 実行環境
|    項目   | 内容 |
|:--------:|:--------:|
| OS | Windows 10 |
| 実行対象モジュール | StefAny.exe |

もし実行できない場合は，後述のトラブルシューティングを参照下さい．

# ツールの概要
これ以降，ツールの説明を行います．変数とか用語の定義とかは上記論文に示していることとし，ここでは概要を説明することとします ^^;

# ソフトウェア構成

## 簡易クラス図
ざっくり，こんな感じです．

![3.1_ClassDiagram.png](https://qiita-image-store.s3.amazonaws.com/0/110138/fa519352-5052-b9f0-36d0-8c6af0349239.png)

## ディレクトリ構成

```
StefAny_release
│
├ StefAny.exe
│      ↑ GUI部．こいつを起動します．
├ state_estimate_filter.dll 
│      ↑ エンジン部．フィルタを計算するのはこれ．
└ opencv_core249.dll
       ↑ 行列演算にOpenCV 2.4.9 を使っています…．
```

## 開発環境

|    項目   | 内容 |
|:--------:|:--------:|
| OS | Windows 10 |
| フレームワーク | Microsoft .Net Framework 4.5 |
| 開発ツール | Visual Studio 2013 |
| 言語 | C#（GUI部），C++/CLI（エンジン部） |
| 行列演算ライブラリ | OpenCV 2.4.9 |

※行列演算のためだけにOpenCVを使用したのは反省です...．開発当時はEiganを知りませんでした ^^;

# 画面構成と機能
まずは，***StefAny*** の画面を構成する4つの主要な項目とそれらの機能について説明します．

## 画面要素 1: 粒子パラメータグラフ
フィルタの推定に関する詳細情報（e.g. , 事前・事前推定値，粒子重み・ヒストグラムなど）を表示します．マルコフ性を仮定したモデルの解析を想定し，指定時刻とその一時刻前の情報を比較できるような画面構成としています．

![スクリーンショット 2016-12-03 15.44.28 - コピー.png](https://qiita-image-store.s3.amazonaws.com/0/110138/e6f17634-1a0c-f9e2-670a-2f7d4a4bc16f.png)

## 画面要素 2: 時系列グラフ
シミュレーションの時系列情報（e.g. , 真値，観測値，フィルタ推定値，推定誤差など）を表示します．

![スクリーンショット 2016-12-03 15.47.21.png](https://qiita-image-store.s3.amazonaws.com/0/110138/9302482b-0b25-81d8-bd04-b320e7ca98fe.png)

## 画面要素 3: モデル選択・フィルタパラメータ設定領域
シミュレーション時に必要となるモデルやフィルタのパラメータの設定（e.g. , 状態空間モデルの選択，PF の粒子数の設定など）を行う領域です．

![スクリーンショット 2016-12-03 15.44.28 - コピー (2).png](https://qiita-image-store.s3.amazonaws.com/0/110138/c2dbe12f-82e9-71cb-8b09-1100050eb8ea.png)

モデルは，ランダムウォーク，等速直線運動，PFの評価でベンチマーク的に用いられる非線形関数から選択できます．

## 画面要素 4: 表示項目選択領域
グラフに表示させる項目（e.g. , 真値，観測値，推定値表示対象のフィルタ，粒子パラメータ）を選択します．着目したいパラメータだけの表示や、異なる複数のフィルタの推定結果の表示が可能です．ここで言う粒子パラメータとは，粒子数，粒子ノイズ分散と言った，PF 特有のパラメータを指すこととしています．

![スクリーンショット 2016-12-03 15.44.28 - コピー (3).png](https://qiita-image-store.s3.amazonaws.com/0/110138/5489595d-6500-6303-bc06-1afa6d8e6d6c.png)

フィルタは，Extended Kalman Filter(EKF)，Unscented Kalman Filter(UKF)，PFから選択できます．

PFの点推定手法は，Minimum Mean Square Error(MMSE)推定，Max Weight(MW)推定，MAP(Maximum A Posteriori)推定から選択できます．

# 粒子パラメータグラフの詳細

ここでは，StefAny 最大の特長である粒子パラメータの表示について述べます．

表示項目は， (1) KF の事前・事後推定値，(2) PF の各粒子の分布と重み，(3) PF の各粒子のリサンプリング後の分布と重み，(4) 点推定値，の4つです．

(1) で KF の情報を表示した理由は，(2) ～ (4)で示す PF の特性との比較を行えるようにするためです．これらの表示方法を StefAny の画面と対応させて説明します．

## 詳細表示 1: KF の事前・事後推定値
KF の事前推定値を破線で，事後推定値を実線で示しています．観測値を同時に示すことで，事前推定値から事後推定値が計算される過程の直観的な理解を支援します．また真値を同時に示すことで，事後推定値との誤差の評価を可能とします．

![3.3.a_KFEstimate.png](https://qiita-image-store.s3.amazonaws.com/0/110138/02df77ec-6481-d05b-e51e-660b224ed99b.png)

## 詳細表示 2: PF の各粒子分布・重み（リサンプリング前）
PF の各粒子の重みを黒色の丸による散布図で，粒子分布のヒストグラムを灰色の棒グラフで示しています．

![3.3.b_PFParticleDetail.png](https://qiita-image-store.s3.amazonaws.com/0/110138/3fba9538-5bbd-c16a-905f-6959a52e053d.png)

## 詳細表示 3: PF の各粒子分布・重み（リサンプリング後）
リサンプリング後の各粒子の重みを赤色の丸による散布図で，粒子の状態に対する分布のヒストグラムを赤色の棒グラフで示しています．詳細表示 1 と比較することで，リサンプリング前後における粒子分布とヒストグラムの変化を観察できます．

![3.3.c_PFParticleDetailAfterResample.png](https://qiita-image-store.s3.amazonaws.com/0/110138/156d9cc1-8eb5-0353-1992-c3a236f5da7d.png)

## 詳細表示 4: PF の点推定値
粒子の事後確率分布を緑色の丸で，それから抽出した唯一の点推定値を緑の実線で示しています．

![3.3.d_PointEstimation.png](https://qiita-image-store.s3.amazonaws.com/0/110138/4f9f8b1c-3ab1-0541-703b-1cf4b64f14cd.png)

# 使い方
## 1. モデルを設定します

![usege_01.png](https://qiita-image-store.s3.amazonaws.com/0/110138/ca3da741-0bd5-5824-c9ff-ef2600bc0209.png)

## 2. アルゴリズムを実行します
1.で「Apply」ボタンを押すと真値と観測値が先に表示されます．「Run」ボタンを押すと，各推定アルゴリズムが走ります．

![usege_02.png](https://qiita-image-store.s3.amazonaws.com/0/110138/446666bb-58fd-367d-02e6-a2374c772855.png)

## 3. 描画します
2.で全てのアルゴリズムが走り終えたら，「Draw」ボタンが有効になるので，押下します．

![usege_03.png](https://qiita-image-store.s3.amazonaws.com/0/110138/1a62ae61-f0ab-2901-8cd6-0daa86ab9c4c.png)

## 4. 表示項目を選択します

描画されれば，あとは表示パラメータを選択できます．解析したい内容に合わせて，チェックボックスを選択して下さい．

![usege_04.png](https://qiita-image-store.s3.amazonaws.com/0/110138/6e226f1e-e253-bfec-2898-5223adc876ad.png)

# トラブルシューティング
## Windows によって PC が保護されました」という警告が表示される場合

悪意あるプログラムではないので，信頼して頂けるなら下記の手順で実行して下さい．

1．詳細情報を選択します
![trouble_shoot_01.png](https://qiita-image-store.s3.amazonaws.com/0/110138/f4e2a6eb-c8d6-1d5e-8df7-8c06768af34b.png)

2．「実行」ボタンをクリックします
![trouble_shoot_02.png](https://qiita-image-store.s3.amazonaws.com/0/110138/b3846bd3-710d-d4b9-ee5d-6e195fa791af.png)

## Windowsセキュリティの警告 が表示される場合
ダウンロードした全てのモジュール(*.exe, *.dll)について，下記の手順でセキュリティブロックを解除します．

1．ファイルを右クリック→プロパティを開きます

2．セキュリティ→ブロックの解除を選択します
![trouble_shoot_03.png](https://qiita-image-store.s3.amazonaws.com/0/110138/4ff9b4c6-5489-01b6-8767-9932505eb9e3.png)

3．再度「StefAny.exe」を実行します

## 実行しても何も起こらない場合
特に開発環境をインストールしていないWindows10での動作確認はできていますが，まれに実行環境が整備されていない場合があるようです．

その場合は，下記ソフトウェアのインストールをしてみて下さい．

- [Visual Studio 2013 の Visual C++ 再頒布可能パッケージ](https://www.microsoft.com/ja-jp/download/details.aspx?id=40784)
- [Microsoft .NET Framework 4.5.*](https://www.microsoft.com/ja-JP/download/details.aspx?id=42643)

# おわりに
確率フィルタの直観的理解を支援するツールについて，簡単ながらご紹介しました．
本ツールの有効性に関する詳細な議論については，当該論文をご参照頂けましたら幸いです．

# 謝辞
今回のツール公開にあたり[九州工業大学 西田研究室](http://lab.cntl.kyutech.ac.jp/~nishida/index.html)のメンバー，[九州工業大学 自律移動ロボット製作サークル](https://github.com/CIR-KIT)のメンバーに，ご多忙の中動作確認等のご協力をして頂きました．

この場をお借りして，深く感謝申し上げます．

# 参考文献
- [森田 賢, 西田 健, "状態推定フィルタ統合シミュレータ"StefAny"の開発," FAN2015, pp.121-126, Sep. 2015.](http://www.ecei.tohoku.ac.jp/fan2015/award)
- [Masaru Morita, Takeshi Nishida, "Development of state estimation filter simulator built on an integrated GUI framework," Journal of Advanced Computational Intelligence and Intelligent Informatics, Vol.20, No.5, pp.721-729, 2016.](https://www.fujipress.jp/jaciii/jc/jacii002000050721/)