Comment simuler des données fonctionnelles?

12

J'essaie de tester différentes approches d'analyse de données fonctionnelles. Idéalement, je voudrais tester le panel d'approches que j'ai sur des données fonctionnelles simulées. J'ai essayé de générer une FD simulée en utilisant une approche basée sur une sommation des bruits gaussiens (code ci-dessous), mais les courbes résultantes semblent beaucoup trop robustes par rapport à la réalité .

Je me demandais si quelqu'un avait un pointeur sur des fonctions / idées pour générer des données fonctionnelles simulées plus réalistes. En particulier, celles-ci doivent être fluides. Je suis complètement nouveau dans ce domaine, donc tout conseil est le bienvenu.

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)
user603
la source
1
Ne pouvez-vous pas simplement simuler des données dont la moyenne est une fonction lisse connue et ajouter du bruit aléatoire? Par exemple,x=seq(0,2*pi,length=1000); plot(sin(x)+rnorm(1000)/10,type="l");
Macro
@Macro: non, si vous zoomez sur votre tracé, vous verrez que les fonctions qu'il génère ne sont pas fluides. Comparez-les à certaines des courbes de ces diapositives: bscb.cornell.edu/~hooker/FDA2007/Lecture1.pdf . Une spline lissée de vos x pourrait faire l'affaire, mais je cherche un moyen direct de générer les données.
user603
chaque fois que vous incluez du bruit (qui est une partie nécessaire de tout modèle stochastique), les données brutes seront, par nature, non lisses. L'ajustement de spline auquel vous faites référence suppose que le signal est lisse - pas les données réelles observées (qui sont une combinaison de signal et de bruit).
Macro
@Macro: comparez vos processus simulés à ceux de la page 16 de ce document: inference.phy.cam.ac.uk/mackay/gpB.pdf
user603
1
utiliser des polynômes d'ordre supérieur. Un polynôme du 20e degré avec des coefficients aléatoires (avec la bonne distribution) peut changer beaucoup (en douceur) de directions. Si vous avez trouvé une réponse à votre question, vous pouvez peut-être la poster comme réponse?
Macro

Réponses:

8

Découvrez comment simuler les réalisations d'un processus gaussien (GP). La régularité des réalisations dépend des propriétés analytiques de la fonction de covariance du GP. Ce livre en ligne contient de nombreuses informations: http://uncertainty.stat.cmu.edu/

Cette vidéo donne une belle introduction aux GP: http://videolectures.net/gpip06_mackay_gpb/

PS Concernant votre commentaire, ce code peut vous donner un début.

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)
Zen
la source
Avez-vous un lien qui aborde la question de savoir comment simuler des réalisations d'un processus gaussien, en particulier? Ce n'est pas abordé dans le livre (en regardant l'index).
user603
La simulation d'un GP se fait à travers les distributions de dimension finie. Fondamentalement, vous choisissez autant de points du domaine que vous le souhaitez, et à partir de la fonction de moyenne et de covariance du GP, vous obtenez une normale multivariée. L'échantillonnage à partir de cette normale multivariée vous donne la valeur des réalisations du GP aux points choisis. Comme je l'ai dit, ces valeurs se rapprochent d'une fonction lisse, tant que la fonction de covariance du GP satisfait les conditions analytiques nécessaires. Une fonction de covariance exponentielle quadratique (avec un terme de "gigue") est un bon début.
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)

Un procès.  Fonctions fluides

user603
la source
Cela semble bon!
Zen