Short history:
As I understood can the normalized (profile) likelihood be used to get the CI of an estimate. "Normalized" means that the function will have a unit integral.
This works beautifully for the binomial distribution (the normalized likelihood is a beta-density). For the expectation of the normal distribution the dispersion parameter needs to be considered -> profile likelihood, and the normalized profile likelihood is the t-density.
My problem:
Now I thought I should be able go a similar way with gamma-distributed data. The ready solution in R seems to be fitting a gamma-glm and use confint(). Here is a working example:
y = c(269, 299, 437, 658, 1326)
mod = glm(y~1, family=Gamma(link=identity))
(coef(mod)-mean(y) < 1E-4) # TRUE
confint(mod, level=0.9)
Ok, now my attempt to solve this problem step-by-step by hand:
The likelihood function, reparametrized to mu = scale*shape:
L = Vectorize(function(mu,s) prod(dgamma(y,shape=mu/s,scale=s)))
L.opt = function(p) 1/L(p[1],p[2])
optim(par=c(100,100), fn=L.opt, control=c(reltol=1E-20))
The MLE for mu is equal to the coefficient of the model. The next lines produce a contour plot of the likelihood function with a red line indicating the maximum depending on mu:
m = seq(200,1500,len=100)
s = seq( 50,1500,len=100)
Lmat = outer(m,s,L)
Rmat = Lmat/max(Lmat)
contour(m,s,Rmat,levels=seq(0.1,1,len=10))
s.max = function(mu) optimize(function(s) L(mu,s), lower=1, upper=2000, maximum=TRUE)$maximum
lines(m,Vectorize(s.max)(m),col=2,lty=3)
The next step is to get the profile likelihood (and look at a plot):
profileL = Vectorize(function(mu) L(mu,s.max(mu)))
plot(profileL, xlim=c(200,2000))
Then this profile likelihood is normalized to get a unit integral:
AUC = integrate(profileL,0,Inf,rel.tol=1E-20)$value
normProfileL = function(mu) profileL(mu)/AUC
(integrate(normProfileL,0,Inf)$value-1 < 1E-4) # TRUE
plot(normProfileL, xlim=c(200,2000))
Now obtain the 90% CI as the quantiles for which the integral of this normalized profile likelihood is 0.05 and 0.95:
uniroot(function(mu) integrate(normProfileL,0,mu)$value-0.05, lower=0, upper=5000)$root
uniroot(function(mu) integrate(normProfileL,0,mu)$value-0.95, lower=0, upper=5000)$root
This is 413.9 ... 1557.
confint(mod,level=0.9) # gives 364.8 ... 1076
This seems to be not just a rounding error.
Where am I wrong?