This post aims to provide some theoretical background on autocorrelation functions and how we can use it to analyse time series. Furthremore, we show how to use the autocorrelation (ACF) function and the Partial Autocorrelation (PACF) functions to determine the parameters for an ARMA model.

Brief introduction to time series

In a previous post (see here) we introduced some basic definitions and terminology about time series. To avoid forcing the reader to move back and forth we repeat those very same definitions here.

In layman’s terms, a time series is a series of observations (or data points) indexed in time order [1, 2]. A few examples of time series are

  • The daily closing price of a stock in the stock market
  • The number of air passengers per month
  • The biosignals recorded from electroencephalogram or electrocardiogram

Figure 1 shows the number of air passengers per month from January 1949 to September 1960. In all the examples in this post, we are going to use this dataset, so if you would like to try the examples by yourself; you can download the data from Kaggle here.

Figure 1. An example of a time series showing the number of air passengers per month.

A more rigorous definition of a time series found in [1] (Chapter 1, pg 1) is given below:

Let $ k \in \mathbf{N}, T \subseteq \mathbf{R} $. A function $$ x: T \rightarrow \mathbf{R}^k, \hspace{2mm} t \rightarrow x_t $$ or equivalently, a set of indexed elements of $ \mathbf{R}^k $, $$ \begin{Bmatrix} x_t | x_t \in \mathbf{R}^k, \hspace{2mm} t \in T \end{Bmatrix} $$ is called an observed time series (or time series). Sometimes, we write $ x_t(t \in T) $ or $ (x_t)_{t\in T} $.

When $ k = 1 $ the time series is called univariate, otherwise is called multivariate. $ T $ determines if the time series is [1]:

  • discrete $ T $ is countable, and $ \forall a < b \in \mathbb{R}: T \cap[a, b] $ is finite,
  • continuous $ T = [a, b], a < b \in \mathbb{R}, T = \mathbb{R}_{+} \hspace{2mm} \text{or} \hspace{2mm} T = \mathbb{R} $,
  • equidistant $ T $ is discrete, and $ \exists u \hspace{2mm} s.t. \hspace{2mm} t_{j+1} - t_j = u $.

From now on and for simplicity’s sake we will use the following notation for a time series: $ \begin{Bmatrix} y[1], y[2], \ldots , y[N] \end{Bmatrix} $, where $ N \in \mathbb{N} $ or $ y[t] $, where $t=1, \ldots , N $.

What is autocorrelation (ACF)

The Autocorrelation function (from now on, we will refer to the autocorrelation function as ACF) for a given time series $ x[t] $ at times $ t_1, t_2, \ldots, t_N $ with mean $ \mu_t $ and the time series $ x[s] $ at time $ s_1, s_2, \ldots, s_N $ with mean $ \mu_s $ is givenb by following formula:

$$ \rho(s, t) = \frac{\mathbb{E}[(x[s]-\mu_s)(x[t]-\mu_t)]}{\mathbb{E}[(x[s]-\mu_s)^2] \mathbb{E}[(x[t]-\mu_t)^2]}. \qquad (1) $$

Another way to express the ACF is through the autocovariance function. By plugging the equation of correlation

$$ \gamma(s, t) = \text{cov}(x[s], x[t]) = \mathbb{E}[(x[s]-\mu_s)(x[t]-\mu_t)], $$ into equation (1) we obtain $$ \rho(s, t) = \frac{\gamma(s, t)}{\sqrt{\gamma(s, s) \gamma(t, t)}}. $$

The above definitions are valid for time series of real numbers. If the time series are complex then we have to replace the term $ \mathbb{E}[(x[s]-\mu_s)(x[t]-\mu_t)] $ with the complex conjugate $\mathbb{E}[(x[s]-\mu_s)\bar{(x[t]-\mu_t)}] $.

From the definitions above one can conclude, first, the autocovariance of a time series with itself is the variance of the signal (i.e., $ \gamma(t, t) = \text{Var}[x[t]] $) and second, the autocorrelation of a time series x[t] with itself is one (i.e., $ \rho(t, t) = 1 $).

Let’s now explain the autocorrelation in layperson’s terms and give some intuition on the information we obtain by using it. Let’s start with the very notion of a time series. In a time series, the data points are ordered temporally. Thus, extra information is stored in a time series, meaning we can determine how past data (historical data) can affect present or future values or the correlation between those points. Therefore, autocorrelation or serial correlation is nothing more than the correlation of a data point with its past values (previous times).

