시계열·스펙트럼 데이터를 re-sampling하여 차원 삭감【Python: SciPy】

2019/3/26

파이썬에서 DataFrame의 시계열과 스펙트럼 데이터를 씨닝하고 싶을 때의 방법입니다.

"pandas.DataFrame.resample"이라면 인수로 D(일차), W(주간) 등의 시간 설정을 해야 합니다.날짜와 시간의 열이 없는 시계열 데이터와 스펙트럼 데이터의 씨닝을 원할 때는 다음 방법을 사용할 수 있습니다.

시계열 및 스펙트럼 데이터란?

시계열 및 스펙트럼 데이터는 특정 축을 따라 일정한 간격으로 관찰됩니다.데이터 계열이 적용된다.예로서, 주가의 추이나 흡광 스펙트럼 등.

시계열 데이터의 예 스펙트럼 데이터의 예
・기온이나 강수 상황의 천이
・교통 상태의 변화
· 매일 판매
· 주가 추이
· 비트 코인 가격 추이
· 음성 데이터
· 화합물의 흡수 스펙트럼(IR, UV)
・천체로부터의 스펙트럼

각각의 분류는 다르지만 데이터로서 유사한 다음과 같은 특징을 갖는다.

  1. 어느 측정점과 인접한 점은 가까운 값을 취한다.
  2. 장기(광범위)로 보면, 노이즈가 포함된다

参照: https://kotobank.jp/word/%E6%99%82%E7%B3%BB%E5%88%97%E3%83%87%E3%83%BC%E3%82%BF-1329677 https://datachemeng.com/preprocessspectratimeseriesdata/

시계열 및 스펙트럼 데이터 재샘플링

시계열 및 스펙트럼 데이터를 기반으로 예측 모델을 작성할 때 모든 측정 포인트의 데이터를 사용하면 엄청난 수의 특징 량이됩니다.이것은 과 학습으로 이어지므로, 범화 성능의 향상에는 다운 샘플링에 의한 차원 삭감이 유효.

사용하는 것: SciPy(scipy.signal)

수학 · 과학 · 공학용 오픈 소스 소프트웨어웨어 생태계 (고급 과학 컴퓨팅 라이브러리의 막대한 것).

NumPy 보다 고도의 수치 연산 처리가 가능해 물리 정수, 소행렬, 확률 분포로부터 수치 적분, 신호 처리, 최적화, 통계 등을 간단하게 실행할 수 있게 된다.

scipy.signal은 scipy의 파형 처리에 관한 모듈입니다.

  • scipy.signal.decimate

import numpy as np from scipy import signal # 기본 40개의 파형 데이터 생성 x = np.linspace(0, 10, 40, endpoint=False) y = np.cos(-x**2/6) # 데이터를 기반으로 20점으로 다운샘플링 x_down = np.linspace(0, 10, 20, endpoint=False) y_down = signal.decimate(y, 2) # 2분의 1로 다운샘플링 # 결과를 그래프로 플롯 %matplotlib inline plt.plot(x, y, '.-', label='data') plt.plot(x_down, y_down, 'rs-', label='down-sampled', alpha=0.5) plt.legend () plt.show()
scipy.signal.decimate로 다운 샘플링
scipy.signal.decimate로 다운 샘플링

scipy.signal.decimate는 안티앨리어싱(anti-aliasing) 처리를 하여 다운샘플링한다(안티앨리어싱 처리란 연속 데이터로부터 일정 간격으로 샘플링할 때 발생하면 왜곡을 없애기 위한 처리를 말한다).그대로 데이터 포인트를 줄인 것에 가까운 형태로 리샘플링된다.

참조 :https://docs.scipy.org/doc/scipy-1.2.1/reference/generated/scipy.signal.decimate.html

  • scipy.signal.resample

# 기본 40 점의 파형 데이터 생성 x = np.linspace(0, 10, 40, endpoint=False) y = np.cos(-x**2/6) # 데이터를 기준으로 2.5배 100점에 업샘플링 x_up = np.linspace(0, 10, 100, endpoint=False) y_up = signal.resample(y, 100) # 데이터를 기준으로 절반 20점으로 다운샘플링 x_down = np.linspace( 0, 10, 20, endpoint=False) y_down = signal.resample(y, 20) # 결과를 그래프에 플롯 import matplotlib.pyplot as plt %matplotlib inline plt.plot(x, y, '.-', label= 'data') plt.plot(x_up, y_up, 'go-', label='up-sampled', alpha=0.3) plt.legend() plt.show() plt.plot(x, y, '.- ', label='data') plt.plot(x_down, y_down, 'rs-', label='down-sampled', alpha=0.5) plt.legend() plt.show()
scipy.signal.resample에서 처리한 파형 데이터
scipy.signal.resample에서 처리한 파형 데이터

scipy.signal.resample은 푸리에 변환을 이용한 리샘플링이기 때문에 신호가 주기적이라는 가정에 기초한다.위의 데이터로 말하는 말단 부분 등 주기성을 만족하지 않는 경우는 크게 값이 빠져 버린다.

덧붙여서 scipy.signal.resample는 up-sampling도 가능.
파란색 선이 원래 데이터 포인트, 녹색이 업 샘플링 후, 빨간색이 다운 샘플링 후 플롯.

 

kaggle의 음성 분석 대회에도 사용예가 있으므로 참고가 됩니다.

참조 :https://docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.signal.resample.html

DataFrame에 적용

행은 각 측정점, 열은 각 샘플의 데이터 프레임에서 수행.

import pandas as pd # 데이터 프레임에 저장할 데이터 생성 y1 = np.cos(-x**2/6)*1/2 y2 = np.cos(x)*1/3 df1 = pd.DataFrame({ 'y':y, 'y1':y1, 'y2':y2}) # 다운샘플링 df1_down = signal.decimate(df1, 2, axis=0) df1_down = pd.DataFrame(df1_down, columns=['y_down') ,'y1_down','y2_down'], index=np.linspace(0, 10, 20, endpoint=False)) # 다운샘플링된 데이터 표시&플롯 print(df1.head(10)) print(df1_down.head (10)) df1.plot(kind='line', marker='.') df1_down.plot(kind='line', marker='.')
df1.head(10) df1_down.head(10)
 df1.head(10) df1_down.head(10)
다운 샘플링 전후의 데이터 포인트
다운 샘플링 전 다운 샘플링 후

원래의 40점에서 1/2의 20점으로 다운샘플링해도, 파형을 정밀도 좋게 유지하고 있어 특징량으로 하는데도 정보의 손실은 적다고 합니다.

행이 각 샘플, 열이 각 측정점의 데이터 프레임 예
행이 각 샘플이고 열이 각 측정점인 경우

또한, 위와 같은 행이 각 샘플, 열이 각 측정점의 데이터 프레임(소위 정연 데이터)인 경우는 인수axis=1그렇다면 OK.