이번에는 시계열 데이터 분석에서, 잡음을 최소화 시키고 시계열상 특정 패턴을 극대화 시키는
Mexican Hat Wavelet Transform에 대해서 알아보겠습니다.
개념 정리 뿐만 아니라 파이썬 코드를 활용해서 예제 데이터에 대한 변환 및 결과 시각화 또한 진행해보겠습니다.
1. Mexican hat wavelet transform
- Mexican Hat Wavelet(Ricker Wavelet이라고도 불립니다)은 Gaussian 함수의 2차 미분 형태로 정의된 wavelet 입니다.
이를 수식적으로 알아보면 아래와 같습니다.
* 여기서 t는 시간 축을 뜻하고, sigma는 scale을 뜻하고 이 값을 조정하면 wavelet의 넓이와 진폭이 조절되게 됩니다.
* sigma 값이 클수록 wavelet이 더 넓게 펼쳐지고 작을 수록 국소적 패턴에 더 민감하게 반응하게 됩니다.
- 이 함수는 중심에서 크게 발산한 후, 양 옆으로는 급겹히 줄어드는 종 모양의 커브를 가지게 되며, 이를 통해 시계열 데이터의 국부적(local) 특징을 강조하고, 특정 시간 구간에서 주파수 변화나 패턴의 차이를 민감하게 탐지할 수 있게 해줍니다.
- Maxican Hat Wavlet 함수에 대해서 시각화 해보면 아래와 같습니다.
import numpy as np
import matplotlib.pyplot as plt
def mexican_hat_wavelet(t, scale=1.0):
"""
Mexican Hat Wavelet (Ricker Wavelet) 생성 함수
Parameters:
t : np.ndarray : 시간 또는 위치 벡터
scale : float : 스케일 파라미터, 주파수 대역을 조정
Returns:
wavelet : np.ndarray : Mexican Hat Wavelet
"""
C = 2 / (np.sqrt(3) * np.pi**0.25) # 정규화 상수
wavelet = C * (1 - (t / scale)**2) * np.exp(-(t / scale)**2 / 2)
return wavelet
# 시간 벡터 생성
t = np.linspace(-5, 5, 500)
# 다양한 스케일로 Mexican Hat Wavelet 생성
scales = [0.5, 1.0, 2.0]
# 시각화
plt.figure(figsize=(10, 6))
for scale in scales:
wavelet = mexican_hat_wavelet(t, scale=scale)
plt.plot(t, wavelet, label=f'Scale = {scale}')
plt.title('Mexican Hat Wavelet (Ricker Wavelet)')
plt.xlabel('Time (t)')
plt.ylabel('Amplitude')
plt.legend()
plt.grid(True)
plt.show()
*이와 같이 scale(sigma) 값이 클수록 조금더 완만한 모자패턴을 보이며, scale이 작을수록 보다 좁은 구간에 대한 정보만 강조하는 패턴을 보이게 됩니다.
- 이러한 Maxican Hat Wavelet을 활용해 시계열 데이터를 변환(Transform) 하게되면 다음과 같은 장점을 가질 수 있습니다.
1) 국소적 시간-주파수 분석
* 이 wavelet은 특정 시간 구간에서 일어나는 변화에 민감하게 반응하게 되는데, 중심 근처에서 높은 진폭을 가지지만, 양 옆으로 갈수록 급격히 줄어들게 됩니다. 그렇기에 국소적인 패턴을 증폭시킬 수 있게됩니다.
2) Edge 및 Sharp transition 감지
* 이 wavelet은 신호의 급격한 변화의 edge 또는 sharp transition을 탐지할 수 해줍니다. 즉, 신호의 중간 부분에서 변화가 생기게 된다면 이 변화를 증폭시켜주기 때문입니다.
3) 다중 스케일 분석
* 위 그림에서 보았듯 scale(sigma) 값을 변경하여 적용한다면, 국소적인 패턴에 대한 scale 또한 달라지기에 다양한 scale에서 변화가 증폭된 모습을 확인할 수 있습니다.
2. 예시 데이터를 통해 확인해보는 Mexican Hat Wavelet Transform
- 이번에는 시계열 데이터 예시를 생성해서 해당 Transform의 역할에 대해서 알아보겠습니다.
- 먼저, sine 함수에 노이즈를 추가한 시계열 데이터를 만들어줍니다.
# 예시 시계열 데이터 생성
np.random.seed(42)
time_steps = np.linspace(0, 50, 500)
signal = np.sin(time_steps) + np.random.normal(scale=0.5, size=time_steps.shape)
# 시계열 데이터 시각화
plt.figure(figsize=(10, 4))
plt.plot(time_steps, signal, label='Original Signal')
plt.title('Original Time Series Signal')
plt.xlabel('Time Steps')
plt.ylabel('Signal Value')
plt.grid(True)
plt.show()
- 다음으로 Mexican hat wavelet transform을 정의한 뒤, scale을 1로 해놓고 변환을 시켜보겠습니다.
from scipy.signal import convolve
import numpy as np
import matplotlib.pyplot as plt
def mexican_hat_wavelet(t, scale=1.0):
"""
Mexican Hat Wavelet (Ricker Wavelet) 생성 함수
Parameters:
t : np.ndarray : 시간 또는 위치 벡터
scale : float : 스케일 파라미터, 주파수 대역을 조정
Returns:
wavelet : np.ndarray : Mexican Hat Wavelet
"""
C = 2 / (np.sqrt(3) * np.pi**0.25) # 정규화 상수
wavelet = C * (1 - (t / scale)**2) * np.exp(-(t / scale)**2 / 2)
return wavelet
# Mexican Hat Wavelet 변환 적용
scale = 1.0
wavelet = mexican_hat_wavelet(np.linspace(-5, 5, 100), scale=scale)
# Convolution을 통해 시계열 데이터에 변환 적용
transformed_signal = convolve(signal, wavelet, mode='same')
# 변환된 시계열 데이터 시각화
plt.figure(figsize=(10, 4))
plt.plot(time_steps, transformed_signal, label='Wavelet Transformed Signal', color='orange')
plt.title('Wavelet Transformed Signal')
plt.xlabel('Time Steps')
plt.ylabel('Transformed Signal Value')
plt.grid(True)
plt.legend()
plt.show()
* 전반적인 패턴을 잘 포착하면서도 세부적인 noise를 제거해줌으로써 결과적으로 원형인 sine의 파형에 가까운 형태를 얻어낼 수 있는 것을 확인할 수 있습니다.
- 다음은 스케일을 바꿔가면서 진행해보겠습니다.
# 다양한 스케일로 시계열 데이터를 변환
scales = [0.5, 1.0, 2.0]
transformed_signals = []
for scale in scales:
wavelet = mexican_hat_wavelet(np.linspace(-5, 5, 100), scale=scale)
transformed_signal = convolve(signal, wavelet, mode='same')
transformed_signals.append(transformed_signal)
# 여러 스케일에서의 변환 결과 시각화
plt.figure(figsize=(10, 6))
for i, scale in enumerate(scales):
plt.plot(time_steps, transformed_signals[i], label=f'Scale = {scale}')
plt.title('Wavelet Transformed Signals at Different Scales')
plt.xlabel('Time Steps')
plt.ylabel('Transformed Signal Value')
plt.legend()
plt.grid(True)
plt.show()
* 스케일이 크게되면 전반적인 패턴을 더 강조하게 되는 것을 알 수있고, 스케일을 작게하면 전반적인 패턴 뿐만 아니라 국소적인 변화의 전반적인 변화까지 포착하는 모습을 알 수 있습니다.
- 이번에는 실제 데이터를 가지고 분석을 진행해보겠습니다. 분석에 활용할 데이터는 tsai 라이브러리를 활용해 UCR timeseries classification dataset 중 basic motions라는 데이터를 활용해보겠습니다.
- 먼저 tsai library를 설치해줍니다.
- 그리고 maxican hat wavelet transform을 정의한 뒤 basic motion data를 받아주고, 이를 바탕으로 scale을 달리해가며 변화를 확인해보겠습니다.
# 필요한 라이브러리 import
import numpy as np
import matplotlib.pyplot as plt
from tsai.all import get_UCR_data
import torch
import torch.nn.functional as F
# Mexican Hat Wavelet 함수 정의
def mexican_hat_wavelet(t, scale=1.0):
C = 2 / (np.sqrt(3) * np.pi**0.25) # 정규화 상수
wavelet = C * (1 - (t / scale)**2) * np.exp(-(t / scale)**2 / 2)
return wavelet.astype(np.float32) # float32로 변환
# UCR 데이터 불러오기
X_train, y_train, X_test, y_test = get_UCR_data('BasicMotions', split_data=True)
# 시계열 데이터 시각화 함수
def plot_multivariate_timeseries(data, title="Original Multivariate Data", wavelet_transformed=False, scales=[1.0]):
n_channels = data.shape[1]
time_steps = data.shape[2]
fig, axs = plt.subplots(n_channels, 1, figsize=(12, n_channels*2), sharex=True)
t = np.linspace(-5, 5, time_steps) # 시간 축 생성
for i in range(n_channels):
channel_data = data[0, i, :] # 첫 번째 샘플의 i번째 채널 데이터
axs[i].plot(channel_data, label=f'Original Channel {i+1}')
# Mexican Hat Wavelet Transform을 적용한 경우
if wavelet_transformed:
for scale in scales:
wavelet = mexican_hat_wavelet(t, scale=scale)
transformed_data = F.conv1d(torch.tensor(channel_data).view(1, 1, -1).float(),
torch.tensor(wavelet).view(1, 1, -1).float(), padding='same')
axs[i].plot(transformed_data[0, 0].detach().numpy(),
label=f'Transformed (scale={scale})', linestyle='--')
axs[i].set_ylabel(f'Channel {i+1}')
axs[i].legend(bbox_to_anchor=(1.05, 1), loc='upper left') # 범례를 우측에 배치
plt.xlabel('Time Steps')
plt.suptitle(title)
plt.tight_layout() # 그래프 레이아웃 자동 조정
plt.show()
# 첫 번째 샘플에 대해 원본 데이터 시각화
plot_multivariate_timeseries(X_train, title="Original Multivariate Data")
# 첫 번째 샘플에 대해 Mexican Hat Wavelet Transform 후 시각화 (scale=0.5, 1.0, 1.5)
plot_multivariate_timeseries(X_train,
title="Transformed Multivariate Data with Mexican Hat Wavelet (scale=0.5, 1.0, 1.5)",
wavelet_transformed=True, scales=[0.5, 1.0, 1.5])
* 위 그림은 원본 데이터의 각 채널별 시계열에 따른 데이터의 모습을 시각화했습니다.
* 위 그림은 각 채널별 데이터에 대해 0.5 / 1 / 1.5 로 scale을 변경했을때 의 변화를 시각화 한 것입니다.
* 다중 scale의 정보를 활용한다면 큰 scale로부터 오는 전반적인 패턴이 강조된 정보와 작은 scale로부터 오는 국소적인 패턴까지도 강조된 정보가 융합되어 보다 세밀한 특징까지도 잘 잡아낼 수 있을 것 같습니다.
댓글