はじめに
最近は、プログラミングで統計値を使うことが多くなってきました。
しかし、
あるデータが出尽くしているような状態で解析を実施する
いわゆるオフライン解析ではあまり問題にならないですが、
ロボティクスのように、センサのデータを逐次的に解析するような
オンライン解析を実施するプログラムでは、
統計値の計算の際に悩んでしまうことがあります。
例えば、有るデータの平均値を計算したい時に、
普通の平均の計算は全データを必要としますが、
そのためにはすべてのデータをメモリ上に保持しなくてはいけません。
しかし、オンライン計算が必要な組み込みシステムでは
使用できるメモリが限られているという問題があります。
そこで、
すべてのデータを保持せずに、
統計値を計算する方法が提案されているので、
それらの方法を説明したいと思います。
最大値最小値の逐次計算
これは簡単です、
最小値と最大値を格納する変数を準備し、
非常に大きい値と、小さい値に初期化しておいて、
逐次的に最大値と最小値を更新することで実現できます。
平均値の逐次計算
平均値は一つ前の平均値と、
これまで計算した値の数を保持することで、
逐次的に平均値を計算することができます。
更新の計算方法は下記の式の通りです。
\bar{x}は平均値、xは得られた値、そしてNはデータ数になります。
上記の式を使うことにより、
平均値とこれまで計算に使った値のみを保持すれば良いので、
受け取ったデータをすべて保持すること無く、
平均値の計算することができます。
C++でクラスを作成すると、このような感じでしょうか。
/** * @brief 逐次平均計算によるMean Filterを実施するクラスライブラリ * @note 使い方 * MeanFilter filter; * while(true){ * double rawData=GetData(); * double mean=filter.CalcMean(rawData); //平均値の取得 * } */ class MeanFilter{ public: MeanFilter(){ InitMember(); } /** * @brief 平均値を計算する関数 * * @param value 生データ * * @return 平均値 */ double CalcMean(double value){ totalNumber_++; mean_+=(value-mean_)/static_cast<double>(totalNumber_); return mean_; } private: unsigned int totalNumber_;//データの総数 double mean_;//平均値 /** * @brief メンバ変数の初期化関数 */ void InitMember(){ totalNumber_=0; mean_=0; } };
ガウス分布パラメータの逐次計算
作成中