まとめ- 天然ガス消費量(NATURALGAS)の月次データを例に、3 種の移動平均(SMA/WMA/EMA)を比較します。
- 上限・下限バンドを作ることで、消費量が異常に多い/少ない月を簡単に検知できます。
pandas.rolling や ewm を使った実装パターンをテンプレ化し、他の系列でもすぐ使い回せるようにします。
1. ライブラリ
#
1
2
3
4
| import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
|
(full_fred を利用すると FRED から最新データを取得できますが、ここではサンプルとして埋め込み済みの辞書を使用します。)
2. データを DataFrame にまとめる
#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| 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 ヶ月の平均・最大・最小を計算します。
1
2
3
4
5
6
7
8
9
10
| 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() を使います。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| 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 にすると通常の定義に一致します。
1
2
3
4
5
6
7
8
9
| 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」と覚えておくと使い分けが楽になります。