バスケットボールでは、相手のフェイントに惑わされぬよう腰に注目します。どんなに激しく動いても、腰が動く先が相手の動く先だからです。柔道では釣り手(相手の襟をつかんだ手)の感覚に注意を払います。釣り手を通して伝わって来る相手の体(たい)の動きが、相手の技の全てを表しているからです。
とかく細かな動きにとらわれると、本質をとらえることが難しくなってしまいます。今回学習するのは、データの細かな変動を緩和し、生のデータからでは得られなかった傾向をつかむための便利な手段です。
移動平均
移動平均[1]とは、細かな変動を含むデータをスムーズにする(平滑化する)方法です。
平均をとるというと、100個のデータの総計を、データの個数100で割って1つの値を得ることですが、これではデータ全体が増加傾向・減少傾向を持つのか、それともあるピークを持っている山形・谷型の分布を示すのかといった貴重な情報が失われてしまいます。
移動平均は、細かなギザギザを持つグラフになるデータを、なめらかな曲線のグラフになるデータに変換します。
ノイズの多い信号データを受け取った場合に、移動平均をとれば、ノイズの緩和されたデータに出来ます。
株価の細かな変動を平滑化して、ある区間での平均的な株価を得る場合にも利用されます。
図58.2に移動平均の取り方を示します。連続するデータのひとつDiに注目し、自分を含む周囲のデータの平均値をとります。この計算を次々と実行していった結果、グラフの形は凹凸の少ないものになります。
例えば時系列に並んだ100個のデータがあるとします。平均をとる範囲を5とすると、10番目のデータD10の値は、次の式で移動平均値に換算されます[2]。
先頭から順番にデータを処理する場合には、D8やD9の値に「移動平均をとる以前の値」を用いるように注意してください。また、別法として、「注目するデータの位置を含む前方(過去)範囲の平均を取る」ことも出来ます。こちらの方がアルゴリズムが単純です。
問題 移動平均をとるプログラムを作りましょう
前回作成したデータファイルを読み込んで、移動平均をとり、またファイルに出力するプログラムを作りましょう。ファイルの入力と、計算結果の出力には、標準入力と標準出力を用い、UNIXやWindowsのコマンドラインのリダイレクト機能を活用しましょう。Windowsならば、コマンドラインから次のように実行しましょう。
この操作により、標準入力を使ってst_sample002.csvがプログラムSample_MovingAverageに読み込まれ、計算結果がresult_ma.csvに書き込まれます。
ソースコードの大枠を次に示しますので、コードの不足している関数CalcMovingAverageにコードを書き加えて完成させてください。
解説
問題 移動平均をとるプログラムを作りましょう
コードの補充が完了した関数を示します。注目するデータ位置に対して前方範囲の平均を取るシンプルなアルゴリズムです。
引数rangeから導かれる、移動平均を計算できない先頭と末尾の部分には0を格納します。いちいち5個ずつの平均をとらずとも、先ほど合計した値から範囲を外れた値を引き、新しく範囲に入ったデータを加算して新しい合計を得れば、ずいぶん効率が良く計算できます。さて、今回もOpenOfficeのCalcで読み込んで、散布図を表示してみましょう。
図58.3と58.4を比較すると、特に図58.3で目立っていた横軸20ごとの突出はほぼ姿を消しました。そのかわりに広く分布していたデータが図58.4ではぎゅっと締まった印象があります。
今回のサンプルデータは、もともと線形で行儀の良い傾向を持っていましたから、ありがたみが薄く感じられますが、よりばらつきや細かな振動の多いデータでしたら、この移動平均が傾向をつかむために効果を発揮します。
今回はここまで
移動平均という、データのぶれをスムーズにするツールを紹介しました。
表計算ソフトウエアを利用しても良いのですが、rangeを自由に選択したり、コマンドライン一発で結果が得られたりするのはプログラムを作成して処理することで得られる大きな利点です。理屈は大変シンプルで、コードにするのも簡単です。それでありながら、効果的なツールとして使えますから、おぼえておいて損はないでしょう。