Процедура та методи аналізу часових журналів з використанням R


13

Я працюю над невеликим проектом, де ми намагаємось передбачити ціни на товари (нафта, алюміній, олово тощо) на наступні 6 місяців. У мене є 12 таких змінних, які можна передбачити, і у мене є дані з квітня 2008 р. По травень 2013 р.

Як слід робити прогнозування? Я зробив наступне:

  • Імпортовані дані як набір даних Timeseries
  • Сезонність всіх змінних, як правило, змінюється залежно від тенденції, тому я переходжу до мультиплікативної моделі.
  • Я взяв журнал змінної для перетворення в аддитивну модель
  • Для кожної змінної декомпоновані дані за допомогою STL

Я планую використовувати для прогнозу експоненціальне згладжування Хольта Вінтерса, 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)

EDIT 2: Одне запитання, чи можете ви мені сказати, чи є в моїх даних сезонність чи тенденція? А також, будь ласка, дайте мені кілька порад, як їх визначити. введіть тут опис зображення введіть тут опис зображення


2
Якщо ви шукаєте спроби прогнозувати групи товарів, наприклад, різні види металу (сталь А, сталь В, сталь С тощо), то, можливо, варто перевірити наявність коінтеграції. Наприклад, щось подібне: чи рухаються ціни на сталь разом? . Це може забезпечити кращі (середньо / довгострокові) прогнози на 6 місяців, ніж універсальні методи, але це справді важка гра, у яку ви намагаєтеся грати. ;-)
Graeme Walsh

1
Як зазначає AS @GraemeWalsh, одноваріантна екстраполяція тренду може бути не ідеальною для даного типу даних. У літературі є добре усталені методи прогнозування цін на нафту, сталь, які, можливо, варто вивчити.
синоптик

1
Чи можете ви публікувати нові зміни як окреме запитання? Оскільки ви вже прийняли відповідь, нові запитання можуть не отримати потрібної уваги. З огляду на дані я можу сказати, що жоден з них не має тенденцій чи сезонних зразків. Як зазначалося в моєму дописі нижче, схоже, що тенденція до зниження до 2009 року є макроекономічним явищем, як рецесія?
синоптик

@ forecaster, @ GraemeWalsh: Дякую. Я планую використовувати метод коінтеграції, використовуючи тести ADF.
Ніранджан Соначалам

1
Ви вказали контекст у своєму новому запитанні, і це має сенс мати вже зараз. Тож падіння до 2009 року справді було макроекономічним явищем. У цьому випадку, будь ласка, використовуйте метод випадкової ходьби з дрейфом або (arima (0,1,0) + дрейф
прогноз

Відповіді:


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)

Я б радив не згладжувати дані до встановлення вашої моделі. Ваша модель по суті буде намагатися згладити дані, тому попереднє згладжування просто ускладнює речі.

введіть тут опис зображення

Редагувати на основі нових даних:

Насправді схоже, що аріма - одна з найгірших моделей, яку ви могли обрати для цього навчального та тестового набору.

Я зберег ваші дані у файловому виклику 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')
}

введіть тут опис зображення

Як бачите, модель аріма помиляється в тренді, але мені подобається зовнішній вигляд "базової структурної моделі"

Нарешті, я виміряв точність кожної моделі на тестовому наборі:

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, який є метрикою, яку я, як правило, віддаю перевагу для вибору моделі.

Останнє питання: чи пощастило структурній моделі на цьому тестовому наборі? Один із способів оцінити це - це дивитися на помилки набору тренувань. Помилки навчального набору менш надійні, ніж помилки тестового набору (тому що вони можуть бути надмірно придатними), але в цьому випадку структурна модель все ж виходить зверху:

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-місячного горизонту (модель аріма все ще є однією з найгірших моделей). Давайте порівняємо моделі в кожному з 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 - Відновіть Моніку

@gung Найкращим способом зробити це було б розділити набір талантів і протестувати модель. Зауважте, що модель, яка робить найкращі короткострокові прогнози, може бути не тією моделлю, яка робить найкращі довгострокові прогнози ....
Зак

Дякую велике, але я не отримую хороших прогнозів для вищенаведеного набору даних (я думаю, я пропускаю тут якийсь важливий крок). Чи можете ви, будь ласка, повідомте мене, якщо я чогось не пропускаю
Niranjan Sonachalam

@Niranjan Чи можете ви нам сказати / показати, як ви робите висновок, що не отримуєте хорошого прогнозу?
синоптик

