指数移動平均(EMA)フィルタの周波数特性

指数移動平均(EMA)フィルタの理論・周波数特性・Python実装を解説。Z変換で1次IIR伝達関数を導出し、numpy.arctan2・numpy.degrees でゲイン・位相特性を計算・可視化、scipy.signal.lfilter によるIIRフィルタ実装、平滑化係数αが決める平滑化と位相遅れのトレードオフ、移動平均・バターワースとの比較までローパスフィルタ設計の基礎をまとめます。

指数移動平均 (Exponential Moving Average; EMA)

指数移動平均(EMA)は、時系列データを平滑化する代表的な手法の一つです。現在の観測値と1ステップ前の平滑化された値に重み付けをして足し合わせることで、新しい平滑化値を計算します。

\[ y_t = (1 - \alpha) y_{t-1} + \alpha x_t \]

ここで、

  • \(y_t\) : 時刻 \(t\) におけるEMAの値
  • \(x_t\) : 時刻 \(t\) における元の観測値
  • \(\alpha\) : 平滑化係数(または平滑化率、\(0 < \alpha \le 1\) )

この式は、最近のデータに大きな重みを置きつつ、古いデータも完全に切り捨てずに考慮するという特徴があります。元の記事の式は \(\beta\) を使っていますが、一般的に \(\alpha\) が使われることが多いので、ここでは \(\alpha\) に統一します。元の記事の \(\beta\) は、ここでいう \(1-\alpha\) に相当します。

周波数特性:ゲイン特性と位相特性

フィルタの周波数特性は、入力信号の周波数成分がフィルタによってどのように変化するかを示します。これは、フィルタの伝達関数 \(G(s)\) を用いて分析されます。

上記のEMAの式をZ変換(離散時間システムの解析に用いられる)すると、伝達関数 \(G(z)\) は次のようになります。

\[ Y(z) = (1 - \alpha) z^{-1} Y(z) + \alpha X(z) \]

\[ G(z) = \frac{Y(z)}{X(z)} = \frac{\alpha}{1 - (1 - \alpha) z^{-1}} \]

ここで、\(z = e^{j\omega T}\) (\(T\) はサンプリング周期、ここでは \(T=1\) と仮定)とすると、周波数応答 \(G(j\omega)\) が得られます。

\[ G(j\omega) = \frac{\alpha}{1 - (1 - \alpha) e^{-j\omega}} \]

この周波数応答から、ゲイン特性 \(|G(j\omega)|\) と位相特性 \(\angle G(j\omega)\) を導出できます。

ゲイン特性

\[ |G(j\omega)| = \frac{\alpha}{\sqrt{1 - 2(1 - \alpha) \cos \omega + (1 - \alpha)^2}} \]

ゲイン特性:α=0.1〜0.9のEMAフィルタについて、角周波数ωに対するゲイン|G(jω)|をプロットしたもの。破線は-3dB点(1/√2)、丸印は各αの遮断角周波数ωcを示す

この式は \(\omega=0\) で \(|G(j0)| = \alpha / \alpha = 1\) となり、直流成分は減衰なく通過することが分かります。一方 \(\omega=\pi\) (ナイキスト周波数、\(T=1\) のときサンプリング周波数の半分)では \(|G(j\pi)| = \alpha / (2-\alpha)\) となり、\(\alpha\) が小さいほどこの値は0に近づく(強い平滑化)、\(\alpha\) が1に近いほど1に近づく(ほぼ素通し)ことが式からも確認できます。

-3dB遮断角周波数の導出

ゲイン特性が \(1/\sqrt{2}\) (-3dB点)まで低下する角周波数 \(\omega_c\) を、ゲインの2乗を\(1/2\) と置いて解析的に求めます。

\[ \frac{\alpha^2}{1 - 2(1-\alpha)\cos\omega_c + (1-\alpha)^2} = \frac{1}{2} \]

分母を払って \(\cos\omega_c\) について整理すると、

