Calculer log-vraisemblance «à la main» pour la régression généralisée des moindres carrés non linéaires (nlme)

12

J'essaie de calculer la log-vraisemblance pour une régression des moindres carrés non linéaires généralisée pour la fonction optimisée par le dans le package R , en utilisant la matrice de covariance de variance générée par les distances sur un arbre phylogénétique en supposant un mouvement brownien (à partir du package). Le code R reproductible suivant correspond au modèle gnls en utilisant les données x, y et un arbre aléatoire avec 9 taxons:f(x)=β1(1+xβ2)β3gnlsnlmecorBrownian(phy=tree)ape

require(ape)
require(nlme)
require(expm)
tree <- rtree(9)
x <- c(0,14.51,32.9,44.41,86.18,136.28,178.21,262.3,521.94)
y <- c(100,93.69,82.09,62.24,32.71,48.4,35.98,15.73,9.71)
data <- data.frame(x,y,row.names=tree$tip.label)
model <- y~beta1/((1+(x/beta2))^beta3)
f=function(beta,x) beta[1]/((1+(x/beta[2]))^beta[3])
start <- c(beta1=103.651004,beta2=119.55067,beta3=1.370105)
correlation <- corBrownian(phy=tree)
fit <- gnls(model=model,data=data,start=start,correlation=correlation)
logLik(fit) 

Je voudrais calculer la log-vraisemblance "à la main" (dans R, mais sans utiliser la logLikfonction) sur la base des paramètres estimés obtenus à partir de gnlssorte qu'elle corresponde à la sortie de logLik(fit). REMARQUE: je n'essaie pas d'estimer les paramètres; Je veux juste calculer la log-vraisemblance des paramètres estimés par la gnlsfonction (bien que si quelqu'un a un exemple reproductible de la façon d'estimer les paramètres sans gnls, je serais très intéressé à le voir!).

Je ne sais pas vraiment comment procéder en R. La notation d'algèbre linéaire décrite dans les modèles à effets mixtes en S et S-Plus (Pinheiro et Bates) me dépasse énormément et aucune de mes tentatives n'a correspondu logLik(fit). Voici les détails décrits par Pinheiro et Bates:

La log-vraisemblance pour le modèle des moindres carrés non linéaires généralisés où est calculée comme suit:ϕ i = A i βyi=fi(ϕi,vi)+ϵiϕi=Aiβ

l(β,σ2,δ|y)=12{Nlog(2πσ2)+i=1M[||yifi(β)||2σ2+log|Λi|]}

où est le nombre d'observations, et .f i ( β ) = f i ( ϕ i , v i )Nfi(β)=fi(ϕi,vi)

y i = Λ - T / 2 i y i fΛi est positif-défini, etyi=ΛiT/2yifi(ϕi,vi)=ΛiT/2fi(ϕi,vi)

Pour les et fixes , l'estimateur ML de estβλσ2

σ^(β,λ)=i=1M||yifi(β)||2/N

et la log-vraisemblance profilée est

l(β,λ|y)=12{N[log(2π/N)+1]+log(i=1M||yifi(β)||2)+i=1Mlog|Λi|}

qui est utilisé avec un algorithme de Gauss-Seidel pour trouver les estimations ML de et . Une estimation moins biaisée de est utilisée:βλσ2

σ2=i=1M||Λ^iT/2[yifi(β^)]||2/(Np)

où représente la longueur de .pβ

J'ai compilé une liste de questions spécifiques auxquelles je suis confronté:

  1. Qu'est-ce que ? Est-ce la matrice de distance produite par in , ou doit-elle être transformée ou paramétrée d'une manière ou d'une autre par , ou autre chose entièrement?Λibig_lambda <- vcv.phylo(tree)apeλ
  2. Would soit , ou l'équation de l'estimation moins biaisée (la dernière équation dans ce post)?σ2fit$sigma^2
  3. Est-il nécessaire d'utiliser pour calculer la log-vraisemblance, ou s'agit-il simplement d'une étape intermédiaire pour l'estimation des paramètres? De plus, comment est utilisé ? Est-ce une valeur unique ou un vecteur, et est-il multiplié par tous les éléments ou juste hors diagonale, etc.?λλΛi
  4. Qu'est-ce que? Serait-ce dans le paquet ? Si c'est le cas, je ne sais pas trop comment calculer la somme , car renvoie une seule valeur, pas un vecteur.M i = 1 | | y i - f i ( β ) | | 2||yf(β)||norm(y-f(fit$coefficients,x),"F")Matrixi=1M||yifi(β)||2norm()
  5. Comment calcule-t-on? Est-ce où est , ou est-ce du paquet ? Si tel est le cas , comment prend-on la somme d'une matrice (ou implique-t-on que ce ne sont que les éléments diagonaux)?Λ ilog|Λi|log(diag(abs(big_lambda)))big_lambdaΛilogm(abs(big_lambda))expmlogm()
  6. Juste pour confirmer, calculé comme ceci :?ΛiT/2t(solve(sqrtm(big_lambda)))
  7. Comment sont et ? Est-ce l'un des éléments suivants: f i ( β )yifi(β)

