내용을 읽기 전에 시계열 자료에 대한 개념이 헛깔린다면 아래 내용을 참조하기 바란다.

시계열 자료
시계열 자료의 종류(정상, 비정상 시계열)아래의 평균 변동이나 분산 변동 외에도 주기적으로 변동하는 계절변동이 존재할 수 있다. par(mfrow=c(2,2)) set.seed(42) df=data.frame(idx=1:150,value=rnorm(150,0,1)) plot(df,type=‘l’,main=‘Stationary’,bty=‘l’) set.seed(42) df=data.

📌이동평균 평활법(Moving Average Smoothing)

이동평균 평활법은 분석자료의 일부만을 산술평균한 값으로 시계열자료를 평활화 하는 분석방법이다.

이동평균 평활법은 중심이동평균과 단순이동평균으로 구분된다. 만약 N이 5, 시점 $t$에 대해서의 중심이동평균은 시점 $t$을 중심으로 좌우 5개인 $t-2$부터 $t+2$까지의 산술 평균을 의미한다. 단순이동평균은 $t$시점 까지의 산술평균을 의미하므로, $t-4$부터 $t$까지의 산술 평균을 의미한다.

만약 시계열 자료에 계절변동이 포함되어 있다면, 주기에 따른 파동은 제거가 될 수 있으며, 우연변동의 분산을 1/N으로 감소하게 된다.

🌈단순 이동평균 평활법(Simple Moving Average Smoothing)

단순 이동평균 평활법은 아래의 수식과 같이 요약된다. 평균을 내는 기간을 의미하는 N이 짧으면 짧을수록 시계열자료에서 튀는 값에 대한 평활화 정도가 적어지며, N이 길어지면 평활화 정도가 커지게 된다. 이는 이상치가 존재하여도 관측자료가 많으면 평균에 미치는 영향이 적은 것과 유사하다.

$$m_t=[y_t+y_{t-1}+\cdots + y_{t-N+1}]/N$$

library(forecast)
library(stats)
AirPassengers
plot(AirPassengers)
# 3점 이동평균
lines(stats::filter(
    AirPassengers,filter=rep(1/3,3),sides=1),col=2)
# 6점 이동평균
lines(stats::filter(
    AirPassengers,filter=rep(1/6,6),sides=1),col=3)
# 9점 이동평균
lines(stats::filter(
    AirPassengers,filter=rep(1/9,9),sides=1),col=4)

🌈이중 이동평균 평활법(Double Moving Average Smoothing)

이중 이동평균 평활법은 단순 이동평균이 추세를 보일 때 추가적으로 이를 평활화 하고자 할 때 적용하는 방법이다. 단순 이동평균의 결과를 다시 이동평균한 결과이므로, 단순이동평균 평활법에 추세가 남아있는 경우, 단기적 불규칙 변동을 제거하는데 활용된다.

$$m_t=[y_t+y_{t-1}+\cdots + y_{t-N+1}]/N$$

$$m^{(2)}_t=[m_t+m_{t-1}+\cdots+m_{t-N+1}]/N$$

$m^{(2)}_t$는 이중평균 평활법의 적용 결과

library(forecast)
library(stats)
plot(AirPassengers)
ff1=stats::filter(
    AirPassengers,filter=rep(1,3)/3,side=1)
lines(stats::filter(
    ff1,filter=rep(1,3)/3,sides=1),col=2)

🌈가중 이동평균 평활법(Weighted Moving Average Smoothing)

단순이동평균과 이중 이동평균은 시계열 자료 일부를 고려하여 분석하지만, 관측치에 대한 가중치는 모두 동일한 값으로 적용한다. 실제 이중 이동평균의 산정과정에서 적용되는 가중치는 중간의 관측값이 최근의 관측값보다 큰 가중치로 적용된다.

$$m^{(w)}_t=[w_t y_t+w_{t-1}y_{t-1}+ \cdots + w_{t-N+1}y_{t-N+1}]/N$$

