Modelando um spline ao longo do tempo - matriz de design e levantamento de abordagens


8

Uma variável de resposta y é uma função não linear de várias variáveis ​​preditoras X (nos meus dados reais a resposta é distribuída binomialmente, mas aqui estou usando um valor normalmente distribuído para simplificar). Posso modelar os relacionamentos entre os preditores e a resposta usando splines / smooths (por exemplo, modelos GAM no mgcvpacote em R).

Por enquanto, tudo bem. No entanto, cada resposta é o resultado de processos que evoluem ao longo do tempo. Ou seja, a relação entre os preditores X e a resposta y muda ao longo do tempo. Para cada resposta, tenho dados para os preditores ao longo de vários pontos no tempo em torno da resposta. Ou seja, há uma resposta por grupo de pontos no tempo (não que a resposta evolua ao longo do tempo).

Algumas ilustrações são provavelmente úteis neste momento. Aqui estão alguns dados com parâmetros conhecidos (código abaixo) e plotados usando o ggplot2 (especificando o método GAM e um método mais suave apropriado), com o tempo nas facetas. Por ilustração, y é uma função quadrática de x1, e o sinal e a magnitude dessa relação mudam em função do tempo.

EDIT: como sou novo, não consigo postar uma imagem;  execute o código para vê-lo.

A relação entre x2 e y é circular, correspondendo a um aumento em y com uma certa direção de x2. A amplitude dessa relação modula-se ao longo do tempo. (Modelado no ggplot usando um gam que especifica uma suavidade cúbica circular "cc").

EDIT: como sou novo, não consigo postar uma imagem;  execute o código para vê-lo.

Eu gostaria de modelar a mudança (não-linear) em cada preditor em função do tempo usando algo como um spline bidimensional.

Eu considerei o uso de uma suavização bidimensional no pacote mgcv (algo como te(x1,t)), exceto que isso exigiria os dados de forma longa (ou seja, uma única coluna de pontos no tempo). Eu acho que isso é inadequado, porque uma resposta está associada a todos os pontos do tempo - portanto, organizar os dados em formato longo (duplicando a mesma resposta em várias linhas da matriz de design) violaria a independência das observações. Meus dados estão atualmente organizados com colunas (y, x1.t1, x1.t2, x1.t3, ..., x2.t1, x2.t2, ...)e acho que esse é o formato mais apropriado.

Eu gostaria de saber:

  1. existe uma maneira melhor de modelar esses dados
  2. Nesse caso, como seria a matriz / fórmula de design do modelo. Por fim, gostaria de estimar os coeficientes do modelo usando a inferência bayesiana em um pacote mcmc como o JAGS, então gostaria de saber como escrever um spline bidimensional.

Código R para reproduzir meu exemplo:

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

1
Dados de séries temporais nunca são dados independentes, uma vez que a evolução no tempo correlaciona as observações da mesma série (correlação automática no tempo), a menos que, é claro, você esteja lidando com ruído. Mas essa correlação temporal não tem nada a ver com as duas séries temporais independentes uma da outra. O tempo é o mesmo para x1 e x2, portanto, a i-ésima pontuação ou a entrada da variável x1 deve estar na mesma linha da matriz do modelo que a i-ésima pontuação da variável x2. Não vejo por que isso viola a suposição de que as séries temporais são independentes. Em caso de dúvida, calcule a correlação cruzada.
Nukimov 20/04

Respostas:


1

Concordo com você que pode ser necessário contabilizar os termos de erros de respondentes individuais ao longo do tempo, principalmente se você não tiver resultado para todo o período de cada respondente.

Uma maneira de fazer isso é com o BayesX . Ele permite efeitos espaciais com splines, onde você pode ter tempo em uma dimensão e o valor covariável na outra. Além disso, você pode adicionar um efeito aleatório para cada observação. Potencialmente, dê uma olhada neste artigo .

No entanto, tenho certeza que você terá que colocar seu modelo em formato longo. Além disso, você precisará adicionar uma idcoluna para o respondente ou o efeito aleatório.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.