앞으로 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 개의 매우 정교한 시계열 모델보다 더 정확합니다 (거의 모든 예측 범위에서). 코일 시장에 아직 알려지지 않은 비밀 정보가 없다면 순진한 코일 가격 예측을이기는 것은 매우 어려울 것 입니다.
누구나 듣고 싶어하는 대답은 아니지만 예측 정확도가 목표라면 가장 정확한 모델을 사용해야합니다. 순진한 모델을 사용하십시오.
답변
당신이 취한 접근법은 합리적입니다. 당신이 예측에 익숙하지 않다면 다음과 같은 책을 추천합니다.
- Makridakis, Wheelright 및 Hyndman의 예측 방법 및 응용
- 예측 : 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가 참조한 것과 같은 방식으로 작동합니다 .
도움이 되었기를 바랍니다