기본 콘텐츠로 건너뛰기

[matplotlib]quiver()함수

[time series] ACF와 PACF

ACF(Autocorrelation function)와 PACF(Partial ACF)

ACF와 PACF 플롯은 시계열 데이터의 정상성(Statioinary)을 시각적으로 판단하는데 유용한 도구입니다.

정상성 시계열은 시간에 따라 평균, 분산 등 통계적인 속성이 일정하게 유지되는 반면 비정상성인 경우 추세, 계절성 또는 시간에 따라 변동이 존재합니다.

ACF

ACF는 서로다른 시점의 값들 간의 상관관계를 측정하는 함수입니다. 즉, 특정시점의 값과 그 보다 k 이전(lag k)의 값 사이의 상관계수를 계산하여 시간 순서에 따라 나열되는 데이터들 간의 자기 의존성을 파악하는데 사용합니다.

$$\rho(k) = \frac{\text{Cov}(y_t, y_{t-k})}{\sqrt{\text{Var}(y_t) \text{Var}(y_{t-k})}}$$
  • yt: 시점 t의 시계열 값
  • Cov(): 공분산
  • Var(): 분산

정상성을 갖는 다면 평균과 분산이 시간에 따라 변하지 않으므로 Var(yt) = Var(yt-k)이므로 위 식의 분모는 상수가 됩니다. 즉 자기상관함수는 공분산을 분산으로 정규화한 형대가 됩니다.

계산과정

  1. 시계열 평균
    • $\bar{y} = \frac{1}{n} \sum^n_{t=1} y_t$
  2. 자기공분산 계산
    • $\gamma_k = \frac{1}{n}\sum^n_{t=k+1} (y_t-\bar{y})(y_{t-k} -\bar{y})$
  3. ACF값 계산: 0차 지연(lag 0)에서의 자기공분산(분산)으로 정규화
    • $\rho_k =\frac{\gamma_k }{\gamma_0}=\frac{\sum^n_{t=k+1} (y_t-\bar{y})(y_{t-k} -\bar{y})}{\sum^n_{t=1} (y_t-\bar{y})}$

다양한 k값들을 계산하기 위해 위 과정을 반복합니다.

statsmodels.tsa.stattools.acf(x, nlags=None, alpha=None, \hellip;) 함수를 사용합니다. nlags로 k값을 지정할 수 있으며 , alpha 값을 지정하는 것에 의해 각 자기상관계수의 신뢰구간이 계산됩니다. 이 결과의 그래프는 statsmodels.graphics.tsaplots.plot_acf() 함수로 작성할 수 있습니다.

import numpy as np
import pandas as pd
import yfinance as yf
import matplotlib.pyplot as plt

from statsmodels.tsa.stattools import acf, pacf
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
st=pd.Timestamp(2024,1, 1)
et=pd.Timestamp(2025, 4,25)
trgnme="000660.KS"
trg=yf.download(trgnme,  st, et)
trg.columns=[i[0] for i in trg.columns]
close=trg["Close"]

pandas 라이브러리의 .isnull().sum() 함수를 사용하여 데이터의 null의 존재를 확인할 수 있으며 .info() 함수로 데이터의 정보를 알수 있습니다. 또한 기술적 통계 .describe()함수를 사용합니다.

close.isnull().sum()
0
close.info()
<class 'pandas.core.series.Series'>
DatetimeIndex: 320 entries, 2024-01-02 to 2025-04-24
Series name: Close
Non-Null Count  Dtype  
--------------  -----  
320 non-null    float64
dtypes: float64(1)
memory usage: 5.0 KB
close.describe()
count       320.000000
mean     183004.198120
std       24984.218425
min      130400.945312
25%      168515.046875
50%      182315.687500
75%      198900.000000
max      240600.328125
Name: Close, dtype: float64
acf_close=acf(close, nlags=3, alpha=0.05)
acf_close
(array([1.        , 0.96767008, 0.93478064, 0.90405612]),
 array([[1.        , 1.        ],
        [0.85810477, 1.0772354 ],
        [0.74907564, 1.12048564],
        [0.66854419, 1.13956805]]))
f, ax=plt.subplots(figsize=(6, 2))
plot_acf(close, lags=30, ax=ax)
plt.ylim(-1, 1.1)
plt.show()

위 결과는 ACF 플롯 (Correlogram)입니다.

  • 상관성의 존재 여부 및 강도: ACF 값이 0에서 멀리 떨어져 있을수록 해당 lag에서 자기 상관성이 강하다는 것을 의미합니다.
    • 추세가 있는 경우: ACF는 매우 천천히 감소 또는 오랜 시간동안 유의미한 값을 유지. 현재와 먼 지연에서도 강한 상관관계를 가짐
    • 정상: 빠르게 0으로 감소, 현재와 먼 과거의 갑과의 상관관계가 없음을 의미. 짧은 지연(lag)에서만 유의미한 자기상관을 보임
  • 시계열의 패턴: ACF 플롯의 형태를 통해 시계열이 어떤 특성(예: 계절성, 추세)을 가지는지 짐작할 수 있습니다. 예를 들어, 계절성이 있는 데이터는 특정 주기를 갖는 ACF 플롯을 보일 수 있습니다.
    • 계절성이 있는 경우: 주기적인 스파크가 나타남.
  • ARIMA 모델 차수 결정: ACF 플롯은 ARIMA 모델의 MA (Moving Average) 항의 차수를 결정하는 데 도움을 줄 수 있습니다.

