ACF와 PACF란? 파이썬으로 시계열 자기상관 분석하는 방법
시계열 데이터에서는 과거 값이 현재 값과 얼마나 연결되어 있는지 확인하는 과정이 중요합니다. ACF와 PACF를 이해하면 ARIMA의 p와 q가 어디에서 나오는지 훨씬 쉽게 이해할 수 있습니다. 그래프의 막대 몇 개만 보고 모델을 결정하기보다 정상성·정보기준·검증 결과를 함께 확인해야 합니다.
앞선 글에서는 ADF 검정을 이용해 시계열 데이터의 정상성을 확인하는 방법을 살펴봤습니다.
그렇다면 정상성을 어느 정도 확인하거나 필요한 차분을 마친 다음에는 무엇을 봐야 할까요?
이번에는 데이터의 ‘기억’을 살펴볼 차례입니다.
오늘의 주가 수익률은 어제와 관계가 있을까요?
오늘의 금리는 한 달 전 금리와 어느 정도 관련되어 있을까요?
과거 1일 전, 2일 전, 3일 전 데이터가 현재 값과 각각 어느 정도 연결되어 있는지를 살펴보는 대표적인 도구가 ACF와 PACF입니다.
처음 접하면 그래프에 막대가 여러 개 나타나서 복잡해 보이지만 두 개념의 차이를 이해하면 AR, MA, ARIMA 모델의 구조도 훨씬 자연스럽게 연결됩니다.
이번 글에서는 ACF와 PACF의 개념부터 파이썬 statsmodels를 이용한 시각화, 그리고 ARIMA의 p와 q를 탐색할 때 어떻게 활용하는지까지 순서대로 알아보겠습니다.
1. 자기상관 ACF란 무엇일까?
자기상관은 이름 그대로 하나의 시계열이 과거의 자기 자신과 얼마나 관련되어 있는지를 의미합니다.
예를 들어 오늘의 값을 t라고 하면 하루 전 값은 t-1, 이틀 전 값은 t-2라고 표현할 수 있습니다.
이때 현재 값과 1일 전 값의 관계를 lag 1 자기상관이라고 생각할 수 있습니다.
2일 전 값과의 관계는 lag 2입니다.
예를 들어 다음과 같은 시계열이 있다고 가정해보겠습니다.
10
12
14
16
18
20
계속 비슷한 방향으로 움직이고 있기 때문에 현재 값과 바로 이전 값 사이에는 상당히 강한 관계가 나타날 가능성이 있습니다.
반면 다음처럼 값이 불규칙하게 움직인다면 자기상관이 상대적으로 약하게 나타날 수도 있습니다.
10
3
18
7
12
5
ACF는 Autocorrelation Function의 약자로 여러 lag에서 자기상관을 계산해 보여줍니다.
파이썬에서는 statsmodels를 이용해 쉽게 확인할 수 있습니다.
import pandas as pd
from statsmodels.tsa.stattools import acf
df = pd.read_csv("stock_data.csv")
df["Date"] = pd.to_datetime(df["Date"])
df = df.sort_values("Date")
df["return"] = df["Close"].pct_change()
series = df["return"].dropna()
acf_values = acf(series, nlags=20)
print(acf_values)
statsmodels의 acf()는 lag 0부터 지정한 lag까지 자기상관 값을 계산합니다. lag 0은 자기 자신과의 상관관계이기 때문에 1입니다.
하지만 숫자만 보는 것보다 그래프로 확인하는 편이 훨씬 편합니다.
import matplotlib.pyplot as plt
from statsmodels.graphics.tsaplots import plot_acf
plot_acf(
series,
lags=20,
alpha=0.05
)
plt.show()
plot_acf()는 각 lag의 자기상관과 신뢰구간을 시각화할 수 있도록 제공되는 함수입니다. 기본적인 그래프에서는 가로축에 lag, 세로축에 자기상관이 나타납니다.
그래프를 보면 보통 가운데를 기준으로 신뢰구간이 표시됩니다.
특정 lag의 막대가 신뢰구간을 벗어난다면 해당 시차의 자기상관을 추가로 살펴볼 근거가 될 수 있습니다.
하지만 여기서 중요한 점이 있습니다.
막대가 신뢰구간을 벗어났다고 해서 곧바로 투자 예측력이 있다는 뜻은 아닙니다.
ACF는 시계열의 구조를 살펴보는 통계적 도구이지 수익을 보장하는 신호가 아닙니다.

