Vad är autokorrelation?
   — Undersökning av en tidsserie

Ingemar Sjöström, SFK-StaM

juni 2025















Bakgrund

Det finns många behov och möjligheter att undersöka en tidsserie och autokorrelation är ett sätt. De flesta datorprogram har ett stort avsnitt med metoder för tidsserieanalys. Det är vanligt att beräkna korrelationskoefficienten mellan två olika variabler, t.ex. längd och vikt hos människor.
Autokorrelation beräknar i stället korrelationen mellan ett värde och föregående värde i samma tidsserie. (Därav ‘auto’ i betydelsen ‘själv’.)

Exempel. Antag att vi har en tidsserie (rad 1 nedan) och sedan kopierar denna men tar bort första värdet (rad 2) och på samma sätt skapas rad 3. (Man säger att raderna är laggade 1, 2, 3 osv steg.)

Data serien: 49.9 44.1 48.2 54.1 44.9 48.8 47.0 41.8 51.0 49.7
Lag 1 steg:  44.1 48.2 54.1 44.9 48.8 47.0 41.8 51.0 49.7 ____
Lag 2 steg:  48.2 54.1 44.9 48.8 47.0 41.8 51.0 49.7 _________
osv

Ibland förväntar man sig att det finns ett beroende mellan mätningar — lufttemperaturen kl 12:00 från en mätstation är antagligen ungefär samma som mätresultatet 24 timmar tidigare. Om man inte förväntar sig ett beroende kan det vara ett fel som måste analyseras vidare.


Simulering — tre olika exempel

    1. Helt slumpmässig serie

    2. Tidsserien med korrelation mellan senaste och näst senaste värdet

    3. Tidsserien med korrelation mellan senaste och femte senaste värdet


 1. Helt slumpmässig serie

Här skapas en tidsserie med initialt 1000 normalfördelade värden N(50, 4.5). Det finns ingen trend eller inget beroende mellan mätdata. Kodraderna skapar tre olika diagram för att belysa tidsserien.

library(ggplot2)      # Bibliotek för att rita grafer.
library(patchwork)    # Bibliotek för att placera grafer.
library(forecast)     # Bibliotek för att göra graf för pacf.
my    <- 50           # Processens medelvärde
sigma <- 4.5          # Processens sigma.
antal <- 1000         # Antal tidsdata

randomData <- rnorm(antal, my, sigma)

rubrik <- paste0("Purely random data")
pacfplot1 <- ggPacf(randomData, main="") + annotate("text", x = 10, y = Inf,
                                            label = rubrik, vjust = 1.5, size = 3.5, colour = "blue" )

Xaxel     <- c(1:length(randomData))
slumpData <- data.frame(randomData, Xaxel)

tidplot1 <- ggplot(slumpData, aes(x = Xaxel, y = randomData)) + geom_line(color="red")
tidplot1 <- tidplot1 + labs(x = "Time", y = "Measurements")
tidplot1 <- tidplot1 + annotate("text", x = mean(Xaxel), y = Inf,
                              label = rubrik, vjust = 1.5, size = 3.5, colour = "blue" )

hist1 <- ggplot(slumpData, aes(randomData)) + geom_histogram(bins=15, color='black', fill="yellow", alpha = 0.5, 
                                                            aes(y = after_stat(density)), position = 'identity')
hist1 <- hist1 + theme(axis.text.y = element_blank(), axis.title.y = element_blank())
hist1 <- hist1 + labs(x = "Mätvärden")
hist1 <- hist1 + annotate("text", x=mean(randomData), y=Inf, label=rubrik, vjust=1.5, size=3.5, colour="blue")
hist1

tidplot1 + pacfplot1           # Bara slumpmässig variation.

Kommentar till simulering 1. Eftersom den simulerade datamängden är helt slumpmässig förväntas inga konstigheter i diagrammen. Både histogrammet och tidsplotten (röd linje) ser ut som förväntat.
PACF-diagrammet skapas av ‘pacf’-kommandot (partial auto correlation function) och visar för varje ‘lag’ (tidsförskjutning) den partiell korrelationskoefficienten (upp t.o.m. lag 30). De två horisontella streckade linjerna anger att cirka 95 % av alla värden förväntas ligga inom dessa gränser om det inte finns någon korrelation. (Eftersom p = 0.05 och n = 30 förväntas 1.5 värden utanför gränserna.)



2. Tidsserien med korrelation mellan senaste och näst senaste värdet (k = 1)

Nedanstående uttryck visar hur det senaste värdet skapas från föregående värde plus en slumpkomponent.

\[ \begin{align} \Large Y(t) =\beta\cdot Y(t-k)+\epsilon(t) \phantom{tomt} |\beta|<1 \end{align} \]

Ju mindre β-koefficienten är desto mindre korrelation mellan mätvärdena.


Precis som föregånde exempel skapas tre diagram men denna gång finns det en korrelation med föregående värde, dvs k = 1.

my    <- 50           # Processens medelvärde
sigma <- 4.5          # Processens sigma.
antal <- 2000         # Antal tidsdata

k <- 1                # Tidsförskjutning i k steg.

startvarde <- rnorm(11, my, sigma) - my

error <- 5.1        # Sigma 'Error'-term: N(0, error)
beta  <- 0.6        # Koeffecient som länkar föregående värde till nästa.

nyaVarden <-c(startvarde)

for (i in 10:antal) {nyaVarden[i] <- beta * nyaVarden[i-k] + rnorm(1, 0, error) }

nyaVarden <- nyaVarden[15:antal]    # Tar bort de första värdena (start och insvängning)

rubrik <- paste0("Time series plot, lag ", k)
pacfplot2 <- ggPacf(nyaVarden, main="") + annotate("text", x = 10, y = Inf, 
                                           label = rubrik, vjust = 1.5, size = 3.5, colour = "blue" )

