In [2]:
import numpy as np
import matplotlib.pyplot as plt
from signal_processor import SignalProcessor
# 시간 배열 생성: 0부터 5 + 0.01 까지 0.01 간격으로 생성 (총 501개 데이터 포인트)
time = np.arange(0, 5 + 0.01, 0.01)
# 노이즈 생성: 평균 0, 표준편차 0.5인 정규분포를 따르는 랜덤 노이즈
# time.shape와 동일한 크기로 생성하여 신호와 더할 수 있도록 함
noise = np.random.normal(0, 0.5, size=time.shape)
# 신호 생성: 사인파에 노이즈를 더한 합성 신호
# np.sin(time)은 순수한 사인파 신호, noise를 더해서 실제 측정된 것처럼 노이즈가 포함된 신호를 만듦
signal = np.sin(time) + noisemoving average, low-pass 필터를 적용하고 원본과 비교해본다
In [3]:
sp = SignalProcessor(window_size=5, alpha=0.1)
# moving average 필터를 위한 리스트
ma_output = []
# low-pass 필터를 위한 리스트
lp_output = []
for val in signal:
ma_output.append(sp.moving_average(val))
lp_output.append(sp.low_pass_filter(val))
sp.plot_signals(time, signal, ma_output, lp_output)확대해서 각각의 차이를 알아보자
In [4]:
sp.plot_signals(time, signal, ma_output, lp_output, [1.2, 1.6])Moving Average와 Low-Pass Filter
Moving Average (이동 평균)
정의: Moving Average는 시계열 데이터에서 노이즈를 제거하고 추세를 파악하기 위해 사용하는 필터다. 일정한 윈도우 크기 내의 데이터 포인트들의 평균을 계산한다.
수식:
여기서:
- : 필터링된 출력 신호
- : 입력 신호
- : 윈도우 크기 (window size)
원리:
- 각 시점에서 과거 개의 데이터 포인트의 평균을 계산한다
- 노이즈는 랜덤하게 분포되어 있기 때문에 평균을 내면 상쇄되어 감소한다
- 신호의 급격한 변화를 완화시켜 부드러운 곡선을 만든다
사용 예시:
- 주식 가격의 추세 분석 (5일, 20일, 50일 이동평균선)
- 센서 데이터의 노이즈 제거
- 실시간 데이터 스무딩
- 경제 지표 분석
장점: 구현이 간단하고 계산 비용이 낮다
단점: 지연(lag)이 발생하고, 급격한 변화에 대한 반응이 느리다
Low-Pass Filter (저역 통과 필터)
정의: Low-Pass Filter는 주파수 영역에서 고주파 성분을 차단하고 저주파 성분만 통과시키는 필터다. 신호 처리에서 노이즈(고주파)를 제거하고 원본 신호(저주파)를 유지하는 데 사용한다.
수식 (지수 이동 평균 기반):
여기서:
- : 필터링된 출력 신호
- : 입력 신호
- : 필터 계수 (0 < < 1), 값이 작을수록 더 강한 필터링
원리:
- 현재 입력값과 이전 출력값의 가중 평균을 계산한다
- 값이 작으면 이전 값의 영향이 커져서 더 부드러운 신호가 된다
- 고주파 노이즈는 빠르게 변하기 때문에 필터링되어 감쇠되고, 저주파 신호는 유지된다
사용 예시:
- 오디오 신호 처리 (고주파 노이즈 제거)
- 이미지 처리 (블러 효과, 노이즈 제거)
- 센서 데이터 필터링 (가속도계, 자이로스코프)
- 통신 시스템 (신호 복원)
- 생체 신호 처리 (ECG, EEG)
장점: 실시간 처리에 적합하고, 메모리 사용량이 적다
단점: Moving Average보다 계산이 약간 복잡하지만, 더 부드러운 결과를 제공한다
두 필터의 차이점
| 특성 | Moving Average | Low-Pass Filter |
|---|---|---|
| 계산 방식 | 과거 N개 데이터의 평균 | 지수 가중 평균 |
| 메모리 | N개 데이터 저장 필요 | 이전 출력값 1개만 저장 |
| 지연 | 윈도우 크기에 비례 | 상대적으로 적음 |
| 반응 속도 | 느림 | 상대적으로 빠름 |
| 부드러움 | 중간 | 높음 |
| 적용 분야 | 추세 분석, 통계 | 실시간 신호 처리 |
In [5]:
time = np.arange(0, 4 + 0.01, 0.01)
square_wave = np.where((time % 2) < 1, 0, 2)
noise = np.random.normal(0, 0.2, size=time.shape)
signal = square_wave + noise
plt.figure(figsize=(10, 4))
plt.plot(time, signal, label='Square Wave with Noise')
plt.plot(time, square_wave, label='Square Wave', linewidth=2, linestyle="--")
plt.xlabel("Time (sec)")
plt.ylabel("Square Wave (0 to 2) with Noise (σ=0.2)")
plt.legend()
plt.show()
In [6]:
sp = SignalProcessor(window_size=5, alpha=0.2)
ma_output = []
lp_output = []
for val in signal:
ma_output.append(sp.moving_average(val))
lp_output.append(sp.low_pass_filter(val))
sp.plot_signals(time, signal, ma_output, lp_output)In [7]:
sp.plot_signals(time, signal, ma_output, lp_output, [0.9, 1.5])In [8]:
time = np.arange(0, 2 + 0.01, 0.01)
signal = np.where(np.isclose(time, 1, atol=1e-8), 1, 0)
sp = SignalProcessor(window_size=5, alpha=0.5)
ma_output = []
lp_output = []
for val in signal:
ma_output.append(sp.moving_average(val))
lp_output.append(sp.low_pass_filter(val))
sp.plot_signals(time, signal, ma_output, lp_output, [0.75, 1.5])확실히 low-pass filter 가 급격한 변화에 대한 반응을 더 잘 한다고 할 수 있다.