title: “チェック6: 移動平均でノイズを抑える” linkTitle: “06 移動平均” pre: “5.1.6 ” weight: 6 created: 2019-05-18T22:49:48+09:00 lastmod: 2025-11-05T00:00:00+09:00 header_image: “/images/bg/france.jpg” searchtitle: “単純移動平均・加重移動平均・指数移動平均をPythonで計算する方法” #
まとめ
- 天然ガス消費量(NATURALGAS)の月次データを例に、3 種の移動平均(SMA/WMA/EMA)を比較します。
- 上限・下限バンドを作ることで、消費量が異常に多い/少ない月を簡単に検知できます。
pandas.rollingやewmを使った実装パターンをテンプレ化し、他の系列でもすぐ使い回せるようにします。
1. ライブラリ #
import japanize_matplotlib as jm
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
jm.japanize()
(full_fred を利用すると FRED から最新データを取得できますが、ここではサンプルとして埋め込み済みの辞書を使用します。)
2. データを DataFrame にまとめる #
data = {
"value": {
"2013-01-01": 2878.8,
...
"2021-12-01": 3012.3,
}
}
data = pd.DataFrame(data)
data.index = pd.to_datetime(data.index)
data = data.rename(columns={"value": "Natural Gas Consumption(BCF)"})
plt.figure(figsize=(12, 6))
sns.lineplot(data=data)
plt.title("天然ガス消費量(BCF)")
plt.show()
3. 単純移動平均(SMA) #
最新 12 ヶ月の平均・最大・最小を計算します。
data_sma = data.copy()
rolling_obj = data_sma["Natural Gas Consumption(BCF)"].rolling(12)
data_sma["SMA(12)"] = rolling_obj.mean()
data_sma["RollingMax(12)"] = rolling_obj.max()
data_sma["RollingMin(12)"] = rolling_obj.min()
plt.figure(figsize=(12, 6))
sns.lineplot(data=data_sma[["Natural Gas Consumption(BCF)", "SMA(12)", "RollingMax(12)", "RollingMin(12)"]])
plt.title("SMA と上下バンド")
plt.show()
使いどころ #
- 季節性のある系列でも滑らかなトレンドを得たいとき
- 異常値検知(上限・下限バンドから外れた月をマーキング)
4. 加重移動平均(WMA) #
最近の観測ほど重みを大きくしたい場合は rolling().apply() を使います。
weights = np.array([0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0])
def get_wma(values, w=weights):
return np.sum(w * values) / w.sum()
data_wma = data.copy()
data_wma["WMA(12, center=True)"] = (
data_wma["Natural Gas Consumption(BCF)"]
.rolling(12, center=True)
.apply(get_wma, raw=True)
)
data_wma["WMA(12, center=False)"] = (
data_wma["Natural Gas Consumption(BCF)"]
.rolling(12, center=False)
.apply(get_wma, raw=True)
)
plt.figure(figsize=(12, 6))
sns.lineplot(data=data_wma)
plt.title("加重移動平均(center True/False)")
plt.show()
center=Trueにすると窓の中央に値を配置でき、季節性の中心を取りたいときに便利です。
5. 指数移動平均(EMA) #
古い観測を指数的に減衰させる方法です(いわゆる平滑化指数)。adjust=False にすると通常の定義に一致します。
data_ema = data.copy()
data_ema["EMA(12)"] = (
data_ema["Natural Gas Consumption(BCF)"].ewm(span=12, adjust=False).mean()
)
plt.figure(figsize=(12, 6))
sns.lineplot(data=data_ema)
plt.title("指数移動平均 (EMA)")
plt.show()
EMA は最新値への追従性が高いので、オンライン予測や在庫管理などリアルタイムな分析で重宝します。
6. まとめ #
| 種類 | 特徴 | 実装 |
|---|---|---|
| SMA | 全観測を均等に平均 | Series.rolling().mean() |
| WMA | 重みをカスタム、窓の中心をずらせる | rolling().apply() |
| EMA | 指数減衰、最新値に敏感 | Series.ewm().mean() |
どの移動平均を選ぶかは目的しだいですが、「まず SMA でトレンド」「短期変動を見たいなら EMA」「季節サイクルの中心を取りたいなら WMA」と覚えておくと使い分けが楽になります。