-
FFT를 활용한 시계열 데이터 노이즈 처리 in Python학습/Python 2023. 10. 27. 04:26
개요
이번에 수행한 데이터 분석 과제에서 Iba 센싱데이터를 전처리하는 모듈을 만들었다.
분석에 사용된 센싱데이터는 수집주기가 0.02초로 매우 짧음에도 현재(t)와 직전(t-1) 데이터의 수치에 약간의 차이가 존재했다.(정상 데이터 범위의 5%이내로 차이 발생)
이는 노후 센서로 인한 측정 오차 등의 여러 외인에 의한 변동으로 파악되었다.
해당 변동은 현장에서 컨트롤 불가능하며, 최종 분석 결과에 좋지 않은 영향을 줄 가능성이 있다고 판단하였다.
따라서 본 과제에서는 변동을 제외처리 하는 방향으로 전처리 작업을 수행하였다.
이전에 수행했던 과제에서는 센싱데이터 노이즈를 제거할 때 이동평균을 사용했지만 이번 분석과제에서는 다음과 같은 단점으로 이동평균을 사용하지 않았다.이동평균 Moving Average 단점
1. 현재시점의 이동평균값을 구하려면 (window size/2) point 이후의 미래 데이터가 필요함(시간 지연).
Streaming 환경에서 부적합함
2. window size가 크면 데이터의 순간적인 변화에 둔감 하고, 작으면 노이즈 처리가 잘 되지 않음.
(적절한 window size를 정하기 어려움귀찮기도 하고..)그리하여 이번 과제에서는 이동평균이 아닌 다른 방법으로 노이즈 처리를 시도하였고,
최종적으로 공학 신호처리에 흔히 사용하는 Fourier Transformation을 도입하였다.
Fourier Transformation Denoise- 임의의 신호를 다양한 주파수(frequency), 강도(amplitude)를 갖는 정현파로 분해.
- Time domain(시간-값) -> Frequency domain(주파수-신호강도)
Fourier Transformation - 주파수가 낮은 저주파는 주기가 길어 시계열 데이터의 trend, seasonality 등의 경향성분으로 해석할 수 있음
- 주파수가 높은 고주파는 주기가 짧아 시계열 데이터의 noise 로 해석할 수 있음
즉, 저주파 대역의 신호만 샘플링하여
이를 역변환 한다면
노이즈가 제거된 데이터를 얻을 수 있다.
FFT를 적용한 노이즈 처리 예제
Fast Fourier Transformation, 고속 푸리에 변환
푸리에변환을 빠르게, 자원효율적으로 수행할 수 있는 알고리즘예제 코드를 통해 노이즈 처리 결과를 확인해보자.
1. 사용 데이터
아래의 예제에 사용된 데이터는 제강 연속 주조 설비가 빌렛을 생산하는 동안
수집하였던 센서 데이터 중 일부이며, 실제 값을 비식별 처리하였다.
데이터 예시 요약
작업시작시간 23년 1월 2일 22시59분 27.64초 작업종료시간 23년 1월 2일 23시00분 19.92초 row 수 2,615 2. FFT 변환 및 역변환
import pandas as pd import numpy as np import matplotlib.pyplot as plt def denoise_fft(data, ifftn): # Fast Fourier Transformation fft_signal = np.fft.fft(data.value) # Reconstruct Original Signal fft_signal[ifftn:len(fft_signal)//2]=0 fft_signal[len(fft_signal)//2:-ifftn]=0 reconstructed_signal = np.fft.ifft(fft_signal) return reconstructed_signal.real
a. numpy의 fft.fft() 메서드를 사용하여 원본 신호를 FFT 변환하고 return 값을 변수(fft_signal)에 저장한다.
fft.fft() return 값은 앞쪽 절반은 양의 주파수 영역, 뒤쪽 절반은 음의 주파수 영역에 해당하며 대칭을 이루고 있다.
(mirrored frequency)mirrored frequency b. n개의 저주파 신호를 남기고, 회색 음영처리된 고주파 부분을 0으로 치환한다.
포함되는 신호와 제외할 신호 c. 고주파 신호가 0으로 치환된 신호를 numpy의 fft.ifft() 메서드를 사용하여 역변환한다(reconstructed_signal).
역변환된 신호(reconstructed_signal)는 실수부와 허수부가 존재하고, 실수만 최종 return한다.3. 결과 비교
우리가 정의한 denoise_fft 함수를 사용하여 원본 신호와 복원된 신호 결과를 비교해보며 노이즈 처리 상태를 확인한다.
value_recon = denoise_fft(data=df, ifftn=50) plt.plot(df.value) plt.plot(value_recon)
Originalifftn=1
ifftn=25ifftn=-1 ifftn 값을 변경해보며 최적값을 탐색할 수 있다. 위의 예시에서는 25개 신호를 선택하였다.
결론
time domain의 원본 데이터를 FFT를 통해 frequency domain으로 변환하고
샘플링한 저주파 신호를 역연산하여 원본 신호의 정보량은 유지하면서 노이즈를 제거해 보았다.
FFT를 활용하여 노이즈 처리하는 방식이 일반적으로 흔히 쓰이는 방식이나 꽤 효과가 좋아 보인다.
예제에서는 25개 정도로 적은 수의 신호를 샘플링 하였음에도
원본 데이터의 정보가 꽤 유지되는 것으로 보인다.
이런저런 생각...
위와 같은 조건에서
만약 원본 신호를 적절하게 추상화 할 수 있는 수준의 FFT 샘플링 수가 25개라고 가정한다면,
그 25개의 변수가 지금 예제에서 사용한 2,615개의 시계열 데이터를 대표할 수 있는것이 아닌지?
(차원 축소의 의미를 가지는 것은 아닐까)
그렇다면 이 25개의 변수를 사용하여 다른 시계열 데이터와 유사도를 구할 수 있는 것은 아닌지?
즉, 센서 데이터의 유형을 군집화 하여 정상 작업 패턴과 이상 작업 패턴을 나누어 볼 수 있는 것은 아닐까?
시간 날 때 아이디어 검토를 해봐도 재밌겠다.
'학습 > Python' 카테고리의 다른 글
판다스가 너무 느리다면? Polars! (0) 2024.05.07 Warning 없이 Pandas Dataframe의 데이터 조작하기 - replace (0) 2023.01.12