ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 실전 예제 - 시계열 분석 12
    빅데이터/Data-Analysis 2022. 3. 3. 11:36

    패스트캠퍼스 '직장인을 위한 파이썬 데이터분석 올인원 패키치 Online' 참조

     

     

     

     

     

    01 시계열 분석이란?

    • 금융분야에는 예전부터 데이터분석이 활발히 진행 되었다. 은행, 보험사, 카드사 등등
    • 은행/카드사는 신용등급 평가 모형에 따른 대출 승인을 진행

    이 공식을 잘 짜느냐에 따라 돈을 벌거나 못벌거나 함

    • 카드사/핀테크사는 소비내역 기반으로 카드 추천, 가맹전 추천등에 활용

    • 보험사는 가입자 생애주기 건강관련 모든것을 예측하려고 함

    • 이렇게 금융사들은 자기들의 이익에 되는 부분에 데이터 분석은 필수. 뿐만 아니라 경기변동, 성장률, 환율, 주식가격등도 예측하고 여기에는 항상 시계열 분석이 주로 쓰임

     

    • 시계열 분석은 과거 데이터를 분석하여 미래를 예측하는 경우를 칭함. 단순 눈으로 과거데이터에서 얻을 수 없는것들을 시계열 분석을 통해 인사이트를 발굴함
    • 예로 증권사에서는 파생상품의 예상 수익이나 가격을 결정하는데 이 모형을 활용. 주로 Revenue와 Risk가 주요 고려 요인임
    • 금융도메인의 특징은 보통 다른 도메인보다 훨씬 민감하게 반응함. 

    금융 도메인은 정확도 보다는 이론과 규율에 맞춰 진행 해야 함

     

     

     

     

     

    02 시계열 데이터 특성

    • 주로 AR(Autoregressive(자기회귀)) 모델을 활용하여 자신의 바로 전 데이터를 활용하여 예측

    일반적으로는 7,8월에 감소했다고 생각할것이다. 하지만..
    시계열은 Trend와 Cycle을 분리하여 이해하여야 하고 이 그래프의 특성은 지속적으로 감소한다고 보는것이 맞다

    • 시계열에서는 반드시 Trend + Cycle(계절 요인 등) + 불규칙 Term을 반드시 고려해야 함

     

     

     

     

     

    03 시계열 데이터 분석 

    • 당뇨병 치료약 월별 세일즈 데이터를 가지고 Trend(추세), Cycle(주기) 을 알아보고 시각화를 해보자!
    • 찾을 인사이트들은 1.월평균 성장율, 2.Seasonal요소 분석, 3.Residual 증감 여부
    # 필요 라이브러리
    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    from statsmodels.tsa.seasonal import seasonal_decompose
    
    
    # parse_dates=['date'] 를 통해 스트링 형태의 Date를 인덱스로 보냄과 동시에 Date형태로 만듬
    df=pd.read_csv('https://raw.githubusercontent.com/selva86/datasets/master/a10.csv', parse_dates=['date'], index_col='date')
    df.head()
    
    df.value.plot();

    • 데이터가 너무 오래 됬다. 최근 데이터들만 묶어서 진행!
    # 최근 데이터 묶기
    df = df[df.index > '1999-12-31']
    df

     

    ▶ 시즌별 분류 ('seasonal_decompose')

    # 시즌별 분류 'seasonal_decopose()' 가 시즌별로 알아서 분류 해줌
    # 시계열 분해는 'additive' = 덧셈 분해, 'multiplicative' = 곱셈 분해로 나뉨
    # two_sided=False 시에는 이동평균계산이 과거값에만 적용
    result = seasonal_decompose(df, model='additive', two_sided=False)
    
    plt.figure(figsize=(40,40))
    result.plot();

    • Trend의 앞의 값이 비어있는 이유는 시즌별 분리시에는 데이터가 최소 12개월이 넘어가야 한다. 즉 안넘어가는것들은 버린다. 이때 'two_sided'를 통해 과거값만 버리냐(False), 현재와 과거에서 각각 6개월(True)을 버리냐를 결정 할 수 있다.
    • 우리는 최근 데이터로 분석을 하기때문에 과거 데이터를 버리는 것.

     

    ▶ 데이터 합치기

    # 하나로 묶어서 분석에 용이하도록 만들기
    # axis=1 -> 열 기준으로 합침
    df_re=pd.concat([result.observed, result.trend, result.seasonal, result.resid], axis=1)
    df_re
    
    df_re.columns=['obs','trend','seasonal','resid']
    df_re.dropna(inplace=True)
    df_re
    
    df_re['year']=df_re.index.year
    df_re

    합치고 전처리 전 vs 후

     

    • 처음에 'date'를 인덱스로 보내고 'Date'형태로 바꿔놓으니 바로 인덱스로 쓸 수 있다. 이런게 경험!

    두개를 찍어보면 axis=1은 열 기준이 맞다

    ▶ 재 시각화

    # 시각화
    plt.figure(figsize=(16,6))
    plt.plot(df_re.obs);

    여기에 나머지 데이터들을 하나씩 추가하면서 차이를 보자

    # 시각화
    plt.figure(figsize=(16,6))
    plt.plot(df_re.obs)
    plt.plot(df_re.trend)
    plt.plot(df_re.seasonal+df_re.trend)
    plt.legend(['observed', 'trend', 'seasonal+trend']);
    # plt.plot(df_re.resid);

    • 그래프를 통해 관측된 값과 추세, 시즌에 따른 추세가 다같이 증가 하고 있는 것을 볼 수 있다
    • 더 중요한것은 관측치가 시즌+추세보다 우의에 있는것들을 중점으로 봐야 한다. 
    • 2006년부터 평범한 주기에서 벗어나는 경향이 있다. 즉 Residual이 크다 즉 예측불가능한 변동성이 많다 라고 볼 수 있다

     

    ▶ Trend 들여다 보기

    * 팁 - 시각화전 값을 찍어보고 NaN이 있으면 .drop()를 해주고 바로 그릴 수 있다

    #.pct_change() -> 값을 퍼센트로 바꿔줌
    df_re.trend.pct_change()

    #.pct_change() -> 값을 퍼센트로 바꿔줌
    df_re.trend.pct_change().dropna().plot(kind='bar', figsize=(16,5));

    Trend의 성장률. 실제로 증가하는지를 보려면 이렇게 각각의 데이터를 찍어봐야한다. 

    * 날짜가 보기 어렵다. 이에대한 팁

    1. 일단 인덱스가 날짜 형식이니 어떻게 넘어오는지 찍어 보자

    df_re.index[0]
    Timestamp('2001-01-01 00:00:00')

    2. 나오는 값을 이제 슬라이싱을 하자

    def get_date(date):
        return (str(date.year)+'-'+str(date.month))
    
    get_date(df_re.index[0])
    '2001-1'

    3. 적용

     

    ▶ Residual 깊게 보기 - unexpected 값. 높을 수록 좋지 않음

    # Residual 들여다 보기
    df_re.groupby('year')['resid'].mean().plot(kind='bar');

    • 2007년이 가장 높고 통상적인 사이클에서 많이 벗어낫다고 볼 수 있다.

     

Designed by Tistory.