2. PACF는 ACF와 무엇이 다를까?
ACF를 이해했다면 PACF가 조금 더 중요하게 느껴질 수 있습니다.
PACF는 Partial Autocorrelation Function, 즉 부분자기상관함수입니다.
핵심은 중간 lag들의 영향을 통제한다는 것입니다.
예를 들어 현재 값과 2일 전 값의 관계를 생각해보겠습니다.
2일 전 값은 1일 전 값에 영향을 주고, 1일 전 값은 다시 현재 값에 영향을 줄 수 있습니다.
그러면 현재와 2일 전 사이에 나타나는 상관관계 가운데 일부는 사실 1일 전 값의 영향 때문에 발생한 것일 수 있습니다.
PACF는 이러한 중간 시차의 영향을 제거하고 특정 lag와 현재 값 사이의 직접적인 관계를 살펴보는 개념입니다.
단순화하면 다음처럼 이해할 수 있습니다.
ACF
현재와 과거 값 사이의 전체적인 상관관계
PACF
중간 시차의 영향을 제거한 뒤 남는 직접적인 상관관계
파이썬에서는 pacf()를 이용할 수 있습니다.
from statsmodels.tsa.stattools import pacf
pacf_values = pacf(
series,
nlags=20
)
print(pacf_values)
statsmodels의 pacf()는 lag별 부분자기상관을 계산하며 여러 추정 방법을 선택할 수 있습니다.
그래프는 다음처럼 그릴 수 있습니다.
from statsmodels.graphics.tsaplots import plot_pacf
import matplotlib.pyplot as plt
plot_pacf(
series,
lags=20,
method="ywm",
alpha=0.05
)
plt.show()
현재 statsmodels의 plot_pacf()는 PACF 그래프와 신뢰구간을 함께 그릴 수 있도록 제공됩니다.
ACF와 PACF를 나란히 출력하면 비교가 더 쉽습니다.
import matplotlib.pyplot as plt
from statsmodels.graphics.tsaplots import (
plot_acf,
plot_pacf
)
fig, axes = plt.subplots(
1,
2,
figsize=(12, 4)
)
plot_acf(
series,
lags=20,
ax=axes[0]
)
plot_pacf(
series,
lags=20,
ax=axes[1],
method="ywm"
)
axes[0].set_title("ACF")
axes[1].set_title("PACF")
plt.tight_layout()
plt.show()
이렇게 하면 같은 시계열의 자기상관과 부분자기상관 구조를 한눈에 비교할 수 있습니다.
3. ACF와 PACF로 ARIMA의 p와 q를 찾는 방법
ACF와 PACF가 많이 언급되는 이유 중 하나는 ARIMA 모델과 연결되기 때문입니다.
ARIMA는 일반적으로 다음과 같이 표현합니다.
ARIMA(p, d, q)
각 숫자는 서로 다른 의미를 가집니다.
- p: AR, 즉 자기회귀 항의 차수
- d: 정상성을 만들기 위해 적용하는 차분 차수
- q: MA, 즉 이동평균 오차 항의 차수
statsmodels 공식 ARIMA 인터페이스에서도 order=(p, d, q) 형태로 자기회귀, 차분, 이동평균 구성요소를 지정합니다.
앞선 ADF 검정 글에서 살펴본 차분이 여기에서 d와 연결됩니다.
그러면 p와 q는 어떻게 정할까요?
전통적인 시계열 분석에서는 ACF와 PACF 형태를 초기 후보를 찾는 데 활용해왔습니다.
대표적으로 AR(p) 구조에서는 PACF가 특정 lag 이후 상대적으로 급격하게 약해지고 ACF가 서서히 감소하는 패턴을 볼 수 있습니다.
반대로 MA(q) 구조에서는 ACF가 특정 lag 이후 약해지고 PACF가 점차 감소하는 형태가 나타날 수 있습니다.
단순한 예를 들어보겠습니다.
PACF에서 lag 1까지 뚜렷한 관계가 보이고 이후 상대적으로 약해진다면 AR(1)을 후보 가운데 하나로 검토할 수 있습니다.
ACF가 lag 1에서 강하고 이후 약해진다면 MA(1)을 후보로 검토할 수 있습니다.
하지만 이것을 공식처럼 외우면 문제가 생깁니다.
실제 금융 데이터에서는 ACF와 PACF가 교과서처럼 깨끗하게 끊기지 않는 경우가 많습니다.
AR과 MA가 함께 존재하거나 데이터에 계절성·구조 변화·변동성 군집 등이 포함될 수도 있기 때문입니다.
따라서 ACF와 PACF는 모델을 ‘확정하는 도구’라기보다 후보 차수를 탐색하는 도구로 보는 것이 합리적입니다.
예를 들어 다음 모델들을 후보로 만들 수 있습니다.
from statsmodels.tsa.arima.model import ARIMA
model_1 = ARIMA(
series,
order=(1, 0, 0)
)
model_2 = ARIMA(
series,
order=(0, 0, 1)
)
model_3 = ARIMA(
series,
order=(1, 0, 1)
)
statsmodels가 제공하는 현재 ARIMA 모델은 AR, MA, ARMA, ARIMA 및 계절 구조를 포함한 확장 형태를 지원합니다.
모델을 적합하면 다음처럼 요약 결과를 확인할 수 있습니다.
result = model_3.fit()
print(result.summary())
공식 statsmodels ARIMA 예제에서도 p, d, q를 정한 뒤 ARIMA()로 모델을 생성하고 fit()을 통해 적합하는 구조를 사용합니다.
4. ACF·PACF 그래프만 믿으면 안 되는 이유
시계열 분석을 처음 공부하면 다음과 같은 방식으로 모델을 고르고 싶어질 수 있습니다.
“PACF가 2에서 끊겼으니 p=2다.”
“ACF가 1까지만 커 보이니 q=1이다.”
하지만 실제 분석에서는 이렇게 단순하게 결론 내리기 어렵습니다.
첫 번째로 정상성이 확보되지 않은 원본 가격 데이터를 그대로 ACF에 넣으면 높은 자기상관이 여러 lag에서 오래 지속될 수 있습니다.
예를 들어 주가 수준에 강한 추세가 있다면 ACF가 천천히 감소하는 모습을 보일 수 있습니다.
따라서 앞선 글에서 다룬 ADF 검정과 차분 과정을 먼저 검토하는 이유가 여기에 있습니다.
가격과 수익률의 ACF를 각각 비교해보는 것도 좋은 방법입니다.
df["return"] = df["Close"].pct_change()
price = df["Close"].dropna()
returns = df["return"].dropna()
plot_acf(price, lags=20)
plt.show()
plot_acf(returns, lags=20)
plt.show()
두 그래프가 상당히 다르게 나타날 수 있습니다.
두 번째로 표본 크기를 고려해야 합니다.
데이터가 많지 않은 상태에서 너무 긴 lag를 살펴보면 해석이 불안정해질 수 있습니다.
세 번째로 여러 후보 모델을 실제로 비교해야 합니다.
예를 들어 몇 가지 차수를 적합한 뒤 AIC나 BIC 같은 정보기준을 함께 확인할 수 있습니다.
candidates = [
(1, 0, 0),
(0, 0, 1),
(1, 0, 1),
(2, 0, 1),
(1, 0, 2)
]
for order in candidates:
model = ARIMA(
series,
order=order
)
result = model.fit()
print(
order,
"AIC:",
result.aic,
"BIC:",
result.bic
)
AIC나 BIC가 작다고 해서 실제 미래 예측 성능까지 자동으로 가장 좋다는 뜻은 아닙니다.
따라서 마지막에는 학습 데이터와 테스트 데이터를 시간 순서대로 나누고 실제 예측 성능을 확인하는 과정까지 필요합니다.
금융 시계열에서는 데이터를 무작위로 섞어버리기보다 과거 데이터로 학습하고 이후 데이터를 평가하는 구조를 사용하는 것이 특히 중요합니다.
5. ACF와 PACF를 볼 때 꼭 확인할 것
여기까지 내용을 실제 분석 순서로 정리하면 다음과 같습니다.
- 날짜를 시간순으로 정렬한다.
- 결측치와 이상치를 점검한다.
- 가격·수익률·로그수익률 등 분석 변수를 결정한다.
- ADF 등으로 정상성을 점검한다.
- 필요한 경우 차분한다.
- ACF로 전체적인 자기상관 구조를 확인한다.
- PACF로 특정 lag의 직접적인 관계를 확인한다.
- ARIMA의 p와 q 후보를 만든다.
- 여러 후보 모델의 AIC·BIC와 잔차를 비교한다.
- 시간 순서를 유지한 검증 데이터에서 실제 성능을 확인한다.
ACF와 PACF를 공부할 때 가장 중요한 것은 그래프 모양을 암기하는 것이 아닙니다.
ACF는 과거 값과 현재 값 사이에 남아 있는 전체적인 관계를 보여주고, PACF는 중간 lag의 영향을 통제한 직접적인 관계를 살펴본다는 차이를 이해하는 것이 먼저입니다.
그리고 이 결과를 이용해 AR이나 MA 차수의 후보를 만들 수 있지만, 실제 모델 선택은 ACF·PACF 하나만으로 끝내지 않는 것이 좋습니다.
정상성, 정보기준, 잔차, 그리고 실제 예측 성능까지 함께 확인해야 합니다.
이렇게 보면 지금까지의 글들이 하나의 분석 흐름으로 연결됩니다.
시계열 전처리에서 결측치와 이상치를 정리하고,
ADF 검정으로 정상성을 확인하고,
ACF와 PACF로 자기상관 구조를 살펴봤습니다.
이제 다음 단계에서는 실제 ARIMA 모델을 만들 차례입니다.
다음 글에서는 **「파이썬 ARIMA 모델 사용법: 주가 시계열 예측부터 성능 평가까지」**를 통해 ARIMA(p,d,q)의 의미부터 모델 학습, 예측, 실제값 비교와 오차 평가까지 하나의 예제로 이어서 살펴보겠습니다.
참고 자료
statsmodels 공식 문서는 plot_acf()와 plot_pacf()를 각각 자기상관함수와 부분자기상관함수를 시각화하는 도구로 제공하고 있습니다.
statsmodels의 ACF 함수는 lag 0부터 지정한 시차까지 자기상관을 계산하며, PACF 함수는 부분자기상관 추정 기능을 제공합니다.
statsmodels의 ARIMA 공식 문서에서 모델의 order는 (p,d,q)로 구성되며 각각 자기회귀, 차분, 이동평균 구성요소의 차수를 나타냅니다.
금융소비자보호 및 개인 유의사항
본 글은 파이썬과 통계적 시계열 분석 방법을 설명하기 위한 교육 및 정보 제공 목적의 콘텐츠입니다. 특정 금융상품의 매수·매도 또는 투자 행동을 권유하기 위한 내용이 아닙니다.
ACF와 PACF의 형태 및 ARIMA 분석 결과는 사용 데이터, 분석 기간, 데이터 빈도, 전처리 방식과 모델 설정에 따라 달라질 수 있습니다. 과거 데이터에서 확인된 자기상관이나 모델의 예측 결과가 향후 시장 움직임 또는 투자 성과를 보장하지 않습니다.
금알남
댓글 0
첫 댓글을 남겨보세요.