\[ \cos\omega_c = \frac{1 + (1-\alpha)^2 - 2\alpha^2}{2(1-\alpha)} \]

を得ます。さらに \(\omega\) が小さいとき \(\cos\omega \approx 1-\omega^2/2\) という近似を上式に適用すると、

\[ \omega_c \approx \frac{\alpha}{\sqrt{1-\alpha}} \]

という簡潔な近似式が導かれます。これを実際にPythonで数値計算した結果と突き合わせると次の通りで、\(\alpha=0.1\) のような小さい値では近似誤差が0.05%程度に収まる一方、\(\alpha\) が大きくなるにつれ小角近似が崩れて誤差が拡大することが分かります。

\(\alpha\)\(\omega_c\) (解析解, rad/sample)小角近似 \(\alpha/\sqrt{1-\alpha}\)近似誤差
0.10.105460.105410.05%
0.30.360520.358570.54%
0.50.722730.707112.16%
0.71.386421.278027.82%
0.93.14159(=π)2.846059.41%

エッジケース: \(\alpha=0.9\) の解析解が \(\pi\) (ナイキスト周波数そのもの)になっている点に注意してください。これは近似の問題ではなく、\(\alpha\) がある閾値を超えると通過帯域がナイキスト周波数まで達し、表現可能な周波数範囲内に-3dB点が存在しなくなることを意味します。実際、\(\omega=\pi\) でのゲインを計算すると \(|G(j\pi)| = 0.9/(2-0.9) = 0.818\) であり、\(1/\sqrt{2}=0.707\) を下回っていません。境界となる\(\alpha\) は \(|G(j\pi)| = 1/\sqrt2\) を解いて \(\alpha = 2 - \sqrt{2} \approx 0.5858\) と求まり、これより大きい\(\alpha\) では「-3dB遮断周波数」という概念自体がナイキスト周波数内に収まらなくなります。フィルタ設計時にこの点を見落とすと、意図した遮断特性が得られていると誤解する恐れがあります。

位相特性

\[ \angle G(j\omega) = \arctan\left(\frac{(1 - \alpha) \sin \omega}{1 - (1 - \alpha) \cos \omega}\right) \]

元の記事の式は符号が逆になっていますが、これは\(\arctan(Y/X)\) の計算において\(X\) と\(Y\) の符号の組み合わせを考慮する必要があるためです。一般的な定義では上記のとおりです。

位相特性:α=0.1〜0.9のEMAフィルタについて、角周波数ωに対する位相∠G(jω)(度)をプロットしたもの

考察(実際に計算した数値、\(\omega=\pi/8, \pi/4, \pi/2\) における値):

\(\alpha\)ゲイン@\(\pi/8\)位相@\(\pi/8\)ゲイン@\(\pi/4\)位相@\(\pi/4\)ゲイン@\(\pi/2\)位相@\(\pi/2\)
0.10.260863.93°0.136460.26°0.074341.99°
0.30.676737.17°0.424244.42°0.245834.99°
0.50.875619.58°0.678628.68°0.447226.57°
0.70.95649.02°0.857915.07°0.670516.70°
0.90.99072.41°0.96574.35°0.89555.71°
  • \(\alpha\) が小さい場合(例: \(\alpha=0.1\) ):フィルタの周波数帯域が狭くなり、より強い平滑化効果が得られます(\(\omega=\pi/8\) でゲイン0.26まで減衰)。しかし、位相遅れが大きくなります(同じ点で63.93°の遅れ)。
  • \(\alpha\) が大きい場合(例: \(\alpha=0.9\) ):平滑化能力は低下しますが(同じ点でゲイン0.99とほぼ素通し)、位相遅れは小さくなります(2.41°)。

これは、平滑化の度合いと応答速度(位相遅れ)の間にトレードオフがあることを示しています。なお、位相特性のグラフが \(\omega=\pi\) で必ず0°に収束するのは、\(\sin\pi=0\) より分子が恒等的に0になるためで、全ての\(\alpha\) に共通する構造的な性質です。

