R kullanarak zaman analizi yöntemi ve yöntemleri


13

Önümüzdeki 6 ay boyunca emtia (Petrol, Alüminyum, Kalay, vb.) Fiyatlarını tahmin etmeye çalıştığımız küçük bir proje üzerinde çalışıyorum. Tahmin edeceğim 12 değişkenim var ve Nisan, 2008 - Mayıs 2013 tarihleri ​​arasında verilerim var.

Tahmin hakkında nasıl gitmeliyim? Aşağıdakileri yaptım:

  • Timeseries veri kümesi olarak içe aktarılan veriler
  • Tüm değişkenlerin mevsimsellik Trend'e göre değişme eğilimindedir, bu yüzden çarpım modeline gidiyorum.
  • Katkı modeline dönüştürmek için değişkenin günlüğünü aldım
  • Her değişken için verileri STL kullanarak ayrıştırdı

Tahmin etmek için Holt Winters üstel yumuşatma, ARIMA ve sinir ağı kullanmayı planlıyorum. Verileri eğitim ve test olarak böldüm (80, 20). Daha az MAE, MPE, MAPE ve MASE ile model seçmeyi planlıyoruz.

Doğru yapıyor muyum?

Ayrıca sahip olduğum bir soru, ARIMA veya sinir ağına geçmeden önce verileri düzeltmem gerekiyor muydu? Evet ise, ne kullanarak? Veriler hem Mevsimsellik hem de eğilimi göstermektedir.

DÜZENLE:

Zaman çizelgesi grafiğini ve verilerini ekleme resim açıklamasını buraya girin

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)

DÜZENLEME 2: Bir soru, lütfen verilerimin mevsimsellik veya eğilim olup olmadığını söyleyebilir misiniz? Ve ayrıca lütfen onları nasıl tanımlayacağımla ilgili bazı ipuçları verin. resim açıklamasını buraya girin resim açıklamasını buraya girin


2
Çeşitli metal türleri (çelik A, çelik B, çelik C, vb.) Gibi meta gruplarını tahmin etmeye çalışıyorsanız, eşbütünleşmenin varlığı için test etmeye değer olabilir. Örneğin, şöyle bir şey: Çelik fiyatları birlikte hareket ediyor mu? . Bu, tek değişkenli yöntemlerden daha iyi 6 aylık (orta / uzun vadeli) tahminler sağlayabilir, ancak bu gerçekten oynamaya çalıştığınız zor bir oyundur. ;-)
Graeme Walsh

1
AS @GraemeWalsh, bu tür veriler için tek değişkenli eğilim ekstrapolasyonunun ideal olmayabileceğini belirtiyor. Literatürde keşfedilmeye değer olabilecek petrol ve çelik fiyatlarının tahmininde köklü yöntemler bulunmaktadır.
tahminci

1
Yeni düzenlemeleri ayrı bir soru olarak gönderebilir misiniz? Bir cevabı zaten kabul ettiğiniz için yeni sorular ihtiyaç duyduğu ilgiyi görmeyebilir. Verilere göz gezdirmekten hiçbirinin eğilimleri veya mevsimsel kalıpları olmadığını söyleyebilirim. Aşağıdaki yazımda da belirtildiği gibi, 2009'dan önceki düşüş eğilimi durgunluk gibi bir makro ekonomik olay mı?
tahminci

@ tahminci, @ GraemeWalsh: Teşekkür ederim. ADF testlerini kullanarak eşbütünleşme yöntemini kullanmayı planlıyorum.
Niranjan Sonachalam

1
Yeni sorunuzda bağlam sağladınız ve şimdi mosre mantıklı. Bu nedenle, 2009'dan önceki düşüş aslında bazı makro ekonomik fenomenlerdi. Bu durumda, lütfen sürüklenme veya (arima (0,1,0) + sürüklenme ile rastgele yürüyüş yöntemi kullanın
tahminci

Yanıtlar:


21

Tüm bu modelleri (ve daha fazlasını) destekleyen ve bunları takmayı kolaylaştıran tahmin paketini kullanmalısınız :

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)

Modelinizi takmadan önce verileri düzeltmemenizi tavsiye ederim. Modeliniz doğal olarak verileri düzeltmeye çalışacaktır, bu nedenle ön düzeltme yalnızca işleri karmaşıklaştırır.

resim açıklamasını buraya girin

Yeni verilere göre düzenleme:

Aslında arima bu eğitim ve test seti için seçebileceğiniz en kötü modellerden biri gibi görünüyor.

Verilerinizi bir dosya görüşmesine kaydettim coil.csv, R'ye yükledim ve bir eğitim ve test kümesine böldüm:

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))

Sonra bir dizi zaman serisi modeline uyuyorum: arima, üstel yumuşatma, sinir ağı, tbats, yarasalar, mevsimsel ayrışma ve yapısal zaman serileri:

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)
  )

Sonra bazı tahminler yaptım ve test setiyle karşılaştırdım. Her zaman düz, yatay bir çizgi öngören saf bir tahmin ekledim:

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')
}

resim açıklamasını buraya girin

