R을 이용한 시계열 분석 절차 및 방법


13

앞으로 6 개월 동안 원자재 (석유, 알루미늄, 주석 등)의 가격을 예측하려는 소규모 프로젝트를 진행하고 있습니다. 예측할 12 가지 변수가 있으며 2008 년 4 월-2013 년 5 월의 데이터가 있습니다.

예측은 어떻게해야합니까? 나는 다음을 수행했다.

  • 시계열 데이터 세트로 가져온 데이터
  • 모든 변수의 계절성은 추세에 따라 달라지는 경향이 있으므로 곱셈 모델을 사용하겠습니다.
  • 가산 모델로 변환하기 위해 변수 로그를 가져 왔습니다.
  • 각 변수에 대해 STL을 사용하여 데이터를 분해

Holt Winters 지수 평활, ARIMA 및 신경망을 사용하여 예측할 계획입니다. 나는 데이터를 훈련과 테스트 (80, 20)로 나누었다. MAE, MPE, MAPE 및 MASE가 적은 모델을 선택할 계획입니다.

내가 제대로하고 있습니까?

또한 ARIMA 또는 신경망으로 전달하기 전에 데이터를 부드럽게해야합니까? 그렇다면 무엇을 사용합니까? 데이터에는 계절 성과 추세가 모두 표시됩니다.

편집하다:

시계열도 및 데이터 첨부 여기에 이미지 설명을 입력하십시오

Year  <- c(2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2008, 2009, 2009, 
           2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2009, 2010, 
           2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 
           2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 2011, 
           2011, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 
           2012, 2012, 2013, 2013)
Month <- c(4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 
           12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 
           8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2) 
Coil  <- c(44000, 44500, 42000, 45000, 42500, 41000, 39000, 35000, 34000, 
           29700, 29700, 29000, 30000, 30000, 31000, 31000, 33500, 33500, 
           33000, 31500, 34000, 35000, 35000, 36000, 38500, 38500, 35500, 
           33500, 34500, 36000, 35500, 34500, 35500, 38500, 44500, 40700, 
           40500, 39100, 39100, 39100, 38600, 39500, 39500, 38500, 39500, 
           40000, 40000, 40500, 41000, 41000, 41000, 40500, 40000, 39300, 
           39300, 39300, 39300, 39300, 39800)
coil <- data.frame(Year = Year, Month = Month, Coil = Coil)

편집 2 : 하나의 질문, 내 데이터에 계절이나 추세가 있는지 알려주십시오. 또한 그것들을 식별하는 방법에 대한 몇 가지 팁을 알려주십시오. 여기에 이미지 설명을 입력하십시오 여기에 이미지 설명을 입력하십시오


2
다양한 유형의 금속 (스틸 A, 스틸 B, 스틸 C 등)과 같은 상품 그룹을 예측하려는 경우 공적분이 있는지 테스트 할 가치가 있습니다. 예를 들어 다음과 같습니다. 철강 가격이 함께 움직입니까? . 이것은 일 변량 방법보다 6 개월 (중 / 장기) 예측이 더 좋을지 모르지만 실제로는 어려운 게임입니다. ;-)
Graeme Walsh

1
@GraemeWalsh가 지적했듯이 일 변량 추세 외삽 법은 이러한 유형의 데이터에 적합하지 않을 수 있습니다. 문헌에는 탐구 할 가치가있는 유가, 철강 가격을 예측하는 방법이 잘 확립되어 있습니다.
예측 자

1
새 수정 사항을 별도의 질문으로 게시 할 수 있습니까? 이미 답변을 수락 했으므로 새 질문에주의를 기울이지 않을 수 있습니다. 데이터를 눈으로 볼 때 트렌드 나 계절 패턴이 없다고 말할 수는 없습니다. 아래 게시물에서 언급했듯이 2009 년 이전의 하락 추세는 경기 침체와 같은 거시 경제 현상입니까?
예측 자