y_star <- t(solve(sqrtm(big_lambda))) %*% y

et

f_star <- t(solve(sqrtm(big_lambda))) %*% f(fit$coefficients,x)

ou serait-ce

y_star <- t(solve(sqrtm(big_lambda))) * y

et

f_star <- t(solve(sqrtm(big_lambda))) * f(fit$coefficients,x) ?

Si toutes ces questions reçoivent une réponse, en théorie, je pense que la log-vraisemblance devrait être calculable pour correspondre à la sortie de logLik(fit). Toute aide sur l'une de ces questions serait grandement appréciée. Si quelque chose doit être clarifié, faites-le moi savoir. Merci!

MISE À JOUR : J'ai expérimenté différentes possibilités pour le calcul de la log-vraisemblance, et voici le meilleur que j'ai trouvé jusqu'à présent. logLik_calcest toujours d'environ 1 à 3 de la valeur renvoyée par logLik(fit). Soit je suis proche de la solution réelle, soit c'est par pure coïncidence. Des pensées?

  C <- vcv.phylo(tree) # variance-covariance matrix
  tC <- t(solve(sqrtm(C))) # C^(-T/2)
  log_C <- log(diag(abs(C))) # log|C|
  N <- length(y)
  y_star <- tC%*%y 
  f_star <- tC%*%f(fit$coefficients,x)
  dif <- y_star-f_star  
  sigma_squared <-  sum(abs(y_star-f_star)^2)/N
  # using fit$sigma^2 also produces a slightly different answer than logLik(fit)
  logLik_calc <- -((N*log(2*pi*(sigma_squared)))+
       sum(((abs(dif)^2)/(sigma_squared))+log_C))/2
Eric
la source
votre définition de la fonction manque un sur le côté droit. xf(x)x
Glen_b -Reinstate Monica

Réponses:

10

Commençons par le cas plus simple où il n'y a pas de structure de corrélation pour les résidus:

fit <- gnls(model=model,data=data,start=start)
logLik(fit)

La vraisemblance logarithmique peut alors être facilement calculée à la main avec:

N <- fit$dims$N
p <- fit$dims$p
sigma <- fit$sigma * sqrt((N-p)/N)
sum(dnorm(y, mean=fitted(fit), sd=sigma, log=TRUE))

Étant donné que les résidus sont indépendants, nous pouvons simplement utiliser dnorm(..., log=TRUE)pour obtenir les termes de vraisemblance du log individuel (puis les résumer). Alternativement, nous pourrions utiliser:

sum(dnorm(resid(fit), mean=0, sd=sigma, log=TRUE))

Notez que ce fit$sigman'est pas "l'estimation moins biaisée de " - nous devons donc d'abord faire la correction manuellement.σ2

Maintenant, pour le cas plus compliqué où les résidus sont corrélés:

fit <- gnls(model=model,data=data,start=start,correlation=correlation)
logLik(fit)

Ici, nous devons utiliser la distribution normale multivariée. Je suis sûr qu'il existe une fonction pour cela quelque part, mais faisons-le simplement à la main:

N <- fit$dims$N
p <- fit$dims$p
yhat <- cbind(fitted(fit))
R <- vcv(tree, cor=TRUE)
sigma <- fit$sigma * sqrt((N-p)/N)
S <- diag(sigma, nrow=nrow(R)) %*% R %*% diag(sigma, nrow=nrow(R))
-1/2 * log(det(S)) - 1/2 * t(y - yhat) %*% solve(S) %*% (y - yhat) - N/2 * log(2*pi)
Wolfgang
la source
La log-vraisemblance pour les résidus non corrélés a parfaitement fonctionné, mais je ne peux pas comprendre la distribution normale multivariée. Dans ce cas, qu'est-ce que S? J'ai essayé S <- vcv.phylo (arbre) et j'ai obtenu environ -700 pour la probabilité de log, alors que logLik (fit) était d'environ -33.
Eric
Désolé - je me suis trompé quand j'ai copié-collé le code. Maintenant c'est terminé. S est la matrice variance-covariance des résidus. Vous étiez sur la bonne voie (avec la vcvfonction) - mais vous devez obtenir la matrice de corrélation, puis utiliser pour en faire la matrice var-cov. σ^2
Wolfgang