指数平滑移動平均とは?
移動平均について
移動平均とは、一定の期間の値から平均値を計算して表す値です。単純な平均値とは違い、時系列データの前後のいくつかのデータを足して平均をとるため、平均値が移動していくことから移動平均と呼ばれます。
指数平滑移動平均について
では指数平滑移動平均とは何でしょうか。これは単純な移動平均とは違い、過去の値よりも直近の値になるほど比重を置いて計算された平均値です。過去の値が減少し、直近の値の変動に対する反応が早くなるという特徴があります。
Pythonでのやり方
calc.py
import time
import math
import datetime
import csv
import pandas as pd
import numpy as np
def get_yaw(count):
acc = [0.0,0.0,0.0]
mag = [0.0,0.0,0.0]
date,acc[0],acc[1],acc[2],mag[0],mag[1],mag[2] = custum_get(count)
yaw_list = list()
for i in range(len(acc[0])):
acc[0][i] = float(acc[0][i])
acc[1][i] = float(acc[1][i])
acc[2][i] = float(acc[2][i])
mag[0][i] = float(mag[0][i])
mag[1][i] = float(mag[1][i])
mag[2][i] = float(mag[2][i])
roll_error, pitch_error = initial_error(acc[0][i],acc[1][i],acc[2][i])
roll = math.atan2(acc[1][i] , math.sqrt(acc[0][i]**2+acc[2][i]**2))
pitch = -math.atan2(acc[0][i] , math.sqrt(acc[1][i]**2+acc[2][i]**2))
numerator = math.cos(roll)*mag[1][i] - math.sin(roll)*mag[2][i]
denominator = math.cos(pitch)*mag[0][i] + math.sin(pitch)*math.sin(roll)*mag[1][i] + math.sin(pitch)*math.cos(roll)*mag[2][i]
yaw = math.atan2(numerator,denominator)
roll = math.degrees(roll) + roll_error
pitch = math.degrees(pitch) + pitch_error
yaw = math.degrees(yaw)
if yaw < 0:
yaw = 360 + yaw
yaw_list.append(yaw)
date_list=list()
for d in date:
d_s = d.split(' ')
date_list.append(d_s[1])
yaw_list = pd.Series(yaw_list)
#指数平滑移動平均の計算
yaw_list_x = yaw_list.ewm(span=10).mean()
yaw_list = yaw_list_x.values.tolist()
return yaw_list,date_list
if __name__ == '__main__':
count = 150
yaw,date = get_yaw(count)
print(len(yaw))
print(len(date))
実行結果
今回は地磁気センサから取得したデータからyaw角を計算するプログラムで指数平滑移動平均を用いた
平滑化に必要な部分はここです。
yaw_list_x = yaw_list.ewm(span=10).mean()
pandasのDataFrameおよび、Seriesに定義されているewm関数を使っています。
##参考
この記事を元に平滑化を行いました。
https://analytics-note.xyz/programming/pandas-ewma/