Python SciPy

SciPy를 활용한 신호 처리와 시계열 데이터 분석

PyExplorer 2025. 4. 1. 10:33
728x90

SciPy를 활용한 신호 처리와 시계열 데이터 분석

1. 개요

신호 처리와 시계열 데이터 분석은 과학, 공학, 금융, 의료 등 다양한 분야에서 데이터를 이해하고 활용하는 데 중요한 역할을 합니다. Python의 SciPy 라이브러리는 이러한 작업을 쉽게 수행할 수 있도록 다양한 기능을 제공하고 있습니다. 이번 포스팅에서는 SciPy를 활용하여 신호 처리와 시계열 데이터 분석을 수행하는 방법에 대해 자세히 살펴보겠습니다.


2. 시계열 데이터와 신호 처리의 기본 개념

2.1 시계열 데이터란?

시계열 데이터(Time Series Data)는 일정한 시간 간격으로 수집된 데이터를 의미합니다. 이러한 데이터는 시간에 따라 변화하는 패턴을 분석하고, 예측하거나 이상 징후를 감지하는 데 사용됩니다.

예:

  • 주식 시장의 일별 주가
  • 기상 관측소의 일기 예보 데이터
  • 센서에서 수집된 온도 및 습도 데이터

2.2 신호 처리란?

신호 처리는 시계열 데이터의 형태로 제공되는 신호를 분석하고 변환하는 과정입니다. 이는 노이즈 제거, 주파수 분석, 필터링 등과 같은 작업을 포함합니다.


3. SciPy를 활용한 신호 처리

SciPy의 scipy.signal 모듈은 다양한 신호 처리 기능을 제공합니다. 여기에서는 필터링, 푸리에 변환, 신호의 주파수 분석 등을 다루겠습니다.

3.1 필터링(Filter)

필터링은 시계열 데이터에서 특정 주파수 성분을 제거하거나 강조하는 과정입니다. 저역 통과(Low-pass), 고역 통과(High-pass), 대역 통과(Band-pass) 필터 등이 있습니다.

3.1.1 Butterworth 필터

Butterworth 필터는 평탄한 주파수 응답을 제공하는 필터입니다. 다음은 SciPy를 사용하여 신호에 저역 통과 필터를 적용하는 예제입니다.

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import butter, filtfilt

# 샘플링 주파수와 시간 축 생성
fs = 500.0  # 샘플링 주파수 (Hz)
t = np.linspace(0, 1.0, int(fs), endpoint=False)

# 신호 생성 (1Hz 및 50Hz 성분 포함)
signal = np.sin(2 * np.pi * 1 * t) + 0.5 * np.sin(2 * np.pi * 50 * t)

# Butterworth 저역 통과 필터 설계
b, a = butter(N=4, Wn=10, fs=fs, btype='low')
filtered_signal = filtfilt(b, a, signal)

# 결과 시각화
plt.figure(figsize=(12, 6))
plt.plot(t, signal, label='원본 신호')
plt.plot(t, filtered_signal, label='저역 통과 필터 적용', linewidth=2)
plt.xlabel('시간 (초)')
plt.ylabel('진폭')
plt.legend()
plt.title('Butterworth 저역 통과 필터 적용 결과')
plt.grid(True)
plt.show()

위 코드에서는 1Hz와 50Hz 성분을 가진 신호를 생성하고, 10Hz 이하의 주파수만 통과시키는 저역 통과 필터를 적용했습니다.

3.2 푸리에 변환(Fourier Transform)

푸리에 변환은 신호를 주파수 성분으로 변환하는 기법입니다. 이는 신호의 주파수 분석과 잡음 제거에 유용합니다.

다음은 SciPy의 scipy.fft를 이용해 신호의 주파수 성분을 분석하는 예제입니다.

from scipy.fft import fft

# 푸리에 변환 수행
yf = fft(signal)
xp = np.fft.fftfreq(len(t), 1 / fs)

# 주파수 스펙트럼 시각화
plt.figure(figsize=(12, 6))
plt.plot(xp[:len(xp) // 2], np.abs(yf)[:len(xp) // 2])
plt.xlabel('주파수 (Hz)')
plt.ylabel('진폭')
plt.title('푸리에 변환 결과')
plt.grid(True)
plt.show()

이 예제에서는 신호를 주파수 영역으로 변환하고, 주파수 성분을 시각화했습니다. 1Hz와 50Hz 성분이 명확하게 나타나는 것을 확인할 수 있습니다.


4. 시계열 분석

시계열 분석에서는 추세, 계절성, 불규칙성을 분석하는 과정이 포함됩니다.

4.1 이동 평균(Moving Average)

이동 평균은 시계열 데이터의 잡음을 줄이고 추세를 파악하는 데 유용합니다.

def moving_average(data, window_size):
    return np.convolve(data, np.ones(window_size) / window_size, mode='valid')

# 이동 평균 적용
window_size = 10
smoothed_signal = moving_average(signal, window_size)

# 시각화
plt.figure(figsize=(12, 6))
plt.plot(t, signal, label='원본 신호')
plt.plot(t[:len(smoothed_signal)], smoothed_signal, label='이동 평균 적용', linewidth=2)
plt.xlabel('시간 (초)')
plt.ylabel('진폭')
plt.legend()
plt.title('이동 평균 적용 결과')
plt.grid(True)
plt.show()

4.2 자기상관 함수(ACF)

자기상관 함수는 시계열 데이터 내에서 반복되는 패턴을 분석하는 방법입니다.

from statsmodels.graphics.tsaplots import plot_acf

plt.figure(figsize=(12, 6))
plot_acf(signal, lags=50)
plt.title('자기상관 함수 (ACF)')
plt.grid(True)
plt.show()

ACF는 특정 시차에서의 상관관계를 나타내며, 주기성을 분석하는 데 유용합니다.


5. 결론

이번 포스팅에서는 SciPy를 활용하여 신호 처리와 시계열 데이터 분석을 수행하는 방법에 대해 알아보았습니다. 필터링, 푸리에 변환, 이동 평균, 자기상관 함수 등 다양한 기법을 활용하면 데이터를 보다 효과적으로 분석하고 의미 있는 인사이트를 도출할 수 있습니다.


참고 문헌 및 자료

728x90