Come simulare i dati funzionali?


12

Sto cercando di testare vari approcci di analisi dei dati funzionali. Idealmente, vorrei testare il pannello di approcci che ho su dati funzionali simulati. Ho provato a generare un FD simulato usando un approccio basato su un sommario rumori gaussiani (codice sotto), ma le curve risultanti sembrano troppo robuste rispetto alla realtà .

Mi chiedevo se qualcuno avesse un puntatore a funzioni / idee per generare dati funzionali simulati dall'aspetto più realistico. In particolare, questi dovrebbero essere lisci. Sono completamente nuovo in questo campo, quindi ogni consiglio è il benvenuto.

library("MASS")
library("caTools")
VCM<-function(cont,theta=0.99){
    Sigma<-matrix(rep(0,length(cont)^2),nrow=length(cont))
    for(i in 1:nrow(Sigma)){
        for (j in 1:ncol(Sigma)) Sigma[i,j]<-theta^(abs(cont[i]-cont[j]))
    }
    return(Sigma)
}


t1<-1:120
CVC<-runmean(cumsum(rnorm(length(t1))),k=10)
VMC<-VCM(cont=t1,theta=0.99)
sig<-runif(ncol(VMC))
VMC<-diag(sig)%*%VMC%*%diag(sig)
DTA<-mvrnorm(100,rep(0,ncol(VMC)),VMC)  

DTA<-sweep(DTA,2,CVC)
DTA<-apply(DTA,2,runmean,k=5)
matplot(t(DTA),type="l",col=1,lty=1)

1
Non puoi semplicemente simulare dati la cui media è una funzione regolare nota e aggiungere rumore casuale? Ad esempio,x=seq(0,2*pi,length=1000); plot(sin(x)+rnorm(1000)/10,type="l");
Macro

@Macro: nop, se ingrandisci la trama vedrai che le funzioni generate da essa non sono fluide. Confrontali con alcune delle curve di queste diapositive: bscb.cornell.edu/~hooker/FDA2007/Lecture1.pdf . Una spline smussata delle tue x potrebbe fare il trucco, ma sto cercando un modo diretto per generare i dati.
user603

ogni volta che includi il rumore (che è una parte necessaria di qualsiasi modello stocastico), i dati grezzi saranno, intrinsecamente, non fluidi. L'adattamento della spline a cui ti riferisci sta assumendo che il segnale sia regolare, non i dati effettivamente osservati (che è una combinazione di segnale e rumore).
Macro

@Macro: confronta i tuoi processi simulati con quelli a pagina 16 di questo documento: inference.phy.cam.ac.uk/mackay/gpB.pdf
user603

1
usa polinomi di ordine superiore. Un polinomio di 20 ° grado con coefficienti casuali (con la giusta distribuzione) può cambiare direzione (senza intoppi) abbastanza. Se hai trovato una risposta alla tua domanda, forse puoi pubblicarla come risposta?
Macro

Risposte:


8

Dai un'occhiata a come simulare le realizzazioni di un processo gaussiano (GP). La scorrevolezza delle realizzazioni dipende dalle proprietà analitiche della funzione di covarianza del GP. Questo libro online contiene molte informazioni: http://uncertainty.stat.cmu.edu/

Questo video offre una buona introduzione ai medici di base: http://videolectures.net/gpip06_mackay_gpb/

PS Per quanto riguarda il tuo commento, questo codice potrebbe darti un inizio.

library(MASS)
C <- function(x, y) 0.01 * exp(-10000 * (x - y)^2) # covariance function
M <- function(x) sin(x) # mean function
t <- seq(0, 1, by = 0.01) # will sample the GP at these points
k <- length(t)
m <- M(t)
S <- matrix(nrow = k, ncol = k)
for (i in 1:k) for (j in 1:k) S[i, j] = C(t[i], t[j])
z <- mvrnorm(1, m, S)
plot(t, z)

Hai un link che risolve la domanda su come simulare le realizzazioni di un processo gaussiano, in particolare? Questo non è affrontato nel libro (guardando l'indice).
user603

La simulazione di un GP viene effettuata attraverso le distribuzioni di dimensioni finite. Fondamentalmente, scegli tutti i punti del dominio che vuoi e dalla funzione media e covarianza del GP ottieni una multivariata normale. Il campionamento da questa normale multivariata ti dà il valore delle realizzazioni del GP nei punti scelti. Come ho detto, questi valori si avvicinano a una funzione regolare, purché la funzione di covarianza del GP soddisfi le condizioni analitiche necessarie. Una funzione di covarianza esponenziale quadratica (con un termine "jitter") è un buon inizio.
Zen,

4

{xi,yi}

require("MASS")
calcSigma<-function(X1,X2,l=1){
    Sigma<-matrix(rep(0,length(X1)*length(X2)),nrow=length(X1))
    for(i in 1:nrow(Sigma)){
        for (j in 1:ncol(Sigma)) Sigma[i,j]<-exp(-1/2*(abs(X1[i]-X2[j])/l)^2)
    }
    return(Sigma)
}
# The standard deviation of the noise
n.samples<-50
n.draws<-50
x.star<-seq(-5,5,len=n.draws)
nval<-3
f<-data.frame(x=seq(-5,5,l=nval),y=rnorm(nval,0,10))
sigma.n<-0.2
# Recalculate the mean and covariance functions
k.xx<-calcSigma(f$x,f$x)
k.xxs<-calcSigma(f$x,x.star)
k.xsx<-calcSigma(x.star,f$x)
k.xsxs<-calcSigma(x.star,x.star)
f.bar.star<-k.xsx%*%solve(k.xx+sigma.n^2*diag(1,ncol(k.xx)))%*%f$y
cov.f.star<-k.xsxs-k.xsx%*%solve(k.xx+sigma.n^2*diag(1,ncol(k.xx)))%*%k.xxs
values<-matrix(rep(0,length(x.star)*n.samples),ncol=n.samples)
for (i in 1:n.samples)  values[,i]<-mvrnorm(1,f.bar.star,cov.f.star)
values<-cbind(x=x.star,as.data.frame(values))
matplot(x=values[,1],y=values[,-1],lty=1,type="l",col="black")
lines(x.star,f.bar.star,col="red",lwd=2)

Una prova.  Funzioni fluide


Questo sembra buono!
Zen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.