How to compute ACF

Therefore, to estimate the ACF, we start by evaluating the correlation of the original time series with itself (zero lag). Then we introduce a lag into our original time series and estimate the correlation between the original time series and its lagged version. We repeat those steps until we exhaust the predetermined number of lags. The table below shows an example of a time series and its first three lagged signals. From now on, we will use the letter $ k $ to indicate any lag.

($ k = 0 $) $ k = 1 $ $ k = 2 $ $ k = 3
1 NaN NaN NaN
2 1 NaN NaN
3 2 1 NaN
4 3 2 1
5 4 3 2
6 5 4 3
7 6 5 4

Let’s now estimate the ACF for the data given in the table above. First, we will write our custom ACF function in the Python programming language, and then we will introduce the ACF function of the statsmodels Python package.

>> import numpy as np

def rho(x, nlags=1):
    # Create a list with all the lagged versions of input signal x
    x_lagged = [x[:(len(x) - i)] for i in range(nlags)]

    # Compute the mean of input x
    x_bar = x.mean()

    # Initialize a list that contains the correlations for each lag
    acf = []

    # Loop over all lags and use equation (1)
    for lag in range(nlags):
        nominator = ((x[lag:] - x_bar) * (x_lagged[lag] - x_bar)).sum() 
        denominator = ((x - x_bar)**2).sum()
        acf.append(nominator / denominator)
    return acf


>> x = np.array([1, 2, 3, 4, 5, 6, 7])
>> rho(x, nlags=4)
[1.0, 0.5714285714285714, 0.17857142857142858, -0.14285714285714285]

The above code snippet shows how to implement a naive autocorrelation algorithm. Now, let’s compute the ACF but this time using the statsmodels Python package (if you haven’t installed the statsmodels package, you will find all the installation information here). The package statsmodels provides tools for the estimation of different statistical models, as well as for conducting statistical tests and statistical data exploration. We will use the TSA submodule, which contains time series analysis and prediction tools.

>> from statsmodels.tsa.stattools import acf       # import ACF


>> x = np.array([1, 2, 3, 4, 5, 6, 7])
>> acf(x, nlags=3, fft=True) 
array([ 1.        ,  0.57142857,  0.17857143, -0.14285714])

As we expected, the ACF of the statsmodels package returns the same results as our custom-made function does. The only difference is that we used four lags in our custom function, and that’s because we count the zero lag ($ k = 0 $) as well. For more information about the ACF function you can check the docs of statsmodels package.

One important note regarding ACF and later the PACF is the number of lags we have to use. The statsmodels module computes the number of lags using the following formula

$$ \text{nlags} = \min \begin{Bmatrix} 10 \log_{10}(N), N - 1 \end{Bmatrix}, $$

where $ N $ is the number of observations in the time series (raw data).

The ACF is often used to identify non-randomness in a time series and to aid in determining the parameters of a mathematical model for that time series.

What is partial autocorrelation (PACF)

Partial autocorrelation, or PACF, is more challenging to understand than ACF. Let’s understand the intuition behind the PACF, and then we will see how to estimate the PACF for a time series. Remember that the ACF reveals how a measurement (or a data point) at a given time index $ t $ affects a data point at time $ t - k $ ($ k $ is the lag). In that case, the formula for estimating ACF considers all the intermediate data points $ t + 1, t + 2, \ldots, t + k - 1 $ until it reaches the $ t + k $. Now, the PACF ignores the information in the intermediate data points; hence it is called partial.

Let’s now give a more rigorous mathematical definition of PACF. Assume that we have a time series x[t], then the PACF is defined as

$$ \rho_{\text{partial}}(t, t) = \text{corr}(x[t+1], x[t]) \quad for k = 1, $$

$$ \rho_{\text{partial}}(t, k) = \text{corr}(x[t+k] - \hat{x}[t+k], x[t] - \hat{x}[t]), \quad for k \geq 2, $$

where $ \hat{x}[t+k] $ and $ \hat{x}[t] $ are linear combinations of all the intermediate data points (i.e., $ x[t+1], x[t+2], \ldots, x[t+k-1]$) that minimize the mean squared error (see here) of $ x[t+k] $ and $ x[t] $, respectively.

How to compute PACF

Estimation of the PACF can be done with several algorithms. The most known are (i) the Yule-Walker approach, (ii) the ordinary least squares (OLS), and the Levinson-Durbin recursion method. The package statsmodels implements all those methods and a few more (see statsmodels docs).

