I am trying to implement the Metropolis Hastings algorithm for Bayesian analysis. In this case, the parameter of interest is the scale parameter for a Weibull distribution. The context is for reliability estimation; the scale parameter is analogous to the service life of an item.
I am working in R. I have data that has an "Age" property that is the age at which an item failed. There is no censored data. I fit the data to a Weibull distribution:
weib_fit <- fitdist(data_tbl$Age, "weibull")
I create a function to serve as the prior distribution based on some assumed 2-param Weibull distribution:
f <- function(x)
{
shape = 3 # theoretical degradation
scale = 30 # theoretical design life
return(dweibull(x, shape, scale))
}
I create a liklihood function using the data parameters:
data_shape <- as.numeric(weib_fit$estimate["shape"])
data_scale <- as.numeric(weib_fit$estimate["scale"])
qx <- function(x)
{
# replace the scale param with x
rweibull(1, data_shape, x)
}
The rest is outlined below
step <- function(x, f, qx)
{
xp <- qx(x)
prob <- min(1, f(xp)/f(x))
if (runif(1) < prob)
{
x <- xp
}
return(x)
}
run <- function(x, f, qx, nsteps)
{
res <- matrix(NA, nsteps, length(x))
for (i in seq_len(nsteps))
res[i,] <- x <- step(x, f, qx)
drop(res)
}
nsteps <- 100000
age_guess <- 20
res <- run(age_guess, f, qx, nsteps)
burn_in <- 5000
# get the final result
result <- res[c(burn_in:length(res))]
hist(result, main="MH Distribution", xlab="Service Life Param")
The problem: I don't think I'm understanding the implementation of the Metropolis-Hastings algorithm. I would assume the qx
function above would be selecting for the Weibull scale distribution, but I get somewhat non-sensical results. If I modify it to rweibull(1, x, data_scale)
it aligns much more with the expected frequentist results, but it doesn't make sense to me why I would be iterating by passing x
to the rweibull()
shape parameter when I am interested in the distribution of the scale parameter.
What am I missing in my understanding and how would I need to modify the code above to fix it?