006 Moving Average.ja

Timeseries

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.rollingewm を使った実装パターンをテンプレ化し、他の系列でもすぐ使い回せるようにします。

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」と覚えておくと使い分けが楽になります。