차분을 하는 이유는 non-stationary한 데이터를 차분을 통해 stationary하게 만들어주는 것이다.
데이터를 안정화하는 작업은 제곱, 로그화, 루트, 차분이 있는데 이번에는 차분을 해볼 것이다.
정상성에 대해서는 다음 포스트를 참고하면 된다.
2022.01.19 - [공부/모델링] - Stationary test (정상성 검정) python
Stationary test (정상성 검정) python
시계열 데이터를 다루게 된다면, 정상성 검정이라는 것을 시행해야 한다. 시계열 데이터를 통해 회귀를 하게 된다면, 이는 과거 데이터를 가지고 미래를 예측하는 것과 같다. 따라서 통계적 속
signature95.tistory.com
이번에는 정상성 검정 포스트에서 다룬 데이터를 기반으로 차분을 진행해 볼 것이다.
차분은 t 시점의 데이터가 t-1 시점 데이터에 비해 얼마나 증감했는지 알 수 있게 된다.
식은 다음과 같다.
식을 보면 알 수 있듯, k개의 시점이 있는 데이터에서 1차 차분을 진행하게 되면, 총 n 개의 데이터가 소실되는 단점이 존재한다.
1차 차분에 대한 식은 다음과 같다.
이를 파이썬으로 확인해보자
데이터는 앞 포스트와 동일한 divvy_data를 활용하였다.
rides = data["rides"].to_frame(name="rides") # 데이터의 행을 역순으로 뒤집는 부분
rides = rides.loc[::-1]
rides["lag_1"] = rides["rides"].shift(periods=1)
print(rides)
>>>
rides lag_1
date
12/31/2017 593 NaN
12/30/2017 519 593.0
12/29/2017 1049 519.0
12/28/2017 1267 1049.0
12/27/2017 1117 1267.0
... ... ...
1/5/2014 32 1.0
1/4/2014 181 32.0
1/3/2014 6 181.0
1/2/2014 111 6.0
1/1/2014 95 111.0
shift함수를 통해 t기의 데이터를 t-1기로 밀어낸 부분이다. 따라서 index의 값은 lag_1에서 하나씩 밀린 것을 확인할 수 있다.
그렇다면 이번엔 차분을 해보자.
차분은 직접 빼는 부분 (diff_1 = rides column - lag_1 column) & diff 함수를 이용한 부분으로 데이터를 구해보았다.
rides['직접 구한 diff_1'] = rides['rides'] - rides['lag_1']
rides['함수로 구한 diff_1'] = rides['rides'].diff(1)
print(rides)
>>>
rides lag_1 직접 구한 diff_1 함수로 구한 diff_1
date
12/31/2017 593 NaN NaN NaN
12/30/2017 519 593.0 -74.0 -74.0
12/29/2017 1049 519.0 530.0 530.0
12/28/2017 1267 1049.0 218.0 218.0
12/27/2017 1117 1267.0 -150.0 -150.0
... ... ... ... ...
1/5/2014 32 1.0 31.0 31.0
1/4/2014 181 32.0 149.0 149.0
1/3/2014 6 181.0 -175.0 -175.0
1/2/2014 111 6.0 105.0 105.0
1/1/2014 95 111.0 -16.0 -16.0
즉, 1차 차분을 하는 방식은 lag_1로 데이터를 하나씩 미룬다음 그것을 직접 뺴주는 방법이라고 보면 된다.
2차 차분의 경우, 거의 사용할 일은 없다. 하지만 식을 보면 다음과 같이 쓸 수 있다.
따라서 이를 파이썬으로 구현하면 다음과 같다. (기존에는 lag_2로 단순히 시기를 2단계 미뤄서 진행했었는데, 이 부분이 잘못되었다고 지적해주시는 분 덕분에 올바르게 수정할 수 있게되었음)
# 앞서 1차 차분에서 진행했던 값의 컬럼을 변경해주고 drop한다
rides["diff_1"] = rides["함수로 구한 diff_1"]
rides = rides.drop(columns=['함수로 구한 diff_1', '직접 구한 diff_1'])
# 2차 차분을 시행하기 위해 1차 차분 값을 lag=1 적용하여 미뤄준다
rides['diff_1 + lag_1'] = rides['diff_1'].shift(1)
# 2차 차분값 도출
rides['diff_1 + lag_1'] = rides['diff_1'].shift(1)
rides['직접 구한 diff_2'] = rides['diff_1'] - rides['diff_1 + lag_1']
rides['함수로 구한 diff_2'] = rides['rides'].diff().diff()
print(rides)
>>>
rides lag_1 diff_1 diff_1 + lag_1 직접 구한 diff_2 함수로 구한 diff_2
date
12/31/2017 593 NaN NaN NaN NaN NaN
12/30/2017 519 593.0 -74.0 NaN NaN NaN
12/29/2017 1049 519.0 530.0 -74.0 604.0 604.0
12/28/2017 1267 1049.0 218.0 530.0 -312.0 -312.0
12/27/2017 1117 1267.0 -150.0 218.0 -368.0 -368.0
... ... ... ... ... ... ...
1/5/2014 32 1.0 31.0 -830.0 861.0 861.0
1/4/2014 181 32.0 149.0 31.0 118.0 118.0
1/3/2014 6 181.0 -175.0 149.0 -324.0 -324.0
1/2/2014 111 6.0 105.0 -175.0 280.0 280.0
1/1/2014 95 111.0 -16.0 105.0 -121.0 -121.0
그러면 차분을 했던 데이터의 정상성을 검정해보자
diff_data = data['rides'].diff(1).dropna()
# 표 그리기
plt.figure(figsize=(16,9))
plt.plot(diff_data.values, alpha=.7)
plt.hlines(y=diff_data.mean(), xmin=-50, xmax=1500, colors='red', linestyles='dashed')
plt.ylabel('divvy_rider')
plt.show()
추가)
2차차분에 대한 시각화는 다음과 같다.
diff_data = data['rides'].diff().diff().dropna()
# 표 그리기
plt.figure(figsize=(16,9))
plt.plot(diff_data.values, alpha=.7)
plt.hlines(y=diff_data.mean(), xmin=-50, xmax=1500, colors='red', linestyles='dashed')
plt.ylabel('divvy_rider')
plt.show()
ADF, KPSS 검정은 앞 포스트를 참고하면 된다.
adf_test(diff_data)
>>>
Results of Dickey-Fuller Test:
Test Statistic -9.252496e+00
p-value 9.827854e-14
Lags Used 2.100000e+01
Number of Observations Used 1.435000e+03
Critical Value (1%) -3.965093e+00
Critical Value (5%) -3.413554e+00
Critical Value (10%) -3.128854e+00
dtype: float64
정상시계열이 아니라는 귀무가설을 5.0%의 유의수준으로 기각할 수 있으므로 해당 데이터는 정상성이 보장됩니다.
kpss_test(diff_data)
>>>
Results of KPSS Test:
Test Statistic 0.043502
p-value 0.100000
Lags Used 52.000000
Critical Value (10%) 0.119000
Critical Value (5%) 0.146000
Critical Value (2.5%) 0.176000
Critical Value (1%) 0.216000
dtype: float64
정상시계열이 맞다는 귀무가설을 5.0%의 유의수준으로 기각할 수 없으므로 해당 데이터는 정상성이 보장됩니다.
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/statsmodels/tsa/stattools.py:2015: InterpolationWarning: The test statistic is outside of the range of p-values available in the
look-up table. The actual p-value is greater than the p-value returned.
이렇게 이번에는 차분을 통해서 비정상 시계열을 안정화하는 작업을 해보았다. (물론 정상화를 위해서는 차분외에도 log 치환 등도 존재한다. 하지만 이번에는 차분만 다루는 것으로 하였다)
다음글에서 ACF가 이어집니다.
2022.01.20 - [공부/모델링] - ACF (auto-correlative function, 자기상관함수) python
ACF (auto-correlative function, 자기상관함수) python
자기상관함수는 보통 시계열 분석으로 도출된 잔차가 시간의 흐름에 따라 상관성이 존재하는지 확인하는 함수이다. 물론 ARIMA를 시행할 때, p,q를 설정하기 위해서도 ACF를 활용하기도 한다. 이번
signature95.tistory.com
'공부 > 통계학' 카테고리의 다른 글
PACF (Partial Auto Correlation Function, 편자기상관함수) python (0) | 2022.01.20 |
---|---|
ACF (auto-correlative function, 자기상관함수) python (0) | 2022.01.20 |
Stationary test (정상성 검정) python (0) | 2022.01.19 |
Stepwise Feature Selection (단계선택법) python (0) | 2022.01.14 |
Backward Feature Selection (후진제거법) python (0) | 2022.01.13 |
댓글