時定数によるもう一つの見方

EMAフィルタの伝達関数の極は \(z=1-\alpha\) にあり、これはステップ応答が指数関数的に \((1-\alpha)^n\) で減衰することを意味します。連続時間の一次遅れ系との対応から、サンプル単位の時定数 \(\tau\) は

\[ \tau = -\frac{1}{\ln(1-\alpha)} \]

で与えられます。計算すると、\(\alpha=0.1\) で \(\tau=9.49\) サンプル、\(\alpha=0.5\) で \(\tau=1.44\) サンプル、\(\alpha=0.9\) で \(\tau=0.43\) サンプルとなり、\(\alpha\) を大きくするほど応答が速くなる(=時定数が短くなる)ことが定量的に裏付けられます。実務上は、サンプリング周波数と欲しい応答速度から \(\tau\) を先に決め、\(\alpha = 1 - e^{-1/\tau}\) で逆算する設計手順がよく使われます。

プログラム

以下のPythonコードは、EMAフィルタのゲイン特性・位相特性・-3dB遮断角周波数を計算し、プロットするものです(実際にこのコードを実行して本記事の図を生成しています)。

import numpy as np
import matplotlib.pyplot as plt

# 平滑化係数αのリスト(代表値。0.2刻みで9本描くと重なって見づらいため5本に絞る)
ALPHAS = [0.1, 0.3, 0.5, 0.7, 0.9]
NUM_POINTS = 1000  # プロット点数

def get_gain(alpha, omega):
    """EMAフィルタのゲインを計算する"""
    denominator = np.sqrt(1 - 2 * (1 - alpha) * np.cos(omega) + (1 - alpha)**2)
    return alpha / denominator

def get_phase(alpha, omega):
    """EMAフィルタの位相を計算する (ラジアン)"""
    numerator = (1 - alpha) * np.sin(omega)
    denominator = 1 - (1 - alpha) * np.cos(omega)
    return np.arctan2(numerator, denominator)  # atan2で正しい象限の角度を得る

def cutoff_analytic(alpha):
    """-3dB遮断角周波数の解析解 cos(wc) = (1+(1-a)^2-2a^2) / (2(1-a))"""
    a = 1 - alpha
    cos_wc = (1 + a**2 - 2 * alpha**2) / (2 * a)
    cos_wc = np.clip(cos_wc, -1, 1)  # alphaが大きいとwcがpiを超えるため飽和させる
    return np.arccos(cos_wc)

omega = np.linspace(1e-6, np.pi, NUM_POINTS)  # 0からπ(ナイキスト周波数)まで

# 各alphaについてomega=pi/8, pi/4, pi/2での具体値と-3dB遮断角周波数を出力
for alpha in ALPHAS:
    for name, w in [("pi/8", np.pi/8), ("pi/4", np.pi/4), ("pi/2", np.pi/2)]:
        g = get_gain(alpha, w)
        p = np.degrees(get_phase(alpha, w))
        print(f"alpha={alpha}, omega={name}: gain={g:.4f}, phase={p:.2f}deg")
    print(f"alpha={alpha}: omega_c={cutoff_analytic(alpha):.5f} rad/sample")

# ゲイン特性のプロット
plt.figure(figsize=(8, 5))
plt.xlabel('Angular frequency (rad/sample)')
plt.ylabel('Gain')
plt.title('EMA Filter Gain Characteristics')
for alpha in ALPHAS:
    plt.plot(omega, get_gain(alpha, omega), label=f"alpha={alpha}")
plt.axhline(1/np.sqrt(2), linestyle='--', label='-3dB')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.savefig('Gain.png')

# 位相特性のプロット
plt.figure(figsize=(8, 5))
plt.xlabel('Angular frequency (rad/sample)')
plt.ylabel('Phase (degrees)')
plt.title('EMA Filter Phase Characteristics')
for alpha in ALPHAS:
    plt.plot(omega, np.degrees(get_phase(alpha, omega)), label=f"alpha={alpha}")
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.savefig('Phase.png')

