Previsión de datos de series de tiempo

Investigué un poco y estoy atascado en encontrar la solución. Tengo una serie de datos de tiempo, un dataframe muy básico, llamémoslo x :

 Date Used 11/1/2011 587 11/2/2011 578 11/3/2011 600 11/4/2011 599 11/5/2011 678 11/6/2011 555 11/7/2011 650 11/8/2011 700 11/9/2011 600 11/10/2011 550 11/11/2011 600 11/12/2011 610 11/13/2011 590 11/14/2011 595 11/15/2011 601 11/16/2011 700 11/17/2011 650 11/18/2011 620 11/19/2011 645 11/20/2011 650 11/21/2011 639 11/22/2011 620 11/23/2011 600 11/24/2011 550 11/25/2011 600 11/26/2011 610 11/27/2011 590 11/28/2011 595 11/29/2011 601 11/30/2011 700 12/1/2011 650 12/2/2011 620 12/3/2011 645 12/4/2011 650 12/5/2011 639 12/6/2011 620 12/7/2011 600 12/8/2011 550 12/9/2011 600 12/10/2011 610 12/11/2011 590 12/12/2011 595 12/13/2011 601 12/14/2011 700 12/15/2011 650 12/16/2011 620 12/17/2011 645 12/18/2011 650 12/19/2011 639 12/20/2011 620 12/21/2011 600 12/22/2011 550 12/23/2011 600 12/24/2011 610 12/25/2011 590 12/26/2011 750 12/27/2011 750 12/28/2011 666 12/29/2011 678 12/30/2011 800 12/31/2011 750 

Realmente aprecio cualquier ayuda con esto. Estoy trabajando con datos de series temporales y necesito poder crear pronósticos basados ​​en datos históricos.

  1. Primero traté de convertirlo a xts :

     x.xts <- xts(x$Used, x$Date) 
  2. Luego, convertí x.xts a series de tiempo regulares:

     x.ts <- as.ts(x.xts) 
  3. Pon los valores en ets :

     x.ets <- ets(x.ts) 
  4. Previsión realizada durante 10 períodos:

     x.fore <- forecast(x.ets, h=10) 
  5. x.fore es esto:

      Point Forecast Lo 80 Hi 80 Lo 95 Hi 95 87 932.9199 831.7766 1034.063 778.2346 1087.605 88 932.9199 818.1745 1047.665 757.4319 1108.408 89 932.9199 805.9985 1059.841 738.8103 1127.029 90 932.9199 794.8706 1070.969 721.7918 1144.048 91 932.9199 784.5550 1081.285 706.0153 1159.824 92 932.9199 774.8922 1090.948 691.2375 1174.602 93 932.9199 765.7692 1100.071 677.2849 1188.555 94 932.9199 757.1017 1108.738 664.0292 1201.811 95 932.9199 748.8254 1117.014 651.3717 1214.468 96 932.9199 740.8897 1124.950 639.2351 1226.605 
  6. Cuando trato de graficar el x.fore , obtengo un gráfico pero el eje x muestra números en lugar de fechas:

enter image description here

¿Los pasos que estoy haciendo son correctos? ¿Cómo puedo cambiar el eje x para leer las fechas de presentación?

Te agradezco mucho por cualquier aporte.

Esto es lo que hice:

 x$Date = as.Date(x$Date,format="%m/%d/%Y") x = xts(x=x$Used, order.by=x$Date) # To get the start date (305) # > as.POSIXlt(x = "2011-11-01", origin="2011-11-01")$yday ## [1] 304 # Add one since that starts at "0" x.ts = ts(x, freq=365, start=c(2011, 305)) plot(forecast(ets(x.ts), 10)) 

Resultando en:

Ejemplo de salida

Qué podemos aprender de esto:

  • Muchos de sus pasos se pueden combinar reduciendo la cantidad de objetos intermedios que crea
  • La salida aún no es tan bonita como @joran, pero todavía es fácil de leer. 2011.85 significa “día número 365*.85 ” (día 310 en el año).
  • Averiguar el día en un año se puede hacer utilizando as.POSIXlt(x = "2011-11-01", origin="2011-11-01")$yday y averiguar la fecha a partir de un número de día se puede hacer usando algo como as.Date(310, origin="2011-01-01")

Actualizar

