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:gnls
nlme
corBrownian(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 logLik
fonction) sur la base des paramètres estimés obtenus à partir de gnls
sorte 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 gnls
fonction (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 β
où est le nombre d'observations, et .f ∗ i ( β ) = f ∗ i ( ϕ i , v i )
y ∗ i = Λ - T / 2 i y i f est positif-défini, et
Pour les et fixes , l'estimateur ML de est
et la log-vraisemblance profilée est
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:
où représente la longueur de .
J'ai compilé une liste de questions spécifiques auxquelles je suis confronté:
- 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?
big_lambda <- vcv.phylo(tree)
ape
- Would soit , ou l'équation de l'estimation moins biaisée (la dernière équation dans ce post)?
fit$sigma^2
- 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.?
- 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
norm(y-f(fit$coefficients,x),"F")
Matrix
norm()
- 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)?Λ i
log(diag(abs(big_lambda)))
big_lambda
logm(abs(big_lambda))
expm
logm()
- Juste pour confirmer, calculé comme ceci :?
t(solve(sqrtm(big_lambda)))
- Comment sont et ? Est-ce l'un des éléments suivants: f ∗ i ( β )
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_calc
est 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
Réponses:
Commençons par le cas plus simple où il n'y a pas de structure de corrélation pour les résidus:
La vraisemblance logarithmique peut alors être facilement calculée à la main avec:
É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:Notez que ceσ2
fit$sigma
n'est pas "l'estimation moins biaisée de " - nous devons donc d'abord faire la correction manuellement.Maintenant, pour le cas plus compliqué où les résidus sont corrélés:
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:
la source
vcv
fonction) - mais vous devez obtenir la matrice de corrélation, puis utiliser pour en faire la matrice var-cov.