@forecaster: Перевірте тут pbrd.co/1DRPRsq . Я новачок у прогнозуванні. Повідомте мене, якщо вам потрібна якась конкретна інформація. Я спробував з моделлю Аріма.
Ніранджан Соначалам

12

Підхід, який ви застосували, є розумним. Якщо ви новачок у прогнозуванні, то рекомендую наступні книги:

  1. Методи та програми прогнозування від Makridakis, Wheelright та Hyndman
  2. Прогнозування: Принципи та практика Гіндмана та Атанасопулоса.

Перша книга - це класика, яку я настійно рекомендую. Друга книга - це книга з відкритим кодом, до якої можна звернутися до методів прогнозування та як вона застосовується, використовуючи прогнозR програмного пакету з відкритим кодом . Обидві книги пропонують хороші знання щодо методів, які я використовував. Якщо ви серйозно ставитесь до прогнозування, то я б рекомендував " Принципи прогнозування " Армстронга - це збір величезної кількості досліджень для прогнозування, що практикуючі можуть вважати це дуже корисним.

Переходячи до вашого конкретного прикладу на котушці, це нагадує мені концепцію передбачуваності, яку більшість підручників часто ігнорують. Таких серій, як ваша серія, просто неможливо передбачити, оскільки вона є меншою, але вона не демонструє тенденцій, сезонних малюнків або систематичних змін. У такому випадку я б класифікував серію як менш прогнозовану. Перш ніж зайнятися методами екстраполяції, я би роздивився дані і задав питання, чи прогнозується моя серія? У цьому конкретному прикладі найпростішим виявилася проста екстраполяція, така як прогноз випадкового ходу, який використовує останнє значення прогнозу. .

Також один додатковий коментар щодо нейронної мережі: Нейронні мережі, як відомо, не вдається провести емпіричні змагання . Я б спробував традиційні статичні методи для часових рядів, перш ніж намагатися використовувати нейронні мережі для завдань прогнозування часових рядів.

Я спробував моделювати ваші дані 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)

Використовуючи МАЕ на даних про затримку, я вибрав би ARIMA для короткотермінового прогнозу (1 - 12 місяців). довгостроково я б покладався на прогноз випадкових прогулянок. Зверніть увагу, що ARIMA обрала випадкову модель прогулянки з дрейфом (0,1,0) + дрейфом, яка, як правило, є набагато точнішою, ніж чиста випадкова модель прогулянки в цьому типі проблем, особливо в короткий термін. Дивіться нижче графік. Це засновано на функції точності, як показано у наведеному вище коді.

введіть тут опис зображення

Конкретні відповіді на ваші конкретні запитання: Також одне питання у мене було, перш ніж переходити до ARIMA або нейронної мережі, чи слід згладжувати дані? Якщо так, використовуючи що?

  • Ні, методи прогнозування, природно, згладжують ваші дані відповідно до моделі.

Дані показують як сезонність, так і тенденцію.

  • Наведені вище дані не показують тенденцію чи сезонність. Якщо ви визначите, що дані виявляють сезонність та тенденцію, то виберіть відповідний метод.

Практичні поради щодо підвищення точності:

Поєднуйте різноманітні методи прогнозування: - Ви можете спробувати використовувати неекстраполяційні методи, такі як прогнозування за аналогією , судження прогнозування чи інші методи і комбінувати їх зі своїми статистичними методами, щоб дати точні прогнози. Дивіться цю статтю про переваги комбінування. Я спробував поєднати вищевказані 5 методів, але прогнозування не було точним, як окремі методи, одна можлива причина - індивідуальний прогноз схожий. Ви користуєтеся перевагами комбінування прогнозу, поєднуючи різні методи, такі як статистичні та оціночні прогнози.

Виявити та зрозуміти людей, які не переживають людей: - Дані реального світу заповнюються видатками. Визначте та належним чином поводьтеся з людьми, що переживають люди, у часових рядах. Рекомендую прочитати цю публікацію . Дивлячись на свої дані котушки, чи крапля до 2009 року - це більше?

Редагувати

Ці дані, мабуть, слідують певному типу макроекономічних тенденцій. Я гадаю, що тенденція до зменшення, що спостерігається до 2009 року, слідує за спадом економіки, який спостерігається у період з 2008 по 2009 рік, і починає набирати посаду 2009 року. Якщо це так, то я б все разом уникав використання будь-яких методів екстраполяції, а замість цього покладався на обгрунтовану теорію про те, як ці економічні тенденції ведуть себе такими, на які посилається @GraemeWalsh.

Сподіваюсь, це допомагає

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.