# 정상성 : 추세와 계절성을 갖지 않는 진동하는 데이터
# 주기성 행동을 가지고 있지만, 주기가 특정 패턴을 갖지 않고 시계열을 관측하는 어떠한 시점에서도
# 똑같은 모양일 것이다
# ARIMA 모형을 적용하기 위해서는, 추세와 계절성이 없는 정상성을 지닌 데이터여야 함
# 정상성 검정 - Augmented Dickey-Fuller Test
# 정상성을 알아보기 위한 단위근 검정 방법
# 귀무가설 : 데이터가 정상성을 갖지 않는다(변동이 있다)
# 대립가설 : 데이터가 정상성을 갖는다
# adfuller(x, maxlag, regression, autolag)
import pandas as pd
data = pd.read_csv('../data/arima_data.csv', names = ['day', 'price'])
data.head(3)
data.info()
data['day'] = pd.to_datetime(data['day'], format = '%Y-%m-%d')
data.set_index('day', inplace = True)
data.head(3)
train_len = int(len(data) * 0.8)
training = data[:train_len]
test = data.drop(training.index)
# 귀무가설 : 데이터가 정상성을 갖지 않는다(변동이 있다)
# 대립가설 : 데이터가 정상성을 갖는다
from statsmodels.tsa.stattools import adfuller
adf = adfuller(training, regression = 'ct')
# adf statistic
adf[0]
# p-value
adf[1]
# 단위근 검정에서 p-value가 0.05보다 크므로, 귀무가설을 기각할 수 없음
# 정상성을 갖지 않는 것으로 판단됨
# 차분 후 단위근 검정 재실시
# 차분 : 비정상성을 정상성으로 만들기 위해, 관측값들의 차이를 계산하는 것
# 데이터프레임을 n차 차분하고, acf, pacf를 다시 구함
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
diff_data = training.diff(1)
diff_data = diff_data.dropna()
diff_data.plot()
from statsmodels.tsa.stattools import adfuller
adf = adfuller(diff_data)
# adf statistic
adf[0]
# p-value
adf[1]
# p-value 값이 유의수준보다 작아, 정상성을 갖추고 있다고 판단
# ARIMA(p, d, q)의 파라미터 정하기
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
import numpy as np
import matplotlib.pyplot as plt
plot_pacf(diff_data) # AR(p)의 값 확인
plot_acf(diff_data) # MA(q)의 값 확인
plt.show()
# 0되기 전 값, 여기서는 acf, pacf 모두 2에서 절단점을 가짐
# p, d, q = 2, 1, 2
# SARIMA : 계절성 시계열 데이터에 대한 분석
# 계절성까지 고려한 ARIMA 모델
import pandas as pd
import matplotlib.pyplot as plt
data = pd.read_csv('../data/arima_data.csv', names = ['day', 'price'])
data['day'] = pd.to_datetime(data['day'], format = '%Y-%m-%d')
data.set_index('day', inplace = True)
s_data = data
train_len = int(len(s_data) * 0.7)
training = s_data[:train_len]
test = s_data.drop(training.index)
import matplotlib.pyplot as plt
training.plot()
plt.show()
import statsmodels.api as sm
from statsmodels.tsa.statespace.sarimax import SARIMAX
model = SARIMAX(training.price.values, order = (2,1,2),
seasonal_order = (1,1,1,12), tremd = 'ct', enforce_stationarity = False,
enforce_invertibility = False)
results = model.fit()
results.summary()
# 데이터 확인
# 시간 경과에 따른 표준화 잔차
# 히스토그램과 표준화 된 잔차의 추정된 밀도, 참조를 위해 그려진 Normal(0,1) alfeh
# 일반 기준선이 있는 일반 QQ 플롯
results.plot_diagnostics(figsize = (14, 10))
plt.show()
forecast_values = results.get_forecast(steps = len(test))
forecast_values.summary_frame()
ax = s_data.plot() # 실제값
pred_ci = pd.DataFrame(forecast_values.conf_int())
pred_ci.index = list(test.index)
ax.fill_between(pred_ci.index, pred_ci.iloc[:,0], pred_ci.iloc[:,1], color = 'gray', alpha = 0.5)
predicted = pd.DataFrame(forecast_values.predicted_mean)
predicted.index = list(test.index)
predicted.columns = ['Forecasts']
predicted.plot(ax = ax, label = 'Forecasts')
plt.legend()
plt.show()
from sklearn.metrics import r2_score
r2_score(predicted, test)
'ADP > 실기' 카테고리의 다른 글
회귀분석(LinearRegression, Ridge, Lasso, Elasticnet) (0) | 2024.01.29 |
---|---|
Auto ARIMA (1) | 2024.01.28 |
시계열 분해, ARIMA 모델 (1) | 2024.01.28 |
연관분석 (0) | 2024.01.28 |
자기조직화지도(Self-Organizing Map, SOM) (1) | 2024.01.28 |