ETS¶
- 데이터의 패턴을 더 잘 파악하기 위해서 또는 예측을 수행하기 위해 Smoothing을 한다.
- Smoothing 위해서 Error, Trend, Seasonality 요소들을 활용하는데, 각각을 더하거나 곱하여 Smoothing을 한다.
- 또한 이것들을 가지고 시계열 데이터를 모델링 할 수 있다.
덧셈 분해 (additive decomposition)
- yt = St + Tt + Rt
- y_t = Level + Trend + Seasonality + Noise (Error)
곱셈 분해 (multiplicative decomposition)
- yt = St Tt Rt
- y_t = Level Trend Seasonality * Noise (Error)
- 선제 조건으로는 데이터에 0 값이 존재해서는 안된다.
- 덧셈 분해는 Trend와 Seasonal이 별개이고, 곱셈 분해는 Trend에 따라서 Seasonal이 변화한다.
- 시간이 지남에 따라 변동폭이 일정, Additive가 적절
- Trend가 지남에 따라 변동폭 역시 증가, Multiplicative가 적절
import numpy as np
import pandas as pd
import warnings
warnings.filterwarnings("ignore")
df = pd.read_csv('/content/drive/MyDrive/UDEMY_TSA_FINAL/Data/airline_passengers.csv', index_col='Month', parse_dates=True)
df.dropna(inplace=True)
df.index.freq = 'MS'
df.index
DatetimeIndex(['1949-01-01', '1949-02-01', '1949-03-01', '1949-04-01', '1949-05-01', '1949-06-01', '1949-07-01', '1949-08-01', '1949-09-01', '1949-10-01', ... '1960-03-01', '1960-04-01', '1960-05-01', '1960-06-01', '1960-07-01', '1960-08-01', '1960-09-01', '1960-10-01', '1960-11-01', '1960-12-01'], dtype='datetime64[ns]', name='Month', length=144, freq='MS')
df.plot();
from statsmodels.tsa.seasonal import seasonal_decompose
result = seasonal_decompose(df['Thousands of Passengers'], model='add')
fig = result.plot()
fig.set_size_inches(8,8);
result = seasonal_decompose(df['Thousands of Passengers'], model='multiplicative')
fig = result.plot()
fig.set_size_inches(8,8);
- residual은 원 데이터에서 trend와 seasonality의 값을 제거한 나머지 값이다.
- 모델의 규칙성 내에 포함되지 않은 데이터를 말하는데, 이를 통해 우리는 모델이 데이터의 값을 포착하는데 적절한지 가늠해 볼 수 있다.
- 예를 들면, residual로 addtive 모델이 적절한지, multiplicative 모델이 적절한지 확인 할 수 있다.
- multiplicative decomposition의 결과가 현저히 작은 것을 확인 할 수 있다.
df['6-month-SMA'] = df['Thousands of Passengers'].rolling(window=6).mean()
df['12-month-SMA'] = df['Thousands of Passengers'].rolling(window=12).mean()
df.head()
Thousands of Passengers | 6-month-SMA | 12-month-SMA | |
---|---|---|---|
Month | |||
1949-01-01 | 112 | NaN | NaN |
1949-02-01 | 118 | NaN | NaN |
1949-03-01 | 132 | NaN | NaN |
1949-04-01 | 129 | NaN | NaN |
1949-05-01 | 121 | NaN | NaN |
df.plot();
df['EWMA12'] = df['Thousands of Passengers'].ewm(span=12).mean()
df[['Thousands of Passengers', '12-month-SMA', 'EWMA12']].plot(figsize=(12, 8));
Holt-Winters Method¶
Simple Exponential Smoothing / Simple Moving Average¶
A variation of the statmodels Holt-Winters function provides Simple Exponential Smoothing. We'll show that it performs the same calculation of the weighted moving average as the pandas .ewm() method.
Double Exponential Smoothing / Holt's Method¶
시계열 데이터가 기울어진 직선 모양의 추세를 보인다면 덧셈 모형을 사용해야 한다.
반면 시계열 데이터가 지수적으로 증가하거나 곡선형 추세를 보인다면 곱셈 모형을 사용해야 한다.
Triple Exponential Smoothing / Holt-Winters Method¶
This model has (so far) the "best" looking forecast plot, as it takes seasonality into account.
When we expect regular fluctuations in the future, this model attempts to map the seasonal behavior.
from statsmodels.tsa.holtwinters import SimpleExpSmoothing
span = 12
alpha = 2/(span+1)
df['EWMA12'] = df['Thousands of Passengers'].ewm(alpha=alpha, adjust=False).mean()
df.head()
Thousands of Passengers | 6-month-SMA | 12-month-SMA | EWMA12 | |
---|---|---|---|---|
Month | ||||
1949-01-01 | 112 | NaN | NaN | 112.000000 |
1949-02-01 | 118 | NaN | NaN | 112.923077 |
1949-03-01 | 132 | NaN | NaN | 115.857988 |
1949-04-01 | 129 | NaN | NaN | 117.879836 |
1949-05-01 | 121 | NaN | NaN | 118.359861 |
model = SimpleExpSmoothing(df['Thousands of Passengers'])
fitted_model = model.fit(smoothing_level=alpha, optimized=False)
df['SES12'] = fitted_model.fittedvalues.shift(-1)
from statsmodels.tsa.holtwinters import ExponentialSmoothing
df['DESadd12'] = ExponentialSmoothing(df['Thousands of Passengers'], trend='add').fit().fittedvalues.shift(-1)
df[['Thousands of Passengers', 'EWMA12', 'DESadd12']].iloc[:24].plot(figsize=(12,6));
df['DESmul12'] = ExponentialSmoothing(df['Thousands of Passengers'], trend='mul').fit().fittedvalues.shift(-1)
df[['Thousands of Passengers', 'DESadd12', 'DESmul12']].iloc[:24].plot(figsize=(12,6));
df['TESadd12'] = ExponentialSmoothing(df['Thousands of Passengers'], trend='add', seasonal='add', seasonal_periods=12).fit().fittedvalues
df.head()
Thousands of Passengers | 6-month-SMA | 12-month-SMA | EWMA12 | SES12 | DESadd12 | DESmul12 | TESadd12 | |
---|---|---|---|---|---|---|---|---|
Month | ||||||||
1949-01-01 | 112 | NaN | NaN | 112.000000 | 112.000000 | 113.474828 | 114.978251 | 112.001172 |
1949-02-01 | 118 | NaN | NaN | 112.923077 | 112.923077 | 119.464366 | 121.191659 | 120.168193 |
1949-03-01 | 132 | NaN | NaN | 115.857988 | 115.857988 | 133.477561 | 135.802180 | 134.698694 |
1949-04-01 | 129 | NaN | NaN | 117.879836 | 117.879836 | 130.543312 | 132.657709 | 131.376310 |
1949-05-01 | 121 | NaN | NaN | 118.359861 | 118.359861 | 122.528126 | 124.213566 | 124.628035 |
df['TESmul12'] = ExponentialSmoothing(df['Thousands of Passengers'], trend='mul', seasonal='mul', seasonal_periods=12).fit().fittedvalues
df.head()
Thousands of Passengers | 6-month-SMA | 12-month-SMA | EWMA12 | SES12 | DESadd12 | DESmul12 | TESadd12 | TESmul12 | |
---|---|---|---|---|---|---|---|---|---|
Month | |||||||||
1949-01-01 | 112 | NaN | NaN | 112.000000 | 112.000000 | 113.474828 | 114.978251 | 112.001172 | 111.597879 |
1949-02-01 | 118 | NaN | NaN | 112.923077 | 112.923077 | 119.464366 | 121.191659 | 120.168193 | 118.844235 |
1949-03-01 | 132 | NaN | NaN | 115.857988 | 115.857988 | 133.477561 | 135.802180 | 134.698694 | 133.334951 |
1949-04-01 | 129 | NaN | NaN | 117.879836 | 117.879836 | 130.543312 | 132.657709 | 131.376310 | 127.901291 |
1949-05-01 | 121 | NaN | NaN | 118.359861 | 118.359861 | 122.528126 | 124.213566 | 124.628035 | 120.978657 |
df[['Thousands of Passengers', 'TESadd12', 'TESmul12']].plot(figsize=(12,6));
Forecasting¶
train_data = df.iloc[:108]
test_data = df.iloc[108:]
test_data.shape
(36, 9)
fitted_model = ExponentialSmoothing(train_data['Thousands of Passengers'], trend='mul', seasonal='mul', seasonal_periods=12).fit()
test_predictions = fitted_model.forecast(36).rename('HW Forecast')
train_data['Thousands of Passengers'].plot(legend=True, label='TRAIN')
test_data['Thousands of Passengers'].plot(legend=True, label='TEST', figsize=(12,8))
test_predictions.plot(legend=True, label='PREDICTION');
train_data['Thousands of Passengers'].plot(legend=True, label='TRAIN')
test_data['Thousands of Passengers'].plot(legend=True, label='TEST', figsize=(12,8))
test_predictions.plot(legend=True, label='PREDICTION', xlim=['1958-01-01', '1961-01-01']);
from sklearn.metrics import mean_squared_error, mean_absolute_error
np.sqrt(mean_squared_error(test_data['Thousands of Passengers'], test_predictions))
59.379221423818684
test_data['Thousands of Passengers'].mean()
428.5
final_model = ExponentialSmoothing(df['Thousands of Passengers'], trend='mul', seasonal='mul', seasonal_periods=12).fit()
forecast_predictions = final_model.forecast(36).rename('FORECAST')
df['Thousands of Passengers'].plot(figsize=(12,8), legend=True)
forecast_predictions.plot(legend=True);
Stationarity¶
Stationary 데이터 특성
- 연속되는 숫자들의 평균(mean)이 time invariant (시간에 따라 변하지 않음)
- 연속되는 숫자들의 분산(variance)이 time invariant
- 연속되는 숫자들의 공분산(covariance)이 time invariant
Stationary Test
- ARIMA 모델은 시계열 데이터가 stationary 특성을 보일 때 효과적이므로
- 데이터가 stationary 특성을 보이는지 확인 할 수 있어야 한다.
Differencing
- 시계열 데이터가 Non-Stationary 하다면 초기 differencing 작업을 ('Integrated') 한 번 이상 적용해서 데이터를 stationary 하게 만드는 단계가 필요하다.
df2 = pd.read_csv('/content/drive/MyDrive/UDEMY_TSA_FINAL/Data/samples.csv', index_col=0, parse_dates=True)
df2.head()
a | b | c | d | |
---|---|---|---|---|
1950-01-01 | 36 | 27 | 0 | 67 |
1950-02-01 | 58 | 22 | 3 | 31 |
1950-03-01 | 61 | 17 | 5 | 67 |
1950-04-01 | 37 | 15 | 8 | 47 |
1950-05-01 | 66 | 13 | 8 | 62 |
df2['a'].plot(ylim=[0, 100], title='STATIONARY DATA');
df2['b'].plot(ylim=[0, 100], title='NON-STATIONARY DATA');
df2['c'].plot(ylim=[0, 10000], title='MORE NON-STATIONARY DATA');
Diffrencing¶
- Non-stationary 데이터는 differencing을 통해 stationary하게 변환해준다.
- differencing 한 데이터에 대해 stationary 할 때까지 differencing을 반복한다.
- seasonal 데이터일 경우 season을 기준으로 differencing 한다.
- 예를 들어 1년 주기의 seasonality를 갖는 월간 데이터에 대해 differencing 할 때,
- differencing의 시간 단위는 1이 아니라 12로 하게 된다.
- seasonal ARIMA 모델의 경우 1차 differencing 후 seasonal differencing 하는 것도 흔히 사용하는 방법이다.
df2['d1b'] = df2['b'] - df2['b'].shift(1)
df2[['b', 'd1b']].head()
b | d1b | |
---|---|---|
1950-01-01 | 27 | NaN |
1950-02-01 | 22 | -5.0 |
1950-03-01 | 17 | -5.0 |
1950-04-01 | 15 | -2.0 |
1950-05-01 | 13 | -2.0 |
from statsmodels.tsa.statespace.tools import diff
diff(df2['b'], k_diff=1)
1950-02-01 -5.0 1950-03-01 -5.0 1950-04-01 -2.0 1950-05-01 -2.0 1950-06-01 3.0 ... 1959-08-01 3.0 1959-09-01 4.0 1959-10-01 -7.0 1959-11-01 17.0 1959-12-01 -14.0 Name: b, Length: 119, dtype: float64
diff(df2['b'], k_diff=1).plot(title='FISRT ORDER DIFFERENCE');
df2['d2c'] = df2['c'].diff().diff()
df2['d2c'].plot(title='SECOND ORDER DIFFERENCE');
ACF and PACF¶
AR(p), MA(q): AutoCorrelation 플롯과 Partial AutoCorrelation Plot을 참고해서 p와 q를 결정한다.
Autocorrelation Function¶
- 현재 시계열과 특정 x차만큼 지연된 시점(lagged by x time units) 간의 데이터와의 상관관계를 보여준다.
- Gradual Decline : 비정상 데이터
- Sharp Drop-off : 정상 데이터
Partial Autocorrelation Function¶
- 전날의 잔차(residuals)와 현재의 실제 값 사이의 상관관계를 보여준다.
- 부분 자기 상관 플롯은 정상 데이터에서 가장 잘 작동한다.
# NON STATIONARY
df1 = pd.read_csv('/content/drive/MyDrive/UDEMY_TSA_FINAL/Data/airline_passengers.csv', index_col='Month', parse_dates=True)
df1.index.freq = 'MS'
# STATIONARY
df2 = pd.read_csv('/content/drive/MyDrive/UDEMY_TSA_FINAL/Data/DailyTotalFemaleBirths.csv', index_col='Date', parse_dates=True)
df2.index.freq = 'D'
from pandas.plotting import lag_plot
lag_plot(df1['Thousands of Passengers']);
lag_plot(df2['Births']);
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
# NON STATIONARY
plot_acf(df1, lags=40);
극대값은 12, 24, 36차 시점에 발생한다.
신뢰 구간을 벗어난 상관 계수는 상관관계일 가능성이 높다. = 시차가 작을수록 상관관계가 더 명확하다.
# STATIONARY
plot_acf(df2, lags=40);
# NON STATIONARY
plot_pacf(df2, lags=40);
AutoRegression Model¶
- t 시점의 데이터와 이전 시점 (t-p: lagged p)의 데이터 사이의 관계에 대한 회귀 모델 (regression model)
- 한 단계 이전 시점의 정보로 미래 시점의 정보를 예측할 수 있다.
Autocorrelation이라고도 한다 (=selfcorrelation, 자기상관성)
자기 회귀 모델은 매우 간단해서 아주 단순한 데이터셋에만 적용할 수 있다. = 명확한 선형 증가 또는 감소 추세를 보이는 데이터셋
from statsmodels.tsa.ar_model import AR, ARResults
df = pd.read_csv('/content/drive/MyDrive/UDEMY_TSA_FINAL/Data/uspopulation.csv', index_col='DATE', parse_dates=True)
df.index.freq = 'MS'
df.head()
PopEst | |
---|---|
DATE | |
2011-01-01 | 311037 |
2011-02-01 | 311189 |
2011-03-01 | 311351 |
2011-04-01 | 311522 |
2011-05-01 | 311699 |
df['PopEst'].plot(figsize=(12,5));
len(df)
96
train = df.iloc[:84]
test = df.iloc[84:]
len(train), len(test)
(84, 12)
model = AR(train['PopEst'])
AR1fit = model.fit(maxlag=1)
AR1fit.aic # 정보량 규준
6.410771237032229
AR1fit.k_ar # k차
1
AR1fit.params
const 284.913797 L1.PopEst 0.999686 dtype: float64
AR(1) 모델의 경우 상수는 284가 되고, 시차1에 대한 파이 값은 약 1이 된다.
start = len(train)
end = len(train) + len(test) - 1
predictions1 = AR1fit.predict(start=start, end=end, dynamic=False).rename('AR (1) Predictions')
test.plot(figsize=(12,8), legend=True)
predictions1.plot(legend=True);
model = AR(train['PopEst'])
AR2fit = model.fit(maxlag=2)
AR2fit.params
const 137.368305 L1.PopEst 1.853490 L2.PopEst -0.853836 dtype: float64
AR(2) 모델로, 2단계 이전 시점의 정보를 고려하여 다음 시점을 예측 할 수 있다.
predictions2 = AR2fit.predict(start, end).rename('AR (2) Predictions')
test.plot(figsize=(12,8), legend=True)
predictions1.plot(legend=True)
predictions2.plot(legend=True);
AR(2) 모델이 AR(1)보다 테스트 값에 훨씬 근접하다.
어떻게 최적 차수 p 값을 알 수 있을까?
model = AR(train['PopEst'])
ARfit = model.fit(ic='t-stat') # 정보량 규준
ARfit.params
const 82.309677 L1.PopEst 2.437997 L2.PopEst -2.302100 L3.PopEst 1.565427 L4.PopEst -1.431211 L5.PopEst 1.125022 L6.PopEst -0.919494 L7.PopEst 0.963694 L8.PopEst -0.439511 dtype: float64
predictions8 = ARfit.predict(start, end).rename('AR (8) Predictions')
오차 평가 방법을 기반으로 기반으로 statsmodel은 8차수까지 가야한다고 정한다.
from sklearn.metrics import mean_squared_error
labels = ['AR1', 'AR2', 'AR8']
preds = [predictions1, predictions2, predictions8]
for i in range(3):
# np.sqrt()
error = mean_squared_error(test['PopEst'], preds[i])
print(f'{labels[i]} MSE was : {error}')
AR1 MSE was : 17449.71423587912 AR2 MSE was : 2713.2585540102214 AR8 MSE was : 186.97053754548145
test.plot(figsize=(12,8), legend=True)
predictions1.plot(legend=True)
predictions2.plot(legend=True)
predictions8.plot(legend=True);
model = AR(df['PopEst'])
ARfit = model.fit(ic='t-stat')
ARfit.params
const 84.885175 L1.PopEst 2.296674 L2.PopEst -2.109518 L3.PopEst 1.429221 L4.PopEst -1.259837 L5.PopEst 1.093852 L6.PopEst -0.985774 L7.PopEst 1.066295 L8.PopEst -0.858709 L9.PopEst 0.826672 L10.PopEst -1.074975 L11.PopEst 1.034535 L12.PopEst -0.458679 dtype: float64
forcasted_values = ARfit.predict(start=len(df), end=len(df)+11).rename('Forecast')
테스트 기간이 12개월이었으므로, 향후 12개월을 예측한다.
테스트세트 길이와 예측하려는 기간이 일치해야 모델을 정확히 평가 할 수 있다.
df['PopEst'].plot(figsize=(12,8), legend=True)
forcasted_values.plot(legend=True);
Descriptive Statistics and Tests¶
Augmented Dickey-Fullter Test¶
- 통계적 시험을 통해 시계열 데이터가 stationary 특성을 보이는지 확인 할 수 있다.
- P 밸류가 0.05 이하면 stationary하다
df1 = pd.read_csv('/content/drive/MyDrive/UDEMY_TSA_FINAL/Data/airline_passengers.csv', index_col='Month', parse_dates=True)
df1.index.freq = 'MS'
df2 = pd.read_csv('/content/drive/MyDrive/UDEMY_TSA_FINAL/Data/DailyTotalFemaleBirths.csv', index_col='Date', parse_dates=True)
df2.index.freq = "D"
df1.plot();
from statsmodels.tsa.stattools import adfuller
adfuller(df1['Thousands of Passengers'])
(0.8153688792060472, 0.991880243437641, 13, 130, {'1%': -3.4816817173418295, '5%': -2.8840418343195267, '10%': -2.578770059171598}, 996.6929308390189)
dftest = adfuller(df1['Thousands of Passengers'])
dfout = pd.Series(dftest[:4], index=['ADF Test Statistic', 'p-value', '# Lags Used', '# Observations'])
for key, val in dftest[4].items():
dfout[f'critical value ({key})'] = val
dfout
ADF Test Statistic 0.815369 p-value 0.991880 # Lags Used 13.000000 # Observations 130.000000 critical value (1%) -3.481682 critical value (5%) -2.884042 critical value (10%) -2.578770 dtype: float64
def adf_test(series, title=''):
print(f'Augmented Dickey-Fuller Test: {title}')
result = adfuller(series.dropna(), autolag='AIC')
labels = ['ADF Test Statistic', 'p-value', '# Lags Used', '# Observations']
out = pd.Series(result[:4], index = labels)
for key, val in result[4].items():
out[f'critical value ({key})'] = val
print(out.to_string()) # .to_string() removes the line "dtype: float64"
if result[1] <= 0.05:
print('\nSTATIONARY')
else:
print('\nNON STATIONARY')
adf_test(df1['Thousands of Passengers'])
Augmented Dickey-Fuller Test: ADF Test Statistic 0.815369 p-value 0.991880 # Lags Used 13.000000 # Observations 130.000000 critical value (1%) -3.481682 critical value (5%) -2.884042 critical value (10%) -2.578770 NON STATIONARY
df2.plot()
<matplotlib.axes._subplots.AxesSubplot at 0x7f8085a79310>
adf_test(df2['Births'])
Augmented Dickey-Fuller Test: ADF Test Statistic -4.808291 p-value 0.000052 # Lags Used 6.000000 # Observations 358.000000 critical value (1%) -3.448749 critical value (5%) -2.869647 critical value (10%) -2.571089 STATIONARY
Granger Causality Tests¶
df3 = pd.read_csv('/content/drive/MyDrive/UDEMY_TSA_FINAL/Data/samples.csv', index_col=0, parse_dates=True)
df3.index.freq = 'MS'
df3[['a', 'd']].plot(figsize=(12, 8))
<matplotlib.axes._subplots.AxesSubplot at 0x7f80852c4610>
df3['a'].iloc[2:].plot(figsize=(12, 8), legend=True)
df3['d'].shift(2).plot(legend=True);
d가 a의 원인이라는 증거가 된다. = 두 시계열 사이의 인과관계가 있다.
그랜저 인과관계 검정을 실행하면 두 개의 시계열 사이에 인과관계가 있는지 없는지 확인 할 수 있다.
from statsmodels.tsa.stattools import grangercausalitytests
grangercausalitytests(df3[['a', 'd']], maxlag=3);
Granger Causality number of lags (no zero) 1 ssr based F test: F=1.7051 , p=0.1942 , df_denom=116, df_num=1 ssr based chi2 test: chi2=1.7492 , p=0.1860 , df=1 likelihood ratio test: chi2=1.7365 , p=0.1876 , df=1 parameter F test: F=1.7051 , p=0.1942 , df_denom=116, df_num=1 Granger Causality number of lags (no zero) 2 ssr based F test: F=286.0339, p=0.0000 , df_denom=113, df_num=2 ssr based chi2 test: chi2=597.3806, p=0.0000 , df=2 likelihood ratio test: chi2=212.6514, p=0.0000 , df=2 parameter F test: F=286.0339, p=0.0000 , df_denom=113, df_num=2 Granger Causality number of lags (no zero) 3 ssr based F test: F=188.7446, p=0.0000 , df_denom=110, df_num=3 ssr based chi2 test: chi2=602.2669, p=0.0000 , df=3 likelihood ratio test: chi2=212.4789, p=0.0000 , df=3 parameter F test: F=188.7446, p=0.0000 , df_denom=110, df_num=3
시차의 범위가 클수록 인과관계를 발견할 가능성은 높지만, 인과관계 검정을 계산하는데 쓰는 시간은 더 많게 된다.
시차가 2일 때, 아주 낮은 p값이 나온다. = 인과관계가 있다.
grangercausalitytests(df3[['b', 'd']], maxlag=3);
Granger Causality number of lags (no zero) 1 ssr based F test: F=1.5225 , p=0.2197 , df_denom=116, df_num=1 ssr based chi2 test: chi2=1.5619 , p=0.2114 , df=1 likelihood ratio test: chi2=1.5517 , p=0.2129 , df=1 parameter F test: F=1.5225 , p=0.2197 , df_denom=116, df_num=1 Granger Causality number of lags (no zero) 2 ssr based F test: F=0.4350 , p=0.6483 , df_denom=113, df_num=2 ssr based chi2 test: chi2=0.9086 , p=0.6349 , df=2 likelihood ratio test: chi2=0.9051 , p=0.6360 , df=2 parameter F test: F=0.4350 , p=0.6483 , df_denom=113, df_num=2 Granger Causality number of lags (no zero) 3 ssr based F test: F=0.5333 , p=0.6604 , df_denom=110, df_num=3 ssr based chi2 test: chi2=1.7018 , p=0.6365 , df=3 likelihood ratio test: chi2=1.6895 , p=0.6393 , df=3 parameter F test: F=0.5333 , p=0.6604 , df_denom=110, df_num=3
P값이 0.05보다 작지 않다. = 인과관계가 없다.
Evaluating forecast accuracy¶
np.random.seed(42)
df = pd.DataFrame(np.random.randint(20,30, (50,2)), columns=['test', 'predictions'])
df.head()
test | predictions | |
---|---|---|
0 | 26 | 23 |
1 | 27 | 24 |
2 | 26 | 29 |
3 | 22 | 26 |
4 | 27 | 24 |
from statsmodels.tools.eval_measures import mse, rmse, meanabs
rmse(df['test'], df['predictions'])
4.125530268947253
df['test'].mean()
25.14
df = pd.read_csv('/content/drive/MyDrive/UDEMY_TSA_FINAL/Data/airline_passengers.csv', index_col='Month', parse_dates=True)
df.index.freq = 'MS'
Exposing Seasonality with Month and Quarter Plots¶
from statsmodels.graphics.tsaplots import month_plot, quarter_plot
month_plot(df['Thousands of Passengers']);
dfq = df['Thousands of Passengers'].resample(rule='Q').mean()
quarter_plot(dfq);
'time_series' 카테고리의 다른 글
ARIMA and SARIMA (0) | 2023.01.10 |
---|