R을 이용한 시계열 분석 절차 및 방법 c(2008, 2008, 2008, 2008, 2008,

앞으로 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 :
하나의 질문, 내 데이터에 계절이나 추세가 있는지 알려주십시오. 또한 그것들을 식별하는 방법에 대한 몇 가지 팁을 알려주십시오.
여기에 이미지 설명을 입력하십시오
여기에 이미지 설명을 입력하십시오



답변

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

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 개의 매우 정교한 시계열 모델보다 더 정확합니다 (거의 모든 예측 범위에서). 코일 시장에 아직 알려지지 않은 비밀 정보가 없다면 순진한 코일 가격 예측을이기는 것은 매우 어려울 것 입니다.

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


답변

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

  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가 참조한 것과 같은 방식으로 작동합니다 .

도움이 되었기를 바랍니다


답변