Puede eliminar aún más pasos intermedios, ya que no hay ninguna razón para convertir primero sus datos en un xts.

 x = ts(x$Used, start=c(2011, as.POSIXlt("2011-11-01")$yday+1), frequency=365) # NOTE: We have only selected the "Used" variable # since ts will take care of dates plot(forecast(ets(x), 10)) 

Esto da exactamente el mismo resultado que la imagen de arriba.

Actualización 2

Basándose en la solución provista por @joran, puedes probar:

 # 'start' calculation = `as.Date("2011-11-01")-as.Date("2011-01-01")+1` # No need to convert anything to dates at this point using xts x = ts(x$Used, start=c(2011, 305), frequency=365) # Directly plot your forecast without your axes plot(forecast(ets(x), 10), axes = FALSE) # Generate labels for your x-axis a = seq(as.Date("2011-11-01"), by="weeks", length=11) # Plot your axes. # `at` is an approximation--there's probably a better way to do this, # but the logic is approximately 365.25 days in a year, and an origin # date in R of `January 1, 1970` axis(1, at = as.numeric(a)/365.25+1970, labels = a, cex.axis=0.6) axis(2, cex.axis=0.6) 

Que cederá:

Segundo intento

Parte del problema en su código original es que después de convertir sus datos a un objeto xts y convertirlos en un objeto ts , pierde las fechas en sus puntos de forecast .

Compare la primera columna ( Point ) de su salida x.fore con lo siguiente:

 > forecast(ets(x), 10) Point Forecast Lo 80 Hi 80 Lo 95 Hi 95 2012.000 741.6437 681.7991 801.4884 650.1192 833.1682 2012.003 741.6437 676.1250 807.1624 641.4415 841.8459 2012.005 741.6437 670.9047 812.3828 633.4577 849.8298 2012.008 741.6437 666.0439 817.2435 626.0238 857.2637 2012.011 741.6437 661.4774 821.8101 619.0398 864.2476 2012.014 741.6437 657.1573 826.1302 612.4328 870.8547 2012.016 741.6437 653.0476 830.2399 606.1476 877.1399 2012.019 741.6437 649.1202 834.1672 600.1413 883.1462 2012.022 741.6437 645.3530 837.9345 594.3797 888.9078 2012.025 741.6437 641.7276 841.5599 588.8352 894.4523 

Espero que esto te ayude a comprender el problema con tu enfoque original y a que mejore tu capacidad al tratar con series de tiempo en R.

Actualización 3

Solución final y más precisa, porque estoy evitando otro trabajo que debería estar haciendo en este momento …

Use el paquete lubridate para un mejor manejo de la fecha:

 require(lubridate) y = ts(x$Used, start=c(2011, yday("2011-11-01")), frequency=365) plot(forecast(ets(y), 10), xaxt="n") a = seq(as.Date("2011-11-01"), by="weeks", length=11) axis(1, at = decimal_date(a), labels = format(a, "%Y %b %d"), cex.axis=0.6) abline(v = decimal_date(a), col='grey', lwd=0.5) 

Resultando en:

Trama final

Tenga en cuenta el método alternativo para identificar la fecha de inicio de su objeto ts .

Si no tiene preferencias sobre un modelo específico, le sugiero que use uno que se aplique a una gran variedad de situaciones:

 library(forecast) t.ser < - ts(used, start=c(2011,1), freq=12) t.ets <- ets(t.ser) t.fc <- forecast(t.ets,h=10) 

Esto te dará la predicción para los próximos 10 meses.

Al ser más técnico, utiliza el método de suavizado exponencial que es una buena opción para situaciones generales. Dependiendo del tipo de datos, puede haber un mejor modelo específico para su uso, pero ets es una buena opción general.

Es importante resaltar que, dado que no tiene dos períodos completados (menos de 24 meses), el modelo no puede detectar la sazonalidad y, por lo tanto, esto no se incluirá en los cálculos.

Es bastante fácil alterar el gráfico para mostrar las fechas, simplemente suprimiendo los ejes en el diagtwig original y luego dibujándolos usted mismo:

 plot(x.fore,axes = FALSE) axis(2) axis(1,at = pretty(1:72,n = 6), labels = (x$Date[1]-1) + pretty(1:72,n = 6), cex.axis = 0.65) 

enter image description here