PCAF

PACF는 서로다른 두 시점의 값들 간의 상관관계를 측정할 때 그 사이의 모든 시점의 영향력을 제거한 순수한 상관관계를 나타내는 함수 입니다.

PACF은 Yule-Walker 방정식 또는 단계별 회귀분석을 이용하는 방법으로 계산됩니다.

Yule-Walker 방정식

다음 식과 같이 자기상관계수 ρk는 그 이전시점의 자기상관계수들과의 선형회귀 즉, AR 모형을 구축할 수 있습니다.

$$\rho_k = \phi_1\rho_{k-1}+\cdots+ \phi_p\rho_{k-p}+W_t$$

위 식에서 Wt는 오차항으로 백색잡음이 됩니다. 즉, 위 선형모델에서 φ1는 ρ{k-1}가 ρk에 단독으로 영향을 주는 정도를 나타냅니다. 그러므로 위 식의 각 항의 계수가 PCAF가 됩니다. 위 식을 행렬방정식 형태로 나타낸 것을 Yule-Walk 방정식이라 합니다.

$$\begin{pmatrix} 1 & \rho_1 & \rho_2 & \cdots & \rho_{k-1} \\ \rho_1 & 1 & \rho_1 & \cdots & \rho_{k-2} \\ \rho_2 & \rho_1 & 1 & \cdots & \rho_{k-3} \\ \vdots & \vdots & \vdots & \ddots & \vdots \\ \rho_{k-1} & \rho_{k-2} & \rho_{k-3} & \cdots & 1 \end{pmatrix} \begin{pmatrix} \phi_{k1} \\ \phi_{k2} \\ \phi_{k3} \\ \vdots \\ \phi_{kk} \end{pmatrix} = \begin{pmatrix} \rho_1 \\ \rho_2 \\ \rho_3 \\ \vdots \\ \rho_k \end{pmatrix}$$

위 방정식의 해인 φi를 계산하여 PCAF(부분상관계수)를 도출할 수 있습니다.

단계별 회귀분석 사용

위 식에서 반응변수와 설명변수를 ρ 대신 데이터를 사용하여 AR 모형을 실행시키면 각 항의 계수는 그에 대응하는 설명변수가 반응변수에 주는 영향을 나타냅니다.

$$y_k = \beta_1y_{k-1}+\cdots+ \beta_py_{k-p}+\epsilon_t$$

즉, 위 모델에서 yt-k의 회귀계수 βk가 lag k의 PCAF가 됩니다.

pacf(), plot_pacf() 함수로 PACF와 결과 그래프를 작성할 수 있습니다.

pacf_close=pacf(close, nlags=3, alpha=0.05)
pacf_close
(array([ 1.        ,  0.97070353, -0.0278097 ,  0.01927532]),
 array([[ 1.        ,  1.        ],
        [ 0.86113821,  1.08026885],
        [-0.13737502,  0.08175562],
        [-0.09028999,  0.12884064]]))
f, ax=plt.subplots(figsize=(6, 2))
plot_pacf(close, lags=30, ax=ax)
plt.ylim(-1, 1.1)
plt.show()

PACF 플롯 (Partial Correlogram):

  • 직접적인 자기 상관성의 존재 여부 및 강도: PACF 값이 0에서 멀리 떨어져 있을수록 해당 lag에서 직접적인 자기 상관성이 강하다는 것을 의미합니다. 중간 lag들의 영향을 제거했기 때문에 순수한 관계를 파악할 수 있습니다.
    • 정상: 유의미한 자기상관이 몇개의 짧은 지연에서만 나타나고, 이후에는 빠르게 0으로 감소
    • 비정상: 특정 시차까지 비교적 큰 스파크를 보임.
  • ARIMA 모델 차수 결정: PACF 플롯은 ARIMA 모델의 AR (Autoregressive) 항의 차수를 결정하는 데 도움을 줄 수 있습니다. PACF가 특정 lag 이후에 급격히 0으로 떨어지면 AR 차수를 그 lag으로 추정할 수 있습니다.

댓글

이 블로그의 인기 게시물

[Linear Algebra] 유사변환(Similarity transformation)