Xaxel <- c(1:length(nyaVarden))
minaData <- data.frame(nyaVarden, Xaxel)

tidplot2 <- ggplot(minaData, aes(x = Xaxel, y = nyaVarden+my)) + geom_line(color="red")
tidplot2 <- tidplot2 + labs(x = "Time", y = "Measurements")
tidplot2 <- tidplot2 + annotate("text", x = mean(Xaxel), y = Inf, 
                label = rubrik, vjust = 1.5, size = 3.5, colour = "blue" )

hist2 <- ggplot(minaData, aes(nyaVarden+my)) + geom_histogram(bins=15, color='black', fill="yellow", alpha = 0.5, 
                                                             aes(y = after_stat(density)), position = 'identity')
hist2 <- hist2 + theme(axis.text.y = element_blank(), axis.title.y = element_blank())
hist2 <- hist2 + labs(x = "Mätvärden")
hist2 <- hist2 + annotate("text", x = mean(nyaVarden+my), y=Inf, label=rubrik, vjust=1.5, size=3.5, colour="blue")
hist2

tidplot2 + pacfplot2           # Data med tidsförskjutning i k steg.

Kommentar till simulering 2. Den simulerade tidsserien innehåller nu en korrelation mellan ett datavärde och datavärdet ett steg innan. Trots detta visar varken histogrammet eller tidsserieplotten något oväntat. PACF-diagrammet däremot innehåller en tydlig korrelation vid lag 1 och motsvarar β-koefficienten i simuleringen.
Om inte detta är förväntat bör ytterligare analyser utföras för att hitta en förklaring.

(En korrelation vid lag 1 steg spelar en väldigt stor roll i processanalys och kallas ibland för en ‘Markov’-effekt men också en AR(1)-process där AR är en s.k. auto regressive model.)



3. Tidsserien med korrelation mellan senaste och femte senaste värdet (k = 5)

Denna simulering är exakt samma som föregående men här är k = 5, dvs det finns en korrelation mellan ett mätvärde och mätvärdet fem steg tidigare.

my    <- 50           # Processens medelvärde
sigma <- 4.5          # Processens sigma.
antal <- 2000         # Antal tidsdata

k <- 5                # Tidsförskjutning i k steg.

startvarde <- rnorm(11, my, sigma) - my

error <- 5.1        # Sigma 'Error'-term: N(0, error)
beta  <- 0.6        # Koeffecient som länkar föregående värde till nästa.

nyaVarden <-c(startvarde)

for (i in 10:antal) {nyaVarden[i] <- beta * nyaVarden[i-k] + rnorm(1, 0, error) }

nyaVarden <- nyaVarden[15:antal]    # Tar bort de första värdena (start och insvängning)

rubrik <- paste0("Time series plot, lag ", k)
pacfplot2 <- ggPacf(nyaVarden, main="") + annotate("text", x = 10, y = Inf, 
                                           label = rubrik, vjust=1.5, size=3.5, colour="blue")

Xaxel <- c(1:length(nyaVarden))
minaData <- data.frame(nyaVarden, Xaxel)

tidplot2 <- ggplot(minaData, aes(x = Xaxel, y = nyaVarden+my)) + geom_line(color="red")
tidplot2 <- tidplot2 + labs(x = "Time", y = "Measurements")
tidplot2 <- tidplot2 + annotate("text", x = mean(Xaxel), y = Inf, 
                label=rubrik, vjust=1.5, size=3.5, colour="blue" )

hist2 <- ggplot(minaData, aes(nyaVarden+my)) + geom_histogram(bins=15, color='black', fill="yellow", alpha = 0.5, 
                                                             aes(y = after_stat(density)), position = 'identity')
hist2 <- hist2 + theme(axis.text.y = element_blank(), axis.title.y = element_blank())
hist2 <- hist2 + labs(x = "Mätvärden")
hist2 <- hist2 + annotate("text", x = mean(nyaVarden+my), y=Inf, label=rubrik, vjust=1.5, size=3.5, colour="blue")
hist2

tidplot2 + pacfplot2           # Data med tidsförskjutning i k steg.

Kommentar till simulering 3. Den simulerade tidsserien innehåller nu en korrelation mellan ett datavärde och datavärdet fem steg innan. Trots detta visar varken histogrammet eller tidsserieplotten något oväntat. PACF-diagrammet däremot innehåller en tydlig korrelation vid lag 5 och motsvarar β-koefficienten i simuleringen.
Om inte detta är förväntat bör ytterligare analyser utföras för att hitta en förklaring.

(En av grundarna av ENBIS (Europen Network for Business and Industrial Statistics, enbis.org) Sören Bisgaard berättade vid en förläsning hur han arbetade med en process utan att hitta en rotorsak. Till sist när han gjorde en PACF-körning insåg han att vissa mekaniska länkar i transportmekanismen var felaktiga. Efter ett utbyte blev tidsserien som en slumpmässig process.)



Avslutningsvis. Vid analys av data ingår det att klämma och vrida på datamängden för att förstå dess hemligheter. Till detta behöver man ett lämpligt datorprogram och många av dem har har verktyg för tidsserieanalys och om man har datamängden preparerad tar kontrollen ovan bara några sekunder.

(Analyserna har gjorts med datorprogrammet ‘R’ och med det grafiska gränssnittet ‘R-studio’ och bägge är gratis tillgängliga på nätet. Se https://www.indstat.se och knappen [Statistikprogram - R] för installation.)

(Se https://www.indstat.se för många andra simuleringsövningar.)

(Se https://www.ing-stat.se/korskorr.html för simulering av s.k. cross correlation.)