본문 바로가기

인공지능/Toy Projects

DeepMC_1 / Wavelet Packet Decomposition (WPD)

목차

    Introduction

    DeepMC(Kumar, Peeyush, et al. "Micro-climate Prediction-Multi Scale Encoder-decoder based Deep Learning Framework." Proceedings of the 27th ACM SIGKDD Conference on Knowledge Discovery & Data Mining. 2021.) 논문의 모델을 구현을 시도했다.

    전처리에 WPD(Wavelet Packet Decomposition)을 이용해 time siries data를 time scale별로 분해하여 multi-scale deeplearning을 하는 프로세스가 있다.

    그림 1의 C부분에 해당하는 내용을 실제 데이터를 이용해서 WPD를 적용해보겠다.

     

    Method & Material

    Python에서 기본으로 제공되는 pywt를 이용해 WPD를 구현했다.

    코드는 매우 간단했지만, 원하는 결과를 얻기가 생각보다 어려웠다.

    우선 해당 논문에서 사용한 family는 Daubechies이므로 wavelet='db1'로 설정했고, 논문에서 level을 5개까지 추출하여 학습에 사용했기 때문에 maxlevel=5로 설정해준다.

    wptree = pywt.WaveletPacket(data=aws_90_th, wavelet='db1', mode='symmetric', maxlevel=5)

     

    Result

    5개의 level로 추출된 WPD결과는 length가 다 다르기 때문에 arange를 통해서 전체 길이를 맞춰주는 작업을 진행했다.

    결과가 이진 트리형태로 나오기 때문에 level이 올라갈수록  WPD결과의 길이가 1/2**n(단, 여기서 n은 레벨)으로 줄어들게 된다.

    전체 코드는 다음과 같게 된다.

    import pywt
    import numpy as np
    import matplotlib.pyplot as plt
    import pandas as pd
    from scipy.interpolate import make_interp_spline
    
    def avg(levels):
        first = True
        for node in levels:
            if first:
                first = False
                sums = node.data
            else :
                sums = sums + node.data
        return sums
        
    aws = pd.read_csv('/path/to/aws/data/aws.csv')
    # random st_num
    aws_90_th = aws.loc[aws['지점번호']==90,'평균 기온'].values
    aws_90_th = aws_90_th[:500]
    
    x = np.arange(len(aws_90_th))
    plt.plot(x, aws_90_th,label='origin')
    
    wptree = pywt.WaveletPacket(data=aws_90_th, wavelet='db1', mode='symmetric', maxlevel=5)
    
    for i in range(1,6):
        levels = wptree.get_level(i, order = "freq") 
        data = avg(levels)
    
        times = np.mean(data)/np.mean(aws_90_th)
    
        data = data/times
    
        cubic_interploation_model=make_interp_spline(np.arange(0,len(aws_90_th),2**(i)),data)
        
        xs=np.linspace(0,len(aws_90_th),len(aws_90_th))
        ys=cubic_interploation_model(xs)
        plt.plot(xs, ys, label='wavelet_%d'%(i))
    
    plt.legend()
    plt.show()

     

    원래 기본 결과만 출력하면 그래프가 뾰족뾰족하게 못생기게 나오게된다.

    이때, scipy의 spline 함수를 이용해서 line을 smooth하게 바꿔주면 다음처럼 이뻐진다.

     

    Conclusion & Discussion

    scipy를 이용해 smooth를 진행한 결과 plot과 진행하지 않은 결과 plot을 비교해보면, smooth를 진행했을 때, 결과가 더 long-term scale의 변화를 확인하기 쉬웠다.

    WPD자체를 처음 들어보는 상황이라 이것저것 찾아보면서 했는데, 생각보다 자료도 official docs 말고는 얻을 곳이 별로 없어서 살짝 삽질을 했지만 생각보다 어려운 내용은 아닌 것 같아 금방 적용할 수 있었던 것 같다.

    다음엔 WPD의 output을 입력이 되는 multi-scale Deep Learning모델을 구현하겠다.