유사변환(Similarity transformation) n×n 차원의 정방 행렬 A, B 그리고 가역 행렬 P 사이에 식 1의 관계가 성립하면 행렬 A와 B는 유사행렬(similarity matrix)이 되며 행렬 A를 가역행렬 P와 B로 분해하는 것을 유사 변환(similarity transformation) 이라고 합니다. $$\tag{1} A = PBP^{-1} \Leftrightarrow P^{-1}AP = B $$ 식 2는 식 1의 양변에 B의 고유값을 고려한 것입니다. \begin{align}\tag{식 2} B - \lambda I &= P^{-1}AP – \lambda P^{-1}P\\ &= P^{-1}(AP – \lambda P)\\ &= P^{-1}(A - \lambda I)P \end{align} 식 2의 행렬식은 식 3과 같이 정리됩니다. \begin{align} &\begin{aligned}\textsf{det}(B - \lambda I ) & = \textsf{det}(P^{-1}(AP – \lambda P))\\ &= \textsf{det}(P^{-1}) \textsf{det}((A – \lambda I)) \textsf{det}(P)\\ &= \textsf{det}(P^{-1}) \textsf{det}(P) \textsf{det}((A – \lambda I))\\ &= \textsf{det}(A – \lambda I)\end{aligned}\\ &\begin{aligned}\because \; \textsf{det}(P^{-1}) \textsf{det}(P) &= \textsf{det}(P^{-1}P)\\ &= \textsf{det}(I)\end{aligned}\end{align} 유사행렬의 특성 유사행렬인 두 정방행렬 A와 B는 'A ~ B' 와 같...

[sympy] Sympy객체의 표현을 위한 함수들

Sympy객체의 표현을 위한 함수들 General simplify(x): 식 x(sympy 객체)를 간단히 정리 합니다. import numpy as np from sympy import * x=symbols("x") a=sin(x)**2+cos(x)**2 a $\sin^{2}{\left(x \right)} + \cos^{2}{\left(x \right)}$ simplify(a) 1 simplify(b) $\frac{x^{3} + x^{2} - x - 1}{x^{2} + 2 x + 1}$ simplify(b) x - 1 c=gamma(x)/gamma(x-2) c $\frac{\Gamma\left(x\right)}{\Gamma\left(x - 2\right)}$ simplify(c) $\displaystyle \left(x - 2\right) \left(x - 1\right)$ 위의 예들 중 객체 c의 감마함수(gamma(x))는 확률분포 등 여러 부분에서 사용되는 표현식으로 다음과 같이 정의 됩니다. 감마함수는 음이 아닌 정수를 제외한 모든 수에서 정의됩니다. 식 1과 같이 자연수에서 감마함수는 factorial(!), 부동소수(양의 실수)인 경우 적분을 적용하여 계산합니다. $$\tag{식 1}\Gamma(n) =\begin{cases}(n-1)!& n:\text{자연수}\\\int^\infty_0x^{n-1}e^{-x}\,dx& n:\text{부동소수}\end{cases}$$ x=symbols('x') gamma(x).subs(x,4) $\displaystyle 6$ factorial 계산은 math.factorial() 함수를 사용할 수 있습니다. import math math.factorial(3) 6 a=gamma(x).subs(x,4.5) a.evalf(3) 11.6 simpilfy() 함수의 알고리즘은 식에서 공통사항을 찾아 정리하...

sympy.solvers로 방정식해 구하기

sympy.solvers로 방정식해 구하기 대수 방정식을 해를 계산하기 위해 다음 함수를 사용합니다. sympy.solvers.solve(f, *symbols, **flags) f=0, 즉 동차방정식에 대해 지정한 변수의 해를 계산 f : 식 또는 함수 symbols: 식의 해를 계산하기 위한 변수, 변수가 하나인 경우는 생략가능(자동으로 인식) flags: 계산 또는 결과의 방식을 지정하기 위한 인수들 dict=True: {x:3, y:1}같이 사전형식, 기본값 = False set=True :{(x,3),(y,1)}같이 집합형식, 기본값 = False ratioal=True : 실수를 유리수로 반환, 기본값 = False positive=True: 해들 중에 양수만을 반환, 기본값 = False 예 $x^2=1$의 해를 결정합니다. solve() 함수에 적용하기 위해서는 다음과 같이 식의 한쪽이 0이 되는 형태인 동차식으로 구성되어야 합니다. $$x^2-1=0$$ import numpy as np from sympy import * x = symbols('x') solve(x**2-1, x) [-1, 1] 위 식은 계산 과정은 다음과 같습니다. $$\begin{aligned}x^2-1=0 \rightarrow (x+1)(x-1)=0 \\ x=1 \; \text{or}\; -1\end{aligned}$$ 예 $x^4=1$의 해를 결정합니다. solve() 함수의 인수 set=True를 지정하였으므로 결과는 집합(set)형으로 반환됩니다. eq=x**4-1 solve(eq, set=True) ([x], {(-1,), (-I,), (1,), (I,)}) 위의 경우 I는 복소수입니다.즉 위 결과의 과정은 다음과 같습니다. $$x^4-1=(x^2+1)(x+1)(x-1)=0 \rightarrow x=\pm \sqrt{-1}, \; \pm 1=\pm i,\; \pm1$$ 실수...