Gördüğünüz gibi, arima modeli eğilimi yanlış anlıyor, ancak "Temel Yapısal Model"

Son olarak, her modelin doğruluğunu test setinde ölçtüm:

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

Kullanılan metrikler , aynı zamanda tahmin paketinin yazarı olan Hyndman, RJ ve Athanasopoulos, G. (2014) "Tahmin: ilkeler ve uygulama" da açıklanmaktadır. Metinlerini okumanızı şiddetle tavsiye ederim: çevrimiçi olarak ücretsiz olarak kullanılabilir. Yapısal zaman serileri, model seçimi için tercih ettiğim metrik olan MASE de dahil olmak üzere birçok metrik için en iyi modeldir.

Son soru şudur: Yapısal model bu test setinde şanslı mıydı? Bunu değerlendirmenin bir yolu eğitim seti hatalarına bakmaktır. Eğitim seti hataları, test seti hatalarından daha az güvenilirdir (çünkü fazla uyum sağlayabilirler), ancak bu durumda yapısal model hala en üstte ortaya çıkar:

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

(Sinir ağının fazla çalıştığını, eğitim setinde mükemmel ve test setinde kötü performans gösterdiğini unutmayın)

Son olarak, belki de 2008-2009 / 2010'da test, 2008-2010'da test / 2011'de test, 2008-2011'de eğitim / 2012'de test, eğitim ile tüm bu modellerin çapraz doğrulanması iyi bir fikir olacaktır. 2008-2012 / 2013'te test edildi ve bu zaman dilimlerinin tamamında hataların ortalaması alındı. Bu rotaya inmek isterseniz , github'da zaman serisi modellerini çapraz doğrulamak için kısmen denemeyi ve bana geri bildirim / çekme istekleri vermenizi istediğim bir paketim var:

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

Edit 2: Kendi paketimi nasıl kullanacağımı hatırlayıp hatırlamadığımı görelim!

Her şeyden önce, paketi github'dan yükleyin ve yükleyin (yukarıya bakın). Ardından bazı modelleri çapraz doğrulayın (tam veri kümesini kullanarak):

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)

(Sinir ağı modelinin esnekliğini azalttığımı, aşırı sığmasını önlemeye yardımcı olmaya çalıştığımı unutmayın)

Modelleri sığdırdıktan sonra, MAPE ile karşılaştırabiliriz (cv.ts henüz MASE'i desteklemez):

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

Ahh. Yapısal tahminlerimizin şanslı olduğu anlaşılıyor. Uzun vadede, naif tahmin, 12 aylık bir ufukta ortalaması alınan en iyi tahminleri yapar (arima modeli hala en kötü modellerden biridir). 12 tahmin ufkunun her birindeki modelleri karşılaştıralım ve bunlardan herhangi birinin saf modeli geçip geçmediğini görelim:

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")
    )

model karşılaştırma

Açıkça, üstel yumuşatma modeli her zaman saf modeli seçmektedir (turuncu çizgi ve mavi çizgi% 100 örtüşüyor). Diğer bir deyişle, "gelecek ayın rulo fiyatlarının naif tahmini" bu ayın rulo fiyatlarıyla aynı olacak "son derece sofistike zaman serisi modellerinden 7 daha doğru (hemen hemen her tahmin ufukta). Bobin piyasasının henüz bilmediği bazı gizli bilgilere sahip olmadığınız sürece, saf bobin fiyat tahminini yenmek son derece zor olacaktır .

Asla kimsenin duymak istediği cevap değildir, ancak tahmin doğruluğu hedefinizse, en doğru modeli kullanmalısınız. Saf modeli kullanın.


Bu modeller arasındaki farklılıklara bakmak ilginç. Özellikle NNAR farklı görünüyor. Bunun ünlü bir veri kümesi olduğu (ve tarihsel olarak eski, inanıyorum), hangisinin doğru olduğu ve bir model tipinin daha iyi performans gösterdiği biliniyor mu? (Not, TS hakkında nispeten az şey biliyorum.)
gung - Monica'yı eski

@gung Bunu yapmanın en iyi yolu bir dağıtım kümesini ayırmak ve modeli test etmektir. Kısa vadeli en iyi tahminleri yapan modelin, en iyi uzun vadeli tahminleri yapan model olmayabileceğini unutmayın ....
Zach

Çok teşekkürler, ama yukarıdaki veri seti için iyi tahminler almıyorum (burada önemli bir adım eksik olduğumu düşünüyorum). Bir şey eksik olup olmadığımı lütfen bana bildirir misin
Niranjan Sonachalam

@Niranjan Bize iyi tahmin alamadığınızı nasıl sonuçlandırdığınızı söyleyebilir / gösterebilir misiniz?
tahminci

@forecaster: Lütfen buradan kontrol edin pbrd.co/1DRPRsq . Tahminlerde yeniyim. Belirli bir bilgiye ihtiyacınız varsa bana bildirin. Arima modeliyle denedim.
Niranjan Sonachalam

12

