Modelado de una spline a lo largo del tiempo: matriz de diseño y encuesta de enfoques

8

Una variable de respuesta y es una función no lineal de varias variables predictoras X (en mis datos reales la respuesta está distribuida binomialmente, pero aquí estoy usando un valor normalmente distribuido para simplificar). Puedo modelar las relaciones entre los predictores y la respuesta usando splines / smooths (por ejemplo, modelos GAM en el mgcvpaquete en R).

Hasta aquí todo bien. Sin embargo, cada respuesta es el resultado de procesos que evolucionan con el tiempo. Es decir, la relación entre los predictores X y la respuesta y cambia con el tiempo. Para cada respuesta, tengo datos para los predictores en varios puntos de tiempo alrededor de la respuesta. Es decir, hay una respuesta por grupo de puntos de tiempo (no es que la respuesta evolucione con el tiempo).

Algunas ilustraciones son probablemente útiles en este punto. Aquí hay algunos datos con parámetros conocidos (código a continuación) y luego graficados usando ggplot2 (especificando el método GAM y un suavizador apropiado), con tiempo en las facetas. Por ejemplo, y es una función cuadrática de x1, y el signo y la magnitud de esta relación cambian en función del tiempo.

EDITAR: como soy nuevo no puedo publicar una imagen;  ejecuta el código para verlo.

La relación entre x2 e y es circular, correspondiente a un aumento en y con una cierta dirección de x2. La amplitud de esta relación se modula con el tiempo. (Modelado en ggplot usando un gam que especifica un suavizador cúbico circular "cc").

EDITAR: como soy nuevo no puedo publicar una imagen;  ejecuta el código para verlo.

Me gustaría modelar el cambio (no lineal) en cada predictor en función del tiempo usando algo así como una spline bidimensional.

He considerado usar un suavizado bidimensional en el paquete mgcv (algo así como te(x1,t)), excepto que esto requeriría los datos en una forma larga (es decir, una sola columna de puntos de tiempo). Creo que esto es inapropiado, porque una respuesta está asociada con todos los puntos de tiempo, por lo que organizar los datos en forma larga (duplicando así la misma respuesta en múltiples filas de la matriz de diseño) violaría la independencia de las observaciones. Mis datos están actualmente organizados con columnas (y, x1.t1, x1.t2, x1.t3, ..., x2.t1, x2.t2, ...)y creo que este es el formato más apropiado.

Me gustaría saber:

  1. ¿Hay alguna manera mejor de modelar estos datos?
  2. de ser así, cómo se vería la matriz / fórmula de diseño del modelo. En última instancia, me gustaría estimar los coeficientes del modelo utilizando la inferencia bayesiana en un paquete mcmc como JAGS, por lo que me gustaría saber cómo escribir una spline bidimensional.

Código R para reproducir mi ejemplo:

library(ggplot2)
library(mgcv)
#-------------------
# start by generating some data with known relationships between two variables,
# one periodic, over time.
set.seed(123)

nTimeBins <- 6
nSamples <- 500

# the relationship between x1, x2 and y are not linear.
# y = 0.4*x1^2 -1.2*x1 + 0.4*sin(x2) + 1.2*cos(x2)

# the relationship between x1, x2 and y evolve over time. 
x1.timeMult <- cos(seq(-pi,pi,length=nTimeBins))
x2.timeMult <- cos(seq(-pi/2,pi/2,length=nTimeBins))

qplot(x=1:nTimeBins,y=x1.timeMult,geom="line") + 
      geom_line(aes(x=1:nTimeBins,y=x2.timeMult,colour="red")) + 
      guides(colour=FALSE) + ylab("multiplier")

df <- data.frame(setup=rep(NA,times=nSamples))
for (time in 1 : nTimeBins){
  text <- paste('df$x1.t',time,' <- runif(nSamples,min=-3,max=3)',sep="")
  eval(parse(text=text))

  text <- paste('df$x2.t',time,' <- runif(nSamples,min=-pi,max=pi)',sep="")
  eval(parse(text=text))
}
df$setup <- NULL

# each y is a function of x over time.
text <- 'y <- '
# replicated from above for reference:
# y = 0.4*x1^2 -1.2*x1 + 0.4*sin(x2) + 1.2*cos(x2)
for (time in 1 : nTimeBins){
  text <- paste(text,'(0.4*x1.t',time,'^2-1.2*x1.t',time,') * 
                x1.timeMult[',time,'] + (0.4*sin(x2.t',time,') + 
                1.2*cos(x2.t',time,'))*x2.timeMult[',time,'] + ',sep="")
}

text <- paste(text,'rnorm(nSamples,sd=0.2)')
attach(df)
eval(parse(text=text))
df$y <- y

#-------------------
# transform into long form data for plotting:
df.long <- data.frame(y=rep(df$y,times=nTimeBins))
textX1 <- 'df.long$x1 <- c('
textX2 <- 'df.long$x2 <- c('

for (time in 1:nTimeBins){
    textX1 <- paste(textX1,'x1.t',time,',',sep="")
    textX2 <- paste(textX2,'x2.t',time,',',sep="")
}
textX1 <- paste(textX1,'NULL)',sep="")
textX2 <- paste(textX2,'NULL)',sep="")
eval(parse(text=textX1))
eval(parse(text=textX2))
# time stamp:
df.long$t <- factor(rep(1:nTimeBins,each=nSamples))

#-------------------
# plot relationships over time using GAM fits in ggplot:
p1 <- ggplot(df.long,aes(x=x1,y=y)) + geom_point() + 
             stat_smooth(method="gam",formula=y ~ s(x,bs="cs",k=4)) + 
             facet_wrap(~ t, ncol=3) + opts(title="x1 versus y over time")
p1

p2 <- ggplot(df.long,aes(x=x2,y=y)) + geom_point() + 
             stat_smooth(method="gam",formula=y ~ s(x,bs="cc",k=5)) + 
             facet_wrap(~ t, ncol=3) + opts(title="x2 versus y over time")
p2
tsawallis
fuente
1
Los datos de series de tiempo nunca son datos independientes, ya que la evolución en el tiempo correlaciona las observaciones de la misma serie de tiempo (autocorrelación de tiempo), a menos que, por supuesto, se trate de ruido. Pero esta correlación de tiempo no tiene nada que ver con que las 2 series de tiempo sean independientes entre sí. El tiempo es el mismo para x1 y x2, por lo que el puntaje i-ésimo o la entrada de la variable x1 debe estar en la misma fila de la matriz del modelo que el puntaje i-ésimo de la variable x2. No veo por qué esto viola el supuesto de que las series temporales son independientes. En caso de duda, calcule la correlación cruzada.
nukimov

Respuestas:

1

Estoy de acuerdo con usted en que es posible que tenga que tener en cuenta los términos de los errores de los encuestados individuales a lo largo del tiempo, especialmente si no tiene un resultado para todo el período para cada encuestado.

Una forma de hacerlo es con BayesX . Permite efectos espaciales con splines donde puede tener tiempo en una dimensión y el valor covariable en la otra. Además, puede agregar un efecto aleatorio para cada observación. Potencialmente, eche un vistazo a este documento .

Sin embargo, estoy bastante seguro de que tendrá que poner su modelo en formato largo. Además, deberá agregar una idcolumna para el encuestado o el efecto aleatorio.

Benjamin Christoffersen
fuente