Estou tentando calcular a probabilidade de log para uma regressão de mínimos quadrados não linear generalizada para a função otimizado pelagnlsfunção no pacote Rnlme, usando a matriz de covariância de variância gerada pelas distâncias em uma árvore filogenética assumindo movimento browniano (corBrownian(phy=tree)daapeembalagem). O seguinte código R reprodutível se ajusta ao modelo gnls usando dados x, y e uma árvore aleatória com 9 táxons:
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)
Eu gostaria de calcular a probabilidade do log "à mão" (em R, mas sem o uso da logLikfunção) com base nos parâmetros estimados obtidos gnlspara que ele corresponda à saída de logLik(fit). NOTA: Não estou tentando estimar parâmetros; Eu só quero calcular a probabilidade de log dos parâmetros estimados pela gnlsfunção (embora se alguém tiver um exemplo reproduzível de como estimar parâmetros sem gnls, eu ficaria muito interessado em vê-lo!).
Não tenho muita certeza de como fazer isso em R. A notação de álgebra linear descrita em Modelos de efeitos mistos em S e S-Plus (Pinheiro e Bates) está muito acima da minha cabeça e nenhuma das minhas tentativas coincidiu logLik(fit). Aqui estão os detalhes descritos por Pinheiro e Bates:
O log-probabilidade para o não linear dos mínimos quadrados modelo generalizado onde φ i = A i β é calculado como se segue:
onde é o número de observações e f ∗ i ( β ) = f ∗ i ( ϕ i , v i ) .
é positivo-definido, y ∗ i = Λ - T / 2 i y i e f ∗ i ( ϕ i , v i ) = Λ - T / 2 i f i ( ϕ i , v i )
Para e λ fixos , o estimador de ML de σ 2 é
e a probabilidade de log com perfil é
que é usado com um algoritmo de Gauss-Seidel para encontrar as estimativas de ML de e λ . Uma estimativa menos tendenciosa de σ 2 é usada:
Eu compilei uma lista de perguntas específicas que estou enfrentando:
big_lambda <- vcv.phylo(tree)ape, or something else entirely?- Would be
fit$sigma^2, or the equation for the less biased estimate (the last equation in this post)? - Is it necessary to use to calculate log-likelihood, or is that just an intermediate step for parameter estimation? Also, how is used? Is it a single value or a vector, and is it multiplied by all of or just off-diagonal elements, etc.?
- What is ? Would that be
norm(y-f(fit$coefficients,x),"F")in the packageMatrix? If so, I'm confused about how to calculate the sum , becausenorm()returns a single value, not a vector. - How does one calculate ? Is it
log(diag(abs(big_lambda)))wherebig_lambdais , or is itlogm(abs(big_lambda))from the packageexpm? If it islogm(), how does one take the sum of a matrix (or is it implied that it is just the diagonal elements)? - Just to confirm, is calculated like this:
t(solve(sqrtm(big_lambda)))? - How are and calculated? Is it either of the following:
y_star <- t(solve(sqrtm(big_lambda))) %*% y
and
f_star <- t(solve(sqrtm(big_lambda))) %*% f(fit$coefficients,x)
or would it be
y_star <- t(solve(sqrtm(big_lambda))) * y
and
f_star <- t(solve(sqrtm(big_lambda))) * f(fit$coefficients,x) ?
If all of these questions are answered, in theory, I think the log-likelihood should be calculable to match the output from logLik(fit). Any help on any of these questions would be greatly appreciated. If anything needs clarification, please let me know. Thanks!
UPDATE: I have been experimenting with various possibilities for the calculation of the log-likelihood, and here is the best I have come up with so far. logLik_calc is consistently about 1 to 3 off from the value returned by logLik(fit). Either I'm close to the actual solution, or this is purely by coincidence. Any thoughts?
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