-
실전 예제 - 시계열 분석 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'형태로 바꿔놓으니 바로 인덱스로 쓸 수 있다. 이런게 경험!
- '.concat()'의 aixs 관련 링크 참조 (https://lsjsj92.tistory.com/456)
두개를 찍어보면 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년이 가장 높고 통상적인 사이클에서 많이 벗어낫다고 볼 수 있다.
'빅데이터 > Data-Analysis' 카테고리의 다른 글
실전 예제 - 시계열 분석 13 (0) 2022.03.03 실전 예제 - 시계열 분석 13 (0) 2022.03.03 실전 예제 - 온-오프라인 비지니스 분석 11 (0) 2022.03.02 실전 예제 - 온-오프라인 비지니스 분석 10 (0) 2022.03.02 실전 예제 - 온-오프라인 비지니스 분석 09 (0) 2022.03.01