Time Series Data(주식 가격 예측 - 1)

안동균·2024년 12월 12일

Time Series

목록 보기
5/11
과거의 주식 데이터로 미래 주식의 가격을 예측할 수 있을까??

여기에는 2가지의 전제 조건이 필요

1. 과거의 데이터에 일정한 패턴이 발견됨
2. 과거의 패턴은 미래에도 동일하게 반복됨

>> 안정적인 데이터에 대해서만 미래 예측이 가능함


안정적인 데이터란?

시계열 데이터의 통계적 특성이 변하지 않아야 함
1. 평균
2. 분산 : 평균에서 떨어져 있는 정도를 가늠하기 위한 지표
3. 공분산 : 각 변수의 평균에서 편차를 곱한 것의 평균(각 변수의 분포가 서로 얼마나 관련 있는지)

구간에 따른 통계치를 봐야하므로 결정적으로 밑의 3가지 통계치가 일정해야함
1. 이동평균 : n개의 데이터를 시점으로 이동하며 계산하는 평균
2. 이동표준편차 : n개의 데이터를 시점으로 이동하며 계산하는 표준 편차(분산의 제곱근)
3. 자기공분산 : 일정 시차를 둔 자기 자신과의 공분산

ex) 4년치 판매량 X(t-3), X(t-2), X(t-1), X(t)를 가지고 X(t+1)이 얼마일지 예측(t는 년도)
예측을 하기 위해서는 t(년도)에 무관해야 함
t가 2010년 일때 2011년을 예측할 수 있다면 2020년일 때도 2021년을 예측할 수 있어야 함

>> 평균과 분산이 일정 범위 안에 있어야 함(이동평균, 이동 표준편차 일정)


X(t - h), X(t)는 t(년도)와 무관하게 h(년도 차이)에 대해서만 달라지는 일정한 상관도를 가져야함

>> 자기 공분산이 일정



시계열 분석

Dataset Load

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os

import warnings
warnings.filterwarnings('ignore')

dataset_filepath = '/content/drive/MyDrive/DataSet/Aiffel/daily-min-temperatures.csv'
df = pd.read_csv(dataset_filepath)

print(type(df))
df.head()

시계열 데이터는 시간을 Index로 하는 Series로 표현됨

Series Type Transform

df = pd.read_csv(dataset_filepath, index_col='Date', parse_dates=True)
print(type(df))
df.head()

ts1 = df['Temp']
print(type(ts1))
ts1.head()


Stationarity 확인

from matplotlib.pylab import rcParams

rcParams['figure.figsize'] = 13, 6
plt.plot(ts1)

코드는 생략되었으나 결측치는 존재하지 않음
만약 존재 하는경우 Drop을 하거나 결측치 양 옆의 값들을 이용하여 보간
보간 : 2와 4 사이의 데이터가 NaN이라면 해당 값을 3으로 채우는 방식
보외법 : 데이터의 범위를 벗어난 영역의 값을 추정하기 위해 사용되는 기법, 패턴과 경향성을 파악하여 결측치 처리

결측치 처리

# 보간기준 time
ts1=ts1.interpolate(method='time')

print(ts1[ts1.isna()])

plt.plot(ts1)


구간 통계치(이동평균, 이동표준편차)

# window는 데이터의 개수를 해당함
def plot_rolling_statistics(timeseries, window=12):

    rolmean = timeseries.rolling(window=window).mean()  # 이동평균 시계열
    rolstd = timeseries.rolling(window=window).std()    # 이동표준편차 시계열

    orig = plt.plot(timeseries, color='blue',label='Original') 
    mean = plt.plot(rolmean, color='red', label='Rolling Mean')
    std = plt.plot(rolstd, color='black', label='Rolling Std')
    
    plt.legend(loc='best')
    plt.title('Rolling Mean & Standard Deviation')
    plt.show(block=False)

데이터 12개 사용(월 기준)

plot_rolling_statistics(ts1, window=12)


데이터 365개 사용(일 기준)

plot_rolling_statistics(ts1, window=365)

시각화로는 그래프의 평균과 표준편차가 일정한 것으로 보여짐

평균이 시간에 따라 증가 >> 비안정적인 데이터

Stationary 검증 (ADF Test)

정상성을 체크하기 위한 단위근 검정 방법

귀무 가설 : 단위근이 존재한다
대립 가설 : 단위근이 존재하지 않아 정상성을 만족한다
from statsmodels.tsa.stattools import adfuller

def augmented_dickey_fuller_test(timeseries):
  
    dftest = adfuller(timeseries, autolag='AIC')  
    
    print('Results of Dickey-Fuller Test:')
    dfoutput = pd.Series(dftest[0:4], index=['Test Statistic','p-value','#Lags Used','Number of Observations Used'])
    for key,value in dftest[4].items():
        dfoutput['Critical Value (%s)' % key] = value
    print(dfoutput)
    
AIC는 모델의 적합도를 평가하는 기준
AIC 값이 낮을수록 더 좋은 모델을 의미
최적의 lag 값을 AIC 기준으로 자동으로 선택

augmented_dickey_fuller_test(ts1)

ts1 시계열 데이터의 경우 p-value가 0에 가깝게 수렴
귀무가설(단위근 존재) 기각 >> 대립 가설(안정적인 시계열 데이터)

augmented_dickey_fuller_test(ts2)

ts2 시계열 데이터의 경우 p-value가 1에 가깝게 수렴
귀무가설 채택 >> 안정적이지 않은 시계열 데이터

0개의 댓글