|
| 1 | +# Likelihood function for the data (log) |
| 2 | +ll.fun <- function(beta_0, beta_1, tau = 0.2){ |
| 3 | + ll <- sum(dnorm(x = y, mean = beta_0 + beta_1 * x, |
| 4 | + sd = sqrt(1 / tau), log = TRUE)) |
| 5 | + return(ll) |
| 6 | +} |
| 7 | + |
| 8 | +# prior function (uninformative) (log) |
| 9 | +prior.fun <- function(beta_0, beta_1, tau = 0.2){ |
| 10 | + lp <- dnorm(x = beta_0, mean = 0, sd = sqrt(1/10^-6), log = TRUE) + |
| 11 | + dnorm(x = beta_1, mean = 0, sd = sqrt(1/10^-6), log = TRUE) + |
| 12 | + dgamma(x = tau, shape = 0.001, rate = 0.001, log = TRUE) |
| 13 | + return(lp) |
| 14 | +} |
| 15 | + |
| 16 | +# MCMC - metropolis algorithm |
| 17 | + |
| 18 | +# N = lengte van de MCMC |
| 19 | +# sigma = grootte van de stappen in de markov chain |
| 20 | +# init_b0 en init_b1 = initiële waarden voor beta_0 en beta_1 |
| 21 | + |
| 22 | +MCMC_metro <- function(x, y, N = 20, sigma = 1, init_b0, init_b1){ |
| 23 | + |
| 24 | + set.seed(56) # Optioneel, om bij iedereen hetzelfde resultaat te bekomen. |
| 25 | + # We maken een lege dataframe om de output in te bewaren |
| 26 | + mcmc <- data.frame(iter = 1:N, # positie in de markov chain |
| 27 | + beta_0 = NA, # intercept |
| 28 | + beta_1 = NA, # helling |
| 29 | + tau = NA, # 1/standard deviation |
| 30 | + post = NA, # posterior |
| 31 | + accept = NA) # stap wel (1) of niet (0) geaccepteerd. |
| 32 | + |
| 33 | + mcmc$beta_0[1] <- init_b0 |
| 34 | + mcmc$beta_1[1] <- init_b1 |
| 35 | + mcmc$tau[1] <- 0.2 # init_tau |
| 36 | + |
| 37 | + # Berekening van de posterior voor de startwaarde |
| 38 | + mcmc$post[1] <- ll.fun(beta_0 = mcmc$beta_0[1], |
| 39 | + beta_1 = mcmc$beta_1[1], |
| 40 | + tau = mcmc$tau[1]) + |
| 41 | + prior.fun(beta_0 = mcmc$beta_0[1], |
| 42 | + beta_1 = mcmc$beta_1[1], |
| 43 | + tau = mcmc$tau[1]) |
| 44 | + mcmc$accept[1] <- 1 # De initiële parameterwaarde altijd accepteren |
| 45 | + |
| 46 | + for(i in 2:N){ |
| 47 | + |
| 48 | + # Kies een nieuwe waarde uit een normale verdeling met |
| 49 | + # mean = vorige parameterwaarde en sd = sigma (stapgrootte) |
| 50 | + new_beta_0 <- rnorm(1, mean = mcmc$beta_0[i - 1], sd = sigma) |
| 51 | + new_beta_1 <- rnorm(1, mean = mcmc$beta_1[i - 1], sd = sigma) |
| 52 | + #new_tau <- rnorm(1, mean = mcmc$tau[i - 1], sd = 0.1) |
| 53 | + new_tau <- mcmc$tau[i -1] #we houden tau fixed voor de eenvoud |
| 54 | + |
| 55 | + # Bereken de posterior voor de nieuwe parameterwaarden |
| 56 | + new_post <- ll.fun(beta_0 = new_beta_0, |
| 57 | + beta_1 = new_beta_1, |
| 58 | + tau = new_tau) + |
| 59 | + prior.fun(beta_0 = new_beta_0, |
| 60 | + beta_1 = new_beta_1, |
| 61 | + tau = new_tau) |
| 62 | + |
| 63 | + # Bereken de ratio van de posterios (in de log schaal is dit het verschil) |
| 64 | + log.ratio <- new_post - mcmc$post[i-1] |
| 65 | + |
| 66 | + # Als de ratio > 0 => nieuwe posterior beter = > accepteren |
| 67 | + if (log.ratio > 0) { |
| 68 | + mcmc$accept[i] <- 1 |
| 69 | + # Als log.ratio <= 0 is de kans op accepteren afhankelijk van de log.ratio |
| 70 | + }else{ |
| 71 | + if (rbinom(n = 1, size = 1, prob = exp(log.ratio))) { |
| 72 | + mcmc$accept[i] <- 1 |
| 73 | + }else{ |
| 74 | + mcmc$accept[i] <- 0 |
| 75 | + } |
| 76 | + } |
| 77 | + |
| 78 | + # De nieuwe waarde wordt geaccepteerd |
| 79 | + if(mcmc$accept[i]) { |
| 80 | + mcmc$beta_0[i] <- new_beta_0 |
| 81 | + mcmc$beta_1[i] <- new_beta_1 |
| 82 | + mcmc$tau[i] <- new_tau |
| 83 | + mcmc$post[i] <- new_post |
| 84 | + }else{ |
| 85 | + # De nieuwe waarde wordt niet geaccepteerd (de oude behouden) |
| 86 | + mcmc$beta_0[i] <- mcmc$beta_0[i-1] |
| 87 | + mcmc$beta_1[i] <- mcmc$beta_1[i-1] |
| 88 | + mcmc$tau[i] <- mcmc$tau[i-1] |
| 89 | + mcmc$post[i] <- mcmc$post[i-1] |
| 90 | + } |
| 91 | + } |
| 92 | + return(mcmc = mcmc) |
| 93 | +} |
0 commit comments