@ forecaster, @ GraemeWalsh : 감사합니다. ADF 테스트를 사용하여 공적분 법을 사용할 계획입니다.
Niranjan Sonachalam 2016 년

1
당신은 당신의 새로운 질문에 맥락을 제공했고 지금은 모순입니다. 따라서 2009 년 이전의 하락은 실제로 거시 경제 현상이었습니다. 이 경우 드리프트 또는 (arima (0,1,0) + drift
예측 자

답변:


21

이러한 모든 모델 (및 그 이상)을 지원하고 간단하게 맞추는 예측 패키지를 사용해야합니다 .

library(forecast)
x <- AirPassengers
mod_arima <- auto.arima(x, ic='aicc', stepwise=FALSE)
mod_exponential <- ets(x, ic='aicc', restrict=FALSE)
mod_neural <- nnetar(x, p=12, size=25)
mod_tbats <- tbats(x, ic='aicc', seasonal.periods=12)
par(mfrow=c(4, 1))
plot(forecast(mod_arima, 12), include=36)
plot(forecast(mod_exponential, 12), include=36)
plot(forecast(mod_neural, 12), include=36)
plot(forecast(mod_tbats, 12), include=36)

모델을 맞추기 전에 데이터를 부드럽게하지 않는 것이 좋습니다. 모델은 본질적으로 데이터를 부드럽게하려고 시도하기 때문에 사전 평활은 문제를 복잡하게 만듭니다.

여기에 이미지 설명을 입력하십시오

새로운 데이터를 기반으로 편집 :

실제로 arima는이 교육 및 테스트 세트에서 선택할 수있는 최악의 모델 중 하나입니다.

데이터를 파일 호출에 저장 coil.csv하고 R에로드 한 다음 훈련 및 테스트 세트로 분할했습니다.

library(forecast)
dat <- read.csv('~/coil.csv')
x <- ts(dat$Coil, start=c(dat$Year[1], dat$Month[1]), frequency=12)
test_x <- window(x, start=c(2012, 3))
x <- window(x, end=c(2012, 2))

다음으로 나는 일련의 시계열 모델에 맞습니다.

models <- list(
  mod_arima = auto.arima(x, ic='aicc', stepwise=FALSE),
  mod_exp = ets(x, ic='aicc', restrict=FALSE),
  mod_neural = nnetar(x, p=12, size=25),
  mod_tbats = tbats(x, ic='aicc', seasonal.periods=12),
  mod_bats = bats(x, ic='aicc', seasonal.periods=12),
  mod_stl = stlm(x, s.window=12, ic='aicc', robust=TRUE, method='ets'),
  mod_sts = StructTS(x)
  )

그런 다음 몇 가지 예측을하고 테스트 세트와 비교했습니다. 항상 평평한 수평선을 예측하는 순진한 예측을 포함했습니다.

forecasts <- lapply(models, forecast, 12)
forecasts$naive <- naive(x, 12)
par(mfrow=c(4, 2))
for(f in forecasts){
  plot(f)
  lines(test_x, col='red')
}

여기에 이미지 설명을 입력하십시오

보시다시피, arima 모델은 추세가 잘못되었지만 "기본 구조 모델"의 모양과 비슷합니다.

마지막으로 테스트 세트에서 각 모델의 정확도를 측정했습니다.

acc <- lapply(forecasts, function(f){
  accuracy(f, test_x)[2,,drop=FALSE]
})
acc <- Reduce(rbind, acc)
row.names(acc) <- names(forecasts)
acc <- acc[order(acc[,'MASE']),]
round(acc, 2)
                ME    RMSE     MAE   MPE MAPE MASE ACF1 Theil's U
mod_sts     283.15  609.04  514.46  0.69 1.27 0.10 0.77      1.65
mod_bats     65.36  706.93  638.31  0.13 1.59 0.12 0.85      1.96
mod_tbats    65.22  706.92  638.32  0.13 1.59 0.12 0.85      1.96
mod_exp      25.00  706.52  641.67  0.03 1.60 0.12 0.85      1.96
naive        25.00  706.52  641.67  0.03 1.60 0.12 0.85      1.96
mod_neural   81.14  853.86  754.61  0.18 1.89 0.14 0.14      2.39
mod_arima   766.51  904.06  766.51  1.90 1.90 0.14 0.73      2.48
mod_stl    -208.74 1166.84 1005.81 -0.52 2.50 0.19 0.32      3.02

사용 된 측정 항목은 Hyndman, RJ 및 Athanasopoulos, G. (2014) "예측 : 원칙 및 실습" 에 설명되어 있으며 예측 패키지의 작성자이기도합니다. 나는 당신이 그들의 텍스트를 읽을 것을 강력히 추천합니다 : 그것은 온라인에서 무료로 구할 수 있습니다. 구조적 시계열은 MASE를 포함하여 여러 모델에서 가장 좋은 모델입니다. MASE는 모델 선택에 선호하는 메트릭입니다.

마지막 질문은이 테스트 세트에서 구조 모델이 운이 좋았습니까? 이를 평가하는 한 가지 방법은 훈련 세트 오류를 ​​보는 것입니다. 트레이닝 세트 오류는 테스트 세트 오류보다 신뢰성이 떨어지지 만 (과도하게 맞을 수 있기 때문에)이 경우 구조 모델은 여전히 ​​최상위에 있습니다.

acc <- lapply(forecasts, function(f){
  accuracy(f, test_x)[1,,drop=FALSE]
})
acc <- Reduce(rbind, acc)
row.names(acc) <- names(forecasts)
acc <- acc[order(acc[,'MASE']),]
round(acc, 2)
                ME    RMSE     MAE   MPE MAPE MASE  ACF1 Theil's U
mod_sts      -0.03    0.99    0.71  0.00 0.00 0.00  0.08        NA
mod_neural    3.00 1145.91  839.15 -0.09 2.25 0.16  0.00        NA
mod_exp     -82.74 1915.75 1359.87 -0.33 3.68 0.25  0.06        NA
naive       -86.96 1936.38 1386.96 -0.34 3.75 0.26  0.06        NA
mod_arima  -180.32 1889.56 1393.94 -0.74 3.79 0.26  0.09        NA
mod_stl     -38.12 2158.25 1471.63 -0.22 4.00 0.28 -0.09        NA
mod_bats     57.07 2184.16 1525.28  0.00 4.07 0.29 -0.03        NA
mod_tbats    62.30 2203.54 1531.48  0.01 4.08 0.29 -0.03        NA

(신경망 과적 합, 훈련 세트에서 우수하고 테스트 세트에서 저조한 성능을 나타냄)

마지막으로, 2008-2009 년 / 2010 년 테스트, 2008-2010 년 / 2011 년 테스트, 2008-2011 년 / 2012 년 테스트, 훈련을 통해 이러한 모델을 모두 교차 검증하는 것이 좋습니다. 2008-2012 / 2013 년 테스트 및 이러한 모든 기간의 평균 오류입니다. 그 길을 가고 싶다면 github에서 교차 검증 시계열 모델을위한 부분적으로 완전한 패키지 가 있습니다. 나는 당신이 시도하고 피드백 / 풀 요청을 해주길 바랍니다 :

devtools::install_github('zachmayer/cv.ts')
library(cv.ts)

편집 2 : 내 자신의 패키지를 사용하는 방법을 기억하는지 보자!

우선, github에서 패키지를 설치하고로드하십시오 (위 참조). 그런 다음 전체 모델을 사용하여 일부 모델을 교차 검증하십시오.

library(cv.ts)
x <- ts(dat$Coil, start=c(dat$Year[1], dat$Month[1]), frequency=12)
ctrl <- tseriesControl(stepSize=1, maxHorizon=12, minObs=36, fixedWindow=TRUE)
models <- list()

models$arima = cv.ts(
  x, auto.arimaForecast, tsControl=ctrl,
  ic='aicc', stepwise=FALSE)

models$exp = cv.ts(
  x, etsForecast, tsControl=ctrl,
  ic='aicc', restrict=FALSE)

models$neural = cv.ts(
  x, nnetarForecast, tsControl=ctrl,
  nn_p=6, size=5)

models$tbats = cv.ts(
  x, tbatsForecast, tsControl=ctrl,
  seasonal.periods=12)

models$bats = cv.ts(
  x, batsForecast, tsControl=ctrl,
  seasonal.periods=12)

models$stl = cv.ts(
  x, stl.Forecast, tsControl=ctrl,
  s.window=12, ic='aicc', robust=TRUE, method='ets')

models$sts = cv.ts(x, stsForecast, tsControl=ctrl)

models$naive = cv.ts(x, naiveForecast, tsControl=ctrl)

models$theta = cv.ts(x, thetaForecast, tsControl=ctrl)

(과도하게 맞지 않도록 신경망 모델의 유연성을 줄였습니다)

모델에 적합하면 MAPE로 비교할 수 있습니다 (cv.ts는 아직 MASE를 지원하지 않습니다).

res_overall <- lapply(models, function(x) x$results[13,-1])
res_overall <- Reduce(rbind, res_overall)
row.names(res_overall) <- names(models)
res_overall <- res_overall[order(res_overall[,'MAPE']),]
round(res_overall, 2)
                 ME    RMSE     MAE   MPE MAPE
naive     91.40 1126.83  961.18  0.19 2.40
ets       91.56 1127.09  961.35  0.19 2.40
stl     -114.59 1661.73 1332.73 -0.29 3.36
neural     5.26 1979.83 1521.83  0.00 3.83
bats     294.01 2087.99 1725.14  0.70 4.32
sts     -698.90 3680.71 1901.78 -1.81 4.77
arima  -1687.27 2750.49 2199.53 -4.23 5.53
tbats   -476.67 2761.44 2428.34 -1.23 6.10

아야. 우리의 구조적 예측은 운이 좋았던 것 같습니다. 장기적으로 순진한 예측은 12 개월 동안 평균적으로 최상의 예측을합니다 (arima 모델은 여전히 ​​최악의 모델 중 하나임). 12 가지 예측 지평 각각에서 모델을 비교하고 이들 중 어느 것도 순진한 모델을 능가하는지 확인하십시오.

library(reshape2)
library(ggplot2)
res <- lapply(models, function(x) x$results$MAPE[1:12])
res <- data.frame(do.call(cbind, res))
res$horizon <- 1:nrow(res)
res <- melt(res, id.var='horizon', variable.name='model', value.name='MAPE')
res$model <- factor(res$model, levels=row.names(res_overall))
ggplot(res, aes(x=horizon, y=MAPE, col=model)) +
  geom_line(size=2) + theme_bw() +
  theme(legend.position="top") +
  scale_color_manual(values=c(
    "#1f78b4", "#ff7f00", "#33a02c", "#6a3d9a",
    "#e31a1c", "#b15928", "#a6cee3", "#fdbf6f",
    "#b2df8a")
    )

모델 비교

즉, 지수 평활 모형은 항상 순진 모형을 선택합니다 (주황색 선과 파란색 선이 100 % 겹칩니다). 다시 말해, "다음 달의 코일 가격이 이번 달의 코일 가격과 동일 할 것"이라는 순진한 예측은 7 개의 매우 정교한 시계열 모델보다 더 정확합니다 (거의 모든 예측 범위에서). 코일 시장에 아직 알려지지 않은 비밀 정보가 없다면 순진한 코일 가격 예측을이기는 것은 매우 어려울 것 입니다.

누구나 듣고 싶어하는 대답은 아니지만 예측 정확도가 목표라면 가장 정확한 모델을 사용해야합니다. 순진한 모델을 사용하십시오.


이 모델들의 차이점을 살펴 보는 것이 흥미 롭습니다. NNAR은 특히 다르게 보입니다. 이것이 유명한 데이터 세트 (및 역사적으로 오래된 것으로 생각)를 감안할 때, 어느 모델이 옳고 & 하나의 모델 유형이 성능이 우수한지 알고 있습니까? (Nb, 나는 TS에 대해 상대적으로 거의 알지 못한다.)
gung-Reinstate Monica

@gung이를 수행하는 가장 좋은 방법은 홀드 아웃 세트를 분리하고 모델을 테스트하는 것입니다. 최상의 단기 예측을하는 모델이 장기 예측을 가장 잘하는 모델이 아닐 수도 있습니다 ..
Zach

고맙지 만 위의 데이터 세트에 대한 좋은 예측을 얻지 못했습니다 (여기에서 중요한 단계가 빠져 있다고 생각합니다). 내가 뭔가 빠졌는지 알려주세요
Niranjan Sonachalam

@Niranjan 당신은 당신이 좋은 예측을 얻지 못했다고 어떻게 결론을 내릴 수 있습니까?
예측 자

@forecaster : 여기에서 확인하시기 바랍니다 pbrd.co/1DRPRsq을 . 예측이 처음입니다. 특정 정보가 필요한 경우 알려주십시오. Arima 모델로 시도했습니다.
Niranjan Sonachalam

12

당신이 취한 접근법은 합리적입니다. 당신이 예측에 익숙하지 않다면 다음과 같은 책을 추천합니다.

  1. Makridakis, Wheelright 및 Hyndman의 예측 방법 및 응용
  2. 예측 : Hyndman과 Athanasopoulos의 원칙과 실천 .

첫 번째 책은 내가 강력히 추천하는 고전입니다. 두 번째 책은 R오픈 소스 소프트웨어 패키지 예측을 사용하여 예측 방법 및 적용 방법을 참조 할 수있는 오픈 소스 책입니다 . 두 책 모두 내가 사용한 방법에 대한 좋은 배경을 제공합니다. 당신이 예측에 대해 진지한 경우 , 실무자들이 매우 도움이 될 것이라고 예측할 때 엄청난 양의 연구를 모은 암스트롱 의 예측 원칙을 추천 합니다.

코일에 대한 구체적인 예를 들어, 대부분의 교과서에서 종종 무시하는 예측 가능성 개념을 생각 나게 합니다 . 시리즈와 같은 일부 시리즈는 추세 나 계절적 패턴을 나타내지 않거나 체계적인 변형을 나타내지 않으므로 패턴이 적기 때문에 예측할 수 없습니다. 이 경우 시리즈를 예측하기 어려운 것으로 분류합니다. 추정 방법에 감행하기 전에, 데이터를보고 질문을 것입니다,이 특정의 예에서와 같은 간단한 외삽? 내 시리즈 forecastable입니다 랜덤 워크의 예측의 마지막 값을 사용하여 예측이 가장 정확한 것으로 밝혀졌다 .

신경망에 대한 또 다른 의견 : 신경망은 경험적 경쟁 에서 실패하는 것으로 악명 높다 . 시계열 예측 작업에 신경망을 사용하기 전에 시계열에 대한 전통적인 통계 방법을 시도합니다.

에서 데이터를 모델링하려고했지만 R's forecast package의견이 자명 한 설명이되기를 바랍니다.

coil <- c(44000, 44500, 42000, 45000, 42500, 41000, 39000, 35000, 34000, 
          29700, 29700, 29000, 30000, 30000, 31000, 31000, 33500, 33500, 
          33000, 31500, 34000, 35000, 35000, 36000, 38500, 38500, 35500, 
          33500, 34500, 36000, 35500, 34500, 35500, 38500, 44500, 40700, 
          40500, 39100, 39100, 39100, 38600, 39500, 39500, 38500, 39500, 
          40000, 40000, 40500, 41000, 41000, 41000, 40500, 40000, 39300, 
          39300, 39300, 39300, 39300, 39800)


coilts <- ts(coil,start=c(2008,4),frequency=12)

library("forecast")

# Data for modeling
coilts.mod <- window(coilts,end = c(2012,3))

#Data for testing
coil.test <- window(coilts,start=c(2012,4))

# Model using multiple methods - arima, expo smooth, theta, random walk, structural time series

#arima
coil.arima <- forecast(auto.arima(coilts.mod),h=11)

#exponential smoothing
coil.ets <- forecast(ets(coilts.mod),h=11)

#theta
coil.tht <- thetaf(coilts.mod, h=11)

#random walk
coil.rwf <- rwf(coilts.mod, h=11)

#structts
coil.struc <- forecast(StructTS(coilts.mod),h=11)


##accuracy 

arm.acc <- accuracy(coil.arima,coil.test)
ets.acc <- accuracy(coil.ets,coil.test)
tht.acc <- accuracy(coil.tht,coil.test)
rwf.acc <- accuracy(coil.rwf,coil.test)
str.acc <- accuracy(coil.struc,coil.test)

보류 데이터에서 MAE를 사용하여 단기 예측 (1-12 개월)으로 ARIMA를 선택합니다. 장기적으로는 랜덤 보행 예측에 의존합니다. ARIMA는 드리프트 (0,1,0) + 드리프트가 있는 랜덤 워크 모델을 선택했는데, 이는 특히 단기적으로 이러한 유형의 문제에서 순수 랜덤 워크 모델보다 훨씬 더 정확한 경향이 있습니다. 아래 차트를 참조하십시오. 이것은 위의 코드에 표시된 정확도 기능을 기반으로합니다.

여기에 이미지 설명을 입력하십시오

귀하의 특정 질문에 대한 구체적인 답변 : ARIMA 또는 신경망으로 전달하기 전에 한 가지 질문도 있었습니까? 그렇다면 무엇을 사용합니까?

  • 아닙니다. 예측 방법은 모델에 맞게 데이터를 자연스럽게 처리합니다.

데이터에는 계절 성과 추세가 모두 표시됩니다.

  • 위의 데이터는 추세 나 계절성을 나타내지 않습니다. 데이터가 계절 성과 추세를 나타내는 것으로 판단되면 적절한 방법을 선택하십시오.

정확도 향상을위한 실용적인 팁 :

다양한 예측 방법을 결합하십시오 .- 유추 , 판단 예측 또는 기타 기술에 의한 예측 과 같은 비 외삽 방법을 사용 하여이를 통계적 방법과 결합하여 정확한 예측을 제공 할 수 있습니다. 결합의 이점에 대해서는이 기사 를 참조하십시오 . 위의 5 가지 방법을 결합하려고 시도했지만 개별 방법으로 예측이 정확하지 않았으므로 가능한 한 가지 이유는 개별 예측이 비슷하기 때문입니다. 통계 및 판단 예측과 같은 다양한 방법을 결합하면 예측 결합의 이점을 얻을 수 있습니다.

특이 치 감지 및 이해 : -실제 데이터는 특이 치로 채워집니다. 시계열에서 특이 치를 식별하고 적절하게 처리 합니다. 이 게시물을 읽는 것이 좋습니다. 코일 데이터를 살펴보면 2009 이전의 하락은 특이 치입니다.

편집하다

데이터는 몇 가지 유형의 거시 경제 추세를 따르는 것으로 보입니다. 내 생각에 2009 년 이전의 하락 추세는 2008-2009 년 사이에 나타난 경기 침체에 이어 2009 년 이후에 회복되기 시작합니다.이 경우, 나는 모두 외삽 법을 사용하지 않고 대신에 어떻게 건전한 이론에 의존 할 것입니다. 이러한 경제 동향 은 @GraemeWalsh가 참조한 것과 같은 방식으로 작동합니다 .

도움이 되었기를 바랍니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.