$$(w_t+w_{t-1}+\cdots+w_{t-N+1})=1$$

library(forecast)
library(stats)
plot(AirPassengers)
# t-1시점에 0.4, t-2시점에 0.3 t-3시점에 0.2 t-4시점에 0.1 가중치를 부여
lines(stats::filter(
    AirPassengers,(4:1)*.1,sides=1),col=2)

📌적용결과 확인하기

이동평균 평활법은 추세변동이나 계절변동을 포함하는 경우에도 이를 고려하여 분석이 가능한 모델로 개발되었다고한다. 해당 특징을 AirPassengers 자료로 확인해보자.

AirPassengers 자료의 경우에는 뒤로갈수록 자료의 분산이 커지므로 BoxCox변환을 통해 이동평균 적용에 대한 오차를 알아보도록하자. BoxCox에 대해 궁금하면 아래 링크를 참조하기 바란다.

시계열 개념과 변환
시계열 개요시계열 분석은 정상성 만족을 가정한다. 정상성은 평균과 분산이 시간에 따라 일정한 성질을 의미하는데, 자료 패턴이 시간에 따라 변화하지 않음을 의미한다. 만약 비정상 시계열 자료의 경우에는 다양한 방식으로 정상화하여 분석을 수행한다. 시계열 모형의 계략적인 구조는 아래와 같은데, 이는 적어도 자료가 특정한 추세로 변화하거나 인접자료와의 상관성이 없다는 가정하에 만들어졌다는 의미이다. $$y_
library(forecast)
library(stats)
data(AirPassengers)
boxcox_out=BoxCox(AirPassengers,BoxCox.lambda(AirPassengers))

o1=stats::filter(boxcox_out,filter=rep(1/3,3),sides=1)
o2=stats::filter(boxcox_out,filter=rep(1/6,6),sides=1)
o3=stats::filter(boxcox_out,filter=rep(1/12,12),sides=1)
o4=stats::filter(o1,filter=rep(1,3)/3,sides=1)
o5=stats::filter(boxcox_out,(4:1)*.1,sides=1)

idx=complete.cases(o3)
{
  par(mfrow=c(2,3))
  plot(o1[idx]-boxcox_out[idx],type='l',ylim=c(-.1,.1))
  plot(o2[idx]-boxcox_out[idx],type='l',ylim=c(-.1,.1))
  plot(o3[idx]-boxcox_out[idx],type='l',ylim=c(-.1,.1))
  plot(o4[idx]-boxcox_out[idx],type='l',ylim=c(-.1,.1))
  plot(o5[idx]-boxcox_out[idx],type='l',ylim=c(-.1,.1))
}

아래 그림은 BoxCox변환한 AirPassengers 자료의 오차를 시각화한 것이다.

BoxCox 역변환을 통해 자료를 원래의 스케일로 변환한 후 계산한 오차이다.

{
  par(mfrow=c(2,3))
  plot(InvBoxCox(o1,
    BoxCox.lambda(AirPassengers))[idx]-AirPassengers[idx],
    type='l',ylim=c(-100,100))
  plot(InvBoxCox(o2,
    BoxCox.lambda(AirPassengers))[idx]-AirPassengers[idx],
    type='l',ylim=c(-100,100))
  plot(InvBoxCox(o3,
    BoxCox.lambda(AirPassengers))[idx]-AirPassengers[idx],
    type='l',ylim=c(-100,100))
  plot(InvBoxCox(o4,
    BoxCox.lambda(AirPassengers))[idx]-AirPassengers[idx],
    type='l',ylim=c(-100,100))
  plot(InvBoxCox(o5,
    BoxCox.lambda(AirPassengers))[idx]-AirPassengers[idx],
    type='l',ylim=c(-100,100))
}

📌코드 참고

library(forecast)
library(stats)

stats::filter(
    AirPassengers,filter=rep(1,3)/3,side=1)
ma(AirPassengers, order=3, centre=F) #centre가 TRUE이면 중심이동평균