Aldığınız yaklaşım makul. Tahmin konusunda yeniyseniz, aşağıdaki kitapları tavsiye ederim:

  1. Makridakis, Wheelright ve Hyndman tarafından tahmin yöntemleri ve uygulamaları
  2. Tahmin: Hyndman ve Athanasopoulos'un ilkeleri ve uygulamaları .

İlk kitap şiddetle tavsiye ettiğim bir klasik. İkinci kitap, tahmin yöntemleri ve Raçık kaynak yazılım paketi tahmini kullanılarak nasıl uygulandığını açıklayabileceğiniz açık kaynaklı bir kitaptır . Her iki kitap da kullandığım yöntemler hakkında iyi bir arka plan sağlıyor. Tahmin konusunda ciddiyseniz, o zaman bir uygulayıcının bunu çok yararlı bulabileceği tahmininde muazzam miktarda araştırma toplayan Armstrong tarafından Öngörme İlkeleri'ni öneriyorum .

Bobin konusundaki özel örneğinize gelince, bana çoğu ders kitabının genellikle görmezden geldiği bir öngörülebilirlik kavramını hatırlatıyor . Serileriniz gibi bazı seriler tahmin edilemez, çünkü eğilim veya mevsimsel patlamalar veya herhangi bir sistematik varyasyon göstermediğinden desen daha azdır. Bu durumda bir diziyi daha az tahmin edilebilir olarak sınıflandırırdım. Ekstrapolasyon yöntemlerine girmeden önce, verilere bakıp soruyu sorardım, benim serim tahmin edilebilir mi? Bu özel örnekte, tahminin son değerini kullanan rastgele yürüyüş tahmini gibi basit bir ekstrapolasyonun en doğru olduğu bulunmuştur. .

Ayrıca sinir ağı hakkında ek bir yorum: Nöral ağların ampirik yarışmalarda başarısız olduğu biliniyor . Sinir ağlarını zaman serisi tahmin görevleri için kullanmaya başlamadan önce zaman serisi için geleneksel istatistiksel yöntemleri denerdim.

Verilerinizi modellemeye çalıştım R's forecast package, umarım yorumlar kendi kendini açıklar.

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)

Bekletme verilerinde MAE kullanarak, kısa vadeli tahmin (1-12 ay) için ARIMA'yı seçerdim. uzun vadede rastgele yürüyüş tahminine güvenirim. ARIMA'nın , özellikle kısa vadede bu tür problemlerde saf rastgele yürüyüş modelinden çok daha doğru olma eğiliminde olan , sürüklenme (0,1,0) + sürüklenme ile rastgele bir yürüyüş modeli seçtiğini unutmayın . Aşağıdaki tabloya bakınız. Bu, yukarıdaki kodda gösterildiği gibi doğruluk işlevine dayanmaktadır.

resim açıklamasını buraya girin

Özel sorularınıza özel cevaplar: Bir sorum da ARIMA ya da nöral ağa geçmeden önce verileri düzeltmeliydim? Evet ise, ne kullanarak?

  • Hayır, Öngörme yöntemleri doğal olarak verilerinizi modele uyacak şekilde düzgünleştirir.

Veriler hem Mevsimsellik hem de eğilimi göstermektedir.

  • Yukarıdaki veriler eğilim veya mevsimsellik göstermemektedir. Verilerin mevsimsellik ve eğilim sergilediğini belirlerseniz, uygun bir yöntem seçin.

Doğruluğu artırmak için pratik ipuçları:

Çeşitli tahmin yöntemlerini birleştirin: - Analoji , yargı tahmini veya diğer tekniklerle tahmin etme gibi ekstrapolasyon dışı yöntemleri kullanmayı deneyebilir ve doğru tahminler sağlamak için bunları istatistiksel yöntemlerle birleştirebilirsiniz. Birleştirmenin yararları için bu makaleye bakın . Yukarıdaki 5 yöntemi birleştirmeyi denedim, ancak tahmin bireysel yöntemler olarak doğru değildi, olası bir neden, bireysel tahminin benzer olmasıdır. İstatistiksel ve yargısal tahminler gibi çeşitli yöntemleri birleştirdiğinizde tahmini birleştirmenin avantajlarından faydalanırsınız.

Aykırı Değerleri Algıla ve Anla: - Gerçek dünya verileri aykırı değerlerle doldurulur. Zaman serilerindeki aykırı değerleri tanımlayın ve uygun şekilde tedavi edin . Bu yazıyı okumanızı öneririz . Bobin verilerinize bakıldığında, 2009 öncesi düşüş bir aykırı değer midir ??

Düzenle

Veriler bir tür makro ekonomik eğilimleri takip ediyor gibi görünmektedir. Tahminim 2009'dan önce görülen düşüş eğilimi, 2008 - 2009 yılları arasında görülen ekonomideki çöküşü takip ediyor ve 2009 sonrası alımını yapmaya başlıyor. Eğer durum buysa, hep birlikte herhangi bir ekstrapolasyon yöntemi kullanmaktan kaçınır ve bunun yerine bu ekonomik eğilimler @GraemeWalsh'ın referans aldığı gibi davranmaktadır .

Bu yardımcı olur umarım

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.