6 votos

Previsión de una serie temporal con ponderaciones

Me gustaría pronosticar (o predecir) una serie temporal con pesos.

Lo siguiente funciona utilizando el l inear m écnicas de modelización de lm aplicando una distribución de pesos (sigmoidal) a los datos de entrada, ponderando esencialmente los últimos puntos de datos más que los primeros:

library("stats")
lm.weight.function <- function(x) {10 / (1 + exp(-x))} # Sigmoidal
lm.weights <- lapply(seq(-13, 14, length.out = 27), lm.weight.function)
lm.input <- as.data.frame(c(23957, 46771, 60767, 73284, 60296, 73122, 78304, 87154, 80459, 76885, 56479, 18809, 13453, 13951, 25140, 12035, 11920, 20683, 30357, 35019, 37732, 46150, 47856, 41931, 20985, 32526, 27283))
lm.input <- cbind(1:27, lm.input)
colnames(lm.input) <- c('x', 'y')
lm.model <- lm(formula = y ~ log(x), data = lm.input, weights = unlist(lm.weights))
predict.input <- as.data.frame(28:55)
colnames(predict.input) <- 'x'
predict.model <- predict(lm.model, predict.input)
plot(1:(27+28), c(lm.input$y, predict.model), type = 'l', xlab = 'x', ylab = 'y')

enter image description here

Ahora deseo hacer lo mismo utilizando el forecast paquete. Sin embargo, tengo dificultades para especificar el paquete weights :

library("forecast")
ts.weight.function <- function(x) {10 / (1 + exp(-x))} # Sigmoidal
ts.weights <- as.data.frame(lapply(seq(-13, 14, length.out = 27), ts.weight.function))
colnames(ts.weights) <- 'trend'
ts.input <- ts(c(23957, 46771, 60767, 73284, 60296, 73122, 78304, 87154, 80459, 76885, 56479, 18809, 13453, 13951, 25140, 12035, 11920, 20683, 30357, 35019, 37732, 46150, 47856, 41931, 20985, 32526, 27283), frequency = 1)
ts.model <- tslm(formula = ts.input ~ log(trend), weights = unlist(ts.weights))

Lo anterior imprime un error:

Error in eval(expr, envir, enclos) : 
  ..1 used in an incorrect context, no ... to look in

¿Cómo puedo utilizar tslm para prever una serie temporal con ponderaciones?

7voto

trish Puntos 31

Se trata de un problema con lm .

wrapper = function(formula,...)
  lm(formula=formula,...)
x=(1:27)
wrapper(ts.input~x,weights=ts.weights)

produce exactamente el mismo error. Si lee el código fuente de tslm , encontrará que lm se llama más o menos de la misma manera.

He encontrado aquí que ..1 se refiere al primer argumento incluido en ... que en este caso es el único argumento, weights . Sugiere que este tipo de error puede deberse a que el argumento que se pasa no existe en el entorno desde el que se llama a la función. Puede ver este comportamiento con wrapper(ts.input~x,weights=foo) si no tiene ningún objeto llamado foo .

Ejecutar un rastreo en wrapper(ts.input~x,weights=ts.weights) revela:

8 eval(expr, envir, enclos) 
7 eval(extras, data, env) 
6 model.frame.default(formula = formula, weights = ..1, drop.unused.levels = TRUE) 
5 stats::model.frame(formula = formula, weights = ..1, drop.unused.levels = TRUE) 
4 eval(expr, envir, enclos) 
3 eval(mf, parent.frame()) 
2 lm(formula = formula, ...) 
1 wrapper(ts.input ~ x, weights = ts.weights) 

Y en el código fuente de lm ,

mf <- match.call(expand.dots = FALSE)
m <- match(c("formula", "data", "subset", "weights", "na.action", 
    "offset"), names(mf), 0L)
mf <- mf[c(1L, m)]
mf$drop.unused.levels <- TRUE
mf[[1L]] <- quote(stats::model.frame)
mf <- eval(mf, parent.frame())
if (method == "model.frame") 
    return(mf)

lo que sugiere que la llamada a model.frame está recogiendo el ... de una manera extraña.

Así que decidí probarlo sin ... :

wrapper = function(formula,weights)
  lm(formula=formula,weights=weights)
x=(1:27)
wrapper(ts.input~x,weights=ts.weights)

que produjo

 Error in model.frame.default(formula = formula, weights = weights, drop.unused.levels = TRUE) : 

tipo inválido (cierre) para variable '(pesos)'

Un cierre, por supuesto, es una función en R. Lo que sólo puede significar una cosa... weights ya es una función en el entorno global. Efectivamente, ?weights revela que es irónicamente la función extractora de pesos modelo. Es obvio que tiene prioridad de búsqueda sobre las variables locales. Así que cambié los nombres de los argumentos (ya que formula también es una función):

wrapper = function(fm,ws){
  print(ws)
  lm(formula=fm,weights=ws)
}
x=(1:27)
wrapper(fm=ts.input~x,ws=ts.weights)

ahora produce

 [1] 2.260324e-05 6.385091e-05 1.803683e-04 5.094997e-04 1.439136e-03 4.064300e-03
 [7] 1.147260e-02 3.234087e-02 9.082267e-02 2.523791e-01 6.815483e-01 1.712317e+00
[13] 3.685455e+00 6.224593e+00 8.232410e+00 9.293615e+00 9.737984e+00 9.905650e+00
[19] 9.966395e+00 9.988078e+00 9.995776e+00 9.998504e+00 9.999471e+00 9.999813e+00
[25] 9.999934e+00 9.999977e+00 9.999992e+00

 Error in eval(expr, envir, enclos) : object 'ws' not found 

Y si corres traceback sigue teniendo el mismo problema con model.frame . Así que estoy completamente desconcertado. Mi única conclusión es que a) no tiene nada que ver con tslm o análisis de series temporales, y b) el problema radica en algún punto de la forma en que se pasan los argumentos dentro de lm .

Probablemente eso no te ayude en nada, pero esperemos que al menos alguien pueda venir y explicarte qué está pasando aquí. Mi respuesta provisional a su pregunta real de cómo utilizar pesos en tslm es que no puedes.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X