実行結果(抜粋)は以下の通りです。

alpha=0.1, omega=pi/8: gain=0.2608, phase=63.93deg
alpha=0.1, omega=pi/4: gain=0.1364, phase=60.26deg
alpha=0.1, omega=pi/2: gain=0.0743, phase=41.99deg
alpha=0.1: omega_c=0.10546 rad/sample
alpha=0.5, omega=pi/8: gain=0.8756, phase=19.58deg
alpha=0.5, omega=pi/4: gain=0.6786, phase=28.68deg
alpha=0.5, omega=pi/2: gain=0.4472, phase=26.57deg
alpha=0.5: omega_c=0.72273 rad/sample
alpha=0.9, omega=pi/8: gain=0.9907, phase=2.41deg
alpha=0.9, omega=pi/4: gain=0.9657, phase=4.35deg
alpha=0.9, omega=pi/2: gain=0.8955, phase=5.71deg
alpha=0.9: omega_c=3.14159 rad/sample

数値は前節の表と完全に一致しており、解析的に導出した式が実装と整合していることを確認できます。

EMAと他のフィルタの比較

EMAフィルタは実装が簡単で計算コストが低い一方、他のフィルタと比較すると異なる特性を持ちます。

フィルタ遮断特性計算コストパラメータ数リアルタイム性
EMAなだらか\(O(1)\)1(\(\alpha\) )優秀
移動平均なだらか\(O(N)\)1(窓幅\(N\) )優秀
バターワース急峻(次数依存)\(O(N)\)2(次数、遮断周波数)良好
FIR/IIR設計次第\(O(N)\)多数FIR:良好, IIR:優秀

EMAは1次のIIRフィルタとして見ることができ、パラメータ\(\alpha\) のみで制御できる点が実務上の大きな利点です。より急峻な遮断特性が必要な場合は バターワースフィルタ を、位相遅れを最小化したい場合は ウィーナーフィルタ を検討してください。

scipy.signalを用いたEMAの実装

Pythonのscipy.signalモジュールを使うと、EMAをIIRフィルタとして実装できます。

import numpy as np
from scipy import signal

def ema_scipy(x, alpha):
    """scipy.signalを用いたEMA実装"""
    # EMA: y[n] = alpha * x[n] + (1 - alpha) * y[n-1]
    # IIRフィルタの伝達関数: H(z) = alpha / (1 - (1-alpha) * z^{-1})
    b = [alpha]           # 分子係数
    a = [1, -(1 - alpha)] # 分母係数
    return signal.lfilter(b, a, x)

# 使用例:5Hzのサイン波にノイズを加えた信号を平滑化する
np.random.seed(42)
t = np.linspace(0, 1, 1000)  # fs=1000 (相当)、1秒分
clean = np.sin(2 * np.pi * 5 * t)
noise = 0.5 * np.random.randn(len(t))
x = clean + noise

for alpha in [0.1, 0.5, 0.9]:
    y = ema_scipy(x, alpha)
    resid = y[50:] - clean[50:]  # 過渡応答が収まった後の残差ノイズ
    reduction = (1 - resid.std() / noise[50:].std()) * 100
    print(f"alpha={alpha}: output_std={y[50:].std():.4f}, resid_std={resid.std():.4f}, noise_reduction={reduction:.1f}%")

実行結果は以下の通りです(入力信号の標準偏差は0.8562、うち純粋なサイン波成分0.7068、ノイズ成分0.4894)。

alpha=0.1: output_std=0.6931, resid_std=0.2083, noise_reduction=57.5%
alpha=0.5: output_std=0.7631, resid_std=0.2804, noise_reduction=42.8%
alpha=0.9: output_std=0.8367, resid_std=0.4425, noise_reduction=9.7%