Let’s take the previous very simple example and estimate the PCAF for the time series $ x[t] = 1, 2, 3, 4, 5, 6, 7 $.

>> from statsmodels.tsa.stattools import acf       # import ACF

>> x = np.array([1, 2, 3, 4, 5, 6, 7])
>> acf(x, nlags=3, method="ols")
array([ 1.00000000e+00,  1.00000000e+00,  1.55431223e-15, -3.33333333e-01])

In the code snippet above, we specified the algorithm for estimating the PCAF to be the ordinary least squares. It is relatively simple to implement the OLS method from scratch. We will use the function lagmat of statsmodels which creates a $ 2d $ array of lags, and we will separate the zero lag signal, which is the original data. Finally, we will use the Numpy function lstsq to estimate the parameters of the least squares and thus compute the PACF.

>> import numpy as np
>> from numpy.linalg import lstsq
>> from statsmodels.tsa.stattools import lagmat 

>> x = np.array([1, 2, 3, 4, 5, 6, 7])

# Compute the lags (x_lagged) and keep the original time series in x0
>> x_lagged, x0 = lagmat(x, 3, original="sep")

# Prepend x_lagged with a column of ones (add constant)
>> x_lagged = x_lagged = np.append(np.ones((7,1)), x_lagged, axis=1)

# The first element of PACF is always 1.0
pacf = [1.0]

# Run the least squares over lags
>> for lag in range(1, lags + 1):
>>     params = lstsq(x_lagged[lag:, :(lag+1)], x0[lag:], rcond=None)[0]
>>     pacf.append(params[-1][0])

>> print(pacf)
[1.0, 1.000000000000001, 1.5543122344752192e-15, -0.33333333333333415]

Keep in mind that here we used the method of least squares, and if one wants to use a different approach to estimate the PACF, the values will differ from the ones in the code snippet above. Moreover, the function lstsq receives an argument named rcond which is a cut-off ratio for small singular values of x_lagged.

Visualization of ACF and PACF

Up to now, we have defined ACF and PACF and learned how to estimate them given a time series. Now we will explore the visualization of ACF and PACF and learn how to interpret their graphical representations. To better demonstrate the power of ACF and PACF visualization, we will apply those two methods to the airport passengers' data set (see Figure 1). To simplify things we will use the functions plot_acf and plot_pacf provided by the Python module statsmodels.

import numpy as np
import matplotlib.pylab as plt

# Import the plot_acf, and plot_pacf functtions
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

# Load the data
x = np.genfromtxt("PATH_TO_FILE/passengers.csv")

fig = plt.figure(figsize=(9, 12))
ax1 = fig.add_subplot(211)

# Call the function for estimating and plotting the ACF
plot_acf(x, ax1, fft=True)

ticks = ax1.get_xticks().astype('i')
ax1.set_xticklabels(ticks, fontsize=14, weight='bold')
ticks = ax1.get_yticks()
ax1.set_yticklabels(ticks, fontsize=14, weight='bold')
ax1.set_title("Autocorrelation (ACF)", fontsize=16, weight='bold')

ax2 = fig.add_subplot(212)

# Call the function plot_pacf to estimate and visualize the PACF
# We use the method "ols" as we did in a previous example
plot_pacf(x, ax2, method="ols")

ticks = ax2.get_xticks().astype('i')
ax2.set_xticklabels(ticks, fontsize=14, weight='bold')
ticks = ax2.get_yticks()
ax2.set_yticklabels(ticks, fontsize=14, weight='bold')
ax2.set_title("Partial Autocorrelation (PACF)", fontsize=16, weight='bold')
plt.show()

After running the script above, we get the plots of ACF and PACF, as depicted in Figure 2. The left panel shows the ACF, and the right is the PACF. Blue-shaded areas indicate the confidence interval cone, and each point outside that cone is considered significant ($ 95 $% confidence). In simple words, whatever is within that cone is considered to be zero.

Figure 2. ACF and PACF on airport passengers data set. Left panel - ACF, right panel PACF.

We observe that the first component in the ACF and PACF plots equals one, as we expected (and have already discussed). A second apparent observation is the reflection of the original’s data periodicity in the ACF plot. The most important part of those graphic representations is the number of statistically significant correlations (outside the cone). Data points in the ACF plot reflect the correlation between a data point in our time series and its past values. Therefore, the number of significant correlations indicates how far in the past one should look to predict a future point using some mathematical/statistical model.

In the following sections, we will learn how to use the ACF and PACF plots to make assumptions about our models and determine their parameters.