\(\alpha=0.1\) では残差ノイズの標準偏差が0.2083まで下がり、元のノイズ(0.4894)に対して57.5%のノイズ低減が得られています。一方 \(\alpha=0.9\) ではほぼ入力をそのまま通しているため低減率は9.7%にとどまります。これは前節で導出したゲイン特性(5Hz、\(T=1/1000\) s換算で \(\omega = 2\pi \times 5/1000 \approx 0.0314\) rad/sampleにおけるゲインが \(\alpha=0.1\) で0.958、\(\alpha=0.9\) で0.9999)と整合しており、信号成分をほぼ減衰させずにノイズだけを落とせているかどうかがノイズ低減率の差として現れています。

以下の図は、この入力信号と各\(\alpha\) でのEMA出力を時間領域で重ねたものです。\(\alpha=0.1\) (薄い青)は滑らかですが波形のピークに遅れて追従し、\(\alpha=0.9\) (濃い青)はノイズをほぼそのまま通してしまう一方で遅れがほとんどないことが視覚的に確認できます。

EMAの平滑化と位相遅れのトレードオフを示す時間領域波形。5Hzのサイン波にノイズを加えた入力(灰色)と真の信号(黒破線)に対し、α=0.1・0.5・0.9でのEMA出力を重ねてプロットしたもの。αが小さいほど滑らかだが遅れが大きく、αが大きいほどノイズが残るが遅れが小さい

この実装は自前のループ実装よりも高速で、scipy.signalの他のフィルタ関数(butterfirwin等)と統一的なインターフェースで扱えます。

最新研究動向:ニューラルネットの重みEMAという応用

信号処理のローパスフィルタとしてのEMAは古典的な手法ですが、同じ再帰的指数平滑化の数式は近年、機械学習モデルの学習過程にも応用されています。深層学習では、勾配降下法で更新される重み \(\theta_t\) に対して同じ漸化式を適用し、学習中の重みを平滑化した「EMAモデル」を推論に使う手法が広く使われています。

\[ \bar\theta_t = (1-\alpha)\bar\theta_{t-1} + \alpha\theta_t \]

機械学習分野では減衰率を \(1-\alpha\) 側に着目して \(\beta\) と書くことが多く、\(\beta=1-\alpha\) に相当します。

Morales-Brotons、Vogels、Hendrikxによる論文 “Exponential Moving Average of Weights in Deep Learning: Dynamics and Benefits”(Transactions on Machine Learning Research, 2024, arXiv:2411.18704 )は、この重みEMAの学習ダイナミクスを体系的に解析しています。同論文は、重みEMAが学習初期から良好な性能を示すこと、SGDと比べて学習率の減衰をより緩やかにできること(平滑化自体がノイズを抑制する暗黙的正則化として働くため)、さらにラベルノイズへの頑健性・予測の一貫性・キャリブレーション・転移学習性能の向上につながることを報告しています。重要な指摘として、EMAで得られる解は最終イテレーションの重みそのものとは異なる、独立した最適化経路の産物であるとしています。

また拡散モデルの学習では、Karrasらの “Analyzing and Improving the Training Dynamics of Diffusion Models”( arXiv:2312.02696 )が、学習後に事後的にEMAの減衰長を調整できる手法を提案し、ImageNet-512での画像生成品質(FID)を当時の最高記録である2.41から1.81まで改善しています。本記事で導出したゲイン・位相特性やカットオフ周波数の考え方は、時系列信号のローパスフィルタとしてだけでなく、こうした「学習軌跡という時系列」を平滑化する際のパラメータ選択(\(\alpha\) が小さいほど強く平滑化されるが過去の情報に強く依存する、というトレードオフ)を理解する上でも共通の枠組みとして役立ちます。

おすすめ書籍

はじめて学ぶディジタル・フィルタと高速フーリエ変換(三上直樹、CQ出版)

ディジタルフィルタと FFT の原理を基礎から丁寧に解説した定番の入門書です。本記事で扱った処理の理論的背景を体系的に学べます。

※ 上記は Amazon アソシエイトのリンクです。

関連記事

参考


関連ツール