What is an ARMA and an ARIMA model?

We will begin our discussion on ARMA and ARIMA models by introducing the autoregressive (AR) and the moving average (MA) models.

Autoregressive Model - AR(p)

The AR(p) model is based on linear regression. It assumes that the current value $ x[t] $ is dependent on previous (past) values (observations). Due to this ``linear'' relationship to the past, AR(p) relies on linear regression. More precisely, it is described by the following equation:

$$ x[t] = \sum_{i=1}^{p} \phi [i] x[t-i] + \epsilon [t], \qquad (2) $$

where $ \phi[1], \ldots, \phi[p] $ are the parameters of the model, and $ \epsilon[t] $ is white noise. We will refer to equation (2) as AR($ p $) or AR of order $p$. The order $ p $ controls how many terms in the right-hand side of equation (2) will contribute to the estimation of $ x[t] $.

Moving Average Model - MA(q)

On the other hand, the MA(q) model relies on past error terms to estimate the current value $ x[t] $, and it is given by

$$ x[t] = \mu + \sum_{i=1}^{q} \theta[i] \epsilon[t - i] + \epsilon[t], \qquad (3) $$

where $ \mu $ is the mean of the time series (all observations up to $ t - 1 $), $ \theta[1], \ldots, \theta[q] $ are the parameters of the model, and $ \epsilon[t], \epsilon[t-1], \ldots, \epsilon[t-q] $ are white noise error terms. Because the error terms are white noise, no linearity is involved in the MA(q) model as in the AR(p) model. The parameter $ q $ is the order of the MA(q) model and determines how many terms the value $ x[t] $ will depend on.

Autoregressive-moving-average - ARMA(p, q)

In the case where we combine an AR(p) model with a MA(q), we obtain an autoregressive-moving average model, ARMA(p, q). In the ARMA(p, q) model, $ p $ is the autoregressive order, and $ q $ is the order of the moving average. ARMA(p, q) model is described by:

$$ x[t] = \epsilon[t] + \sum_{i=1}^{p} \phi[i] x[t-i] + \sum_{i=1}^{q} \theta[i] \epsilon[t-i]. \qquad (4) $$

Lag (L) and backshift (B) operators. In a time series context, the backshift operator acts on a time series element and returns the previous element as its name reveals. For instance, if $ x[t] = \begin{Bmatrix} x[1], x[2], \ldots, \end{Bmatrix} $ is a time series then $ Bx[t] = x[t-1] $ for each $ t > 1 $. The lag operator $ L $ acts in the same way $ Lx[t] = x[t-1] $. Furthermore, both operators can be raised in integer powers, $ L^k x[t] = t[t-k] $.

Another way to write equation (4) is to use the lag operator, and thus $$ \Big(1 - \sum_{i=1}^{p} \phi[i] L^i \Big) x[t] =\Big(1 + \sum_{i=1}^{q} \theta[i] L^i \Big) \epsilon[t]. $$

Stationarity A wide-sense stationary time series has a constant mean and variance (autocovariance) over time. For instance, the passengers' data in Figure 1 are non-stationary since an upward trend indicates that the mean increases over time. However, because the variance does not change, we will call that time series non-stationary in the sense of mean. You can You can find more details about stationarity here and in [1].
Differencing The time series in Figure 1 are non-stationary in the sense of mean (see Stationarity). One way to eliminate the non-stationarity is to apply a differencing transform, $ x'[t] = x[t] - x[t-1] $ (for instance, in Python, we could use the diff() function to apply the differencing transform on the original time series.

Autoregressive Integrated Moving Average - ARIMA(p, d, q)

ARIMA(p, q, d) is a generalzation of ARMA(p, q) model. ARIMA can be seen as an improvement of ARMA for time series that show non-stationarity in the sense of mean. The integrated part of the ARIMA model corresponds to the differencing of the time series observations. Differencing non-stationary time series can cancel the non-stationarity (in many time series applications, one has to apply a differencing transformation on the data to remove the non-stationarity [5]).

$$ x[t] - \alpha[1] x[t-1] - \cdots - \alpha[p] x[t-p] = \epsilon[t] + \theta[1]\epsilon[t-1] + \cdots + \theta[q] \epsilon[t-q], \qquad (5) $$

and using the lag operator, equation (5) recast

$$ \Big(1 - \sum_{i=1}^{p} \alpha[i] L^i \Big) x[t] = \Big( 1 + \sum_{i=1}^{q} \theta[i] L^i \Big) \epsilon[t]. $$

The parameters of the autoregressive part are $ \alpha[i] $ and of the moving average are $ \theta[i] $. $ \epsilon[t] $ are error i.i.d variables (sampled from a normal distribution with zero mean).

Examples

Two basic examples of ARIMA models are:

  • The random walk $ x[t] = x[t-1] + \epsilon[t] $ is an ARIMA(0, 1, 0),
  • and white noise $ x[t] = \epsilon[t] $ can be described as an ARIMA(0, 0, 0).

How to use ACF and PACF in time series analysis

In this section, we present several applications of the ACF and PACF. The most practical applications are the determination of the order of AR(p), MA(q), ARMA(p, q), and ARIMA(p, d, q) models.

Let’s begin by examining some basic examples of AR, MA, ARMA, and ARIMA models and see what conclusions we can draw. For simplicity’s sake, we first consider a signal generated from a normal distribution with zero mean, white noise, Figure 3A. When we estimate its ACF and PACF (Figure 3B and 3C), we notice that both are zero (remember that the first component always equals one and can be ignored). The absence of strong correlations (non-zero elements) indicates that our data come from a random process.

The second example demonstrates what information we can obtain from the ACF and PACF applied to an AR(1) model. Remember that an AR(1) model is an autoregressive model with order $ p = 1 $, meaning that the data shown in Figure 3D have been generated by $ x[t] = 0.6 * x[t-1] + \epsilon[t] $, where $ \epsilon[t] $ is white noise. First, let’s take a look at the ACF plot in Figure 3E. We notice four lags with strong correlations besides the zero lag component, meaning there is a structure in the data, and they are not completely random. Moreover, we see that the non-significant components (lags $ k > 1 $) follow a geometric decay. The PACF plot in panel 3F of Figure 3 has only one strong correlation at lag $ k = 1 $, verifying that the data come from an AR(1) model.

Figure 3. Estimation of ACF and PACF for three models. Each row shows a white noise, an AR(1), and a MA(1) raw data, the ACF, and the PACF. The blue-shaded area indicates the confidence interval cone ($ 95 $% confidence).

Let’s look now into a moving average model of order $ p = 1 $. In this case, the data shown in Figure 3G are described by the equation $ x[t] = 10 + 0.7 \epsilon[t-1] + \epsilon[t] $, which is MA(1) model. By examining the ACF plot in Figure 3H, we see strong correlations besides lag $ k = 0 $, which means that the data come from a process that is not completely random. In the PACF plot in Figure 3I, several lag components have strong correlations, and the PACF decays geometrically.

AThe final example regards a periodic time series with period $ T $. Figure 3J shows a sinusoidal signal $ g(t) = \sin(2 \pi t \frac{1}{T}) + \epsilon $ with additive white noise, $ \epsilon $, and $ T = \frac{1}{10} $. Because there are several components with strong correlations in the ACF and PACF plots, we know there is some structure in the data. The ACF plot in Figure 3K reflects the periodicity of the time series. We can infer that the signal’s frequency is $ f = 10 $ (where an entire cycle has been completed). Moreover, the lag component on the frequency ($ k = 10 $) is the strongest in the graph. Therefore, if we needed to know the frequency of the raw data without knowing the model, we could infer the period by looking into the ACF plot.

A few remarks on ACF and PACF plots

Let’s now draw some conclusions and give some remarks regarding the ACF and PACF and how to use them to identify an underlying model in raw data.

  • When a time series (or a signal) contains a moving average term (MA), we can determine the exact order of the MA by counting the components with strong correlations in an ACF plot. That’s true even when the underlying model is a high-order MA.
  • There is an autoregressive term (AR) in the raw data when the PACF plot has strong correlations up to some lag $ k > 0 $. The number of those elements determines the order $ p $ of the AR($ p $) model.
  • When a strong positive correlation exists and the PACF oscillates to zero, then there is a moving average, MA, term. The same holds when the zero lag is negative, and the PACF decays geometrically to zero.
  • Another case is when the PACF has strong correlations up to a lag $ k $, then decays geometrically to zero. The data can be modeled in that case by an ARMA(p, q) model.

Why do we need models like AR(p), MA(q), and others ?

So far, we have seen the ACF and PACF and how to estimate them given a time series. Moreover, we have seen how to use the ACF and PACF plots in determining the parameters of models such as AR(p) or MA(q). However, there is one question we still need to answer. Why do we need models like AR(p) in the first place? The answer is for describing raw data with a mathematical model that will allow us to make predictions (forecasting) of future values of our system.

Let’s be more specific. Assume that we obtain some raw data (observations) like the ones in Figure 1 showing the number of airport passengers per month for the years $ 1949 - 1960 $. Suppose we would like to know the number of passengers in the next month or in two months. In other words, we would like to predict the number of passengers in the future using known historical (past) observations.

One way to predict future values would be to assume that the number of passengers will keep growing following the current trend. However, that would need to be more accurate since we do not have a model for the underlying processes that describe our observations. A solution to that problem would be to apply the analysis we have already used. First, we would estimate the ACF and PACf and visualize the results. From ACF and PACF plots, we would find out the type of model (AR(p), MA(q), or other) that best fits our observations. Once we know that our observations follow a, let’s assume, AR(p) model with order $ p $, we can use that model to make predictions. More precisely, we could use equation (2) to fit the data and then use the fitted equation to make predictions for future values. Below, we give a Python code demonstrating how we can make predictions using the statsmodels module.

First, let’s create the data set, which follows an AR(1) model. For that reason, we will use the model in Figure 2D. The equation that describes the dynamics is $ x[t] = 0.6 * x[t-1] + \epsilon[t] $ (see the section about the AR(p) model). In a real-life situation, we won’t create the data set; instead, we will have to obtain them somehow, for instance, collect them by ourselves.

In the first code snippet, we show how to build the data set from scratch.

import numpy as np
import matplotlib.pylab as plt

from statsmodels.tsa.ar_model import AutoReg

np.random.seed(3)	# fix the RNG seed for reproducibility

# Create raw data using an AR(1) model
N = 1000 	# total number of observations
x = [0.5]	# initial value
for i in range(N):
    x.append(0.6 * x[i-1] + np.random.normal(0, 1))

The next step is to split the raw data into two separate sets. One for training (fitting) the parameters of our AR model and one for testing the fitted model. The training data set is usually larger than the testing one. Therefore, we use $ 70 $% of the data for training and the remaining $ 30 $% for testing. Remember that we have already performed our analysis in Figures 2E and 2F, where we estimated the ACF and PACF. Thus, we know that the underlying process for those observations is an AR(1), and we need three lags to predict the future.

# Split the original data set into train/test data sets
K = int(N * 0.7)   # size of training data set
train_data = x[:K]
test_data = x[K:]

# Fit the AR model using 3 lags (see Figures 2D, E, F)
# We use the same AR(1) model. 
ARmodel = AutoReg(train_data, lags=3).fit()

# Print a summary of the fitting process
print(ARmodel.summary())

Finally, we use the method predict of the class AutoReg to predict five steps into the future (the horizon is five). As we see in Figure 4, although the prediction is not perfect, it captures the main pattern.

horizon = 5	# How many values into the future we want to predict
prediction = ARmodel.predict(start=K, end=(K + horizon), dynamic=False)

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(prediction, 'b', label="prediction")
ax.plot(test_data[:horizon], 'k', label="target")
plt.plot()
Figure 4. Prediction of an AR(1) process using *statsmodels* `AutoReg`. The black curve indicates actual observations and the red one is the predictions.

Summary

In this post, we defined the autocorrelation and the partial autocorrelation functions, ACF and PACF. We introduced the AR(p), MA(q), ARMA(p, q), and ARIMA(p, d, q) models, and we showed how one could use the ACF and PACF to determine the parameters p, q, and d. Moreover, we provided a few examples and Python code snippets on how to use the statsmodels acf and pacf functions. Finally, we give a simple example of using models such as AR(p) to make predictions for future values.

Cited as

@article{detorakis2022acfpacf,
  title   = "Autocorrelation functions for time series",
  author  = "Georgios Is. Detorakis",
  journal = "gdetor.github.io",
  year    = "2022",
  url     = "https://gdetor.github.io/posts/acf_pacf"
}

References

  1. J. Beran, Mathematical Foundations of Time Series Analysis A Concise Introduction, Springer, 2017.
  2. “Time series”, Wikipedia, Wikimedia Foundation, May 2 2022.
  3. “Autocorrelation”, Wikipedia, Wikimedia Foundation, May 2 2022.
  4. “Partial autocorrelation function”, Wikipedia, Wikimedia Foundation, May 2 2022.
  5. S. Wang, C. Li, and A. Lim, Why Are the ARIMA and SARIMA not Sufficient, arXiv:1904.07632, 2019.