@@ -228,6 +228,116 @@ ggplotly(ggplot(pop_posterior_lognormal_independent, aes(x=value, fill=source, a
228228 geom_histogram(bins = 50 , position = ' identity' , alpha = 0.5 )+
229229 theme_minimal())
230230
231+ # Fit a hierarchical model ------------------------------------------------
232+
233+
234+ pars_lognormal_hierarchical_cp <- c(' alpha_national' ,' alpha_settlement' , ' u_alpha_settlement' , ' sigma' , ' pop_post_pred' )
235+
236+ fit_poisson_lognormal_hierarchical_cp <- stan(
237+ file = here(' tutorials' , ' refresher' ,' poisson_hierarchical_cp.stan' ),
238+ data = input_data ,
239+ iter = iter + warmup ,
240+ warmup = warmup ,
241+ seed = seed ,
242+ pars = pars_lognormal_hierarchical_cp
243+ )
244+
245+ traceplot(fit_poisson_lognormal_hierarchical_cp , pars = ' alpha_settlement' )
246+ traceplot(fit_poisson_lognormal_hierarchical_cp , pars = ' alpha_national' )
247+ traceplot(fit_poisson_lognormal_hierarchical_cp , pars = ' u_alpha_settlement' )
248+ traceplot(fit_poisson_lognormal_hierarchical_cp , pars = ' sigma' )
249+
250+ samples_poisson_lognormal_hierarchical_cp <- rstan :: extract(fit_poisson_lognormal_hierarchical_cp )
251+
252+
253+ # prior retrodictive check
254+ alpha <- as_tibble(samples_poisson_lognormal_hierarchical_cp $ alpha_settlement )
255+ colnames(alpha ) <- c(' posterior_alpha_settlement_1' , ' posterior_alpha_settlement_2' )
256+
257+ alpha <- alpha %> %
258+ mutate (
259+ posterior_alpha_national = samples_poisson_lognormal_hierarchical_cp $ alpha_national ,
260+ prior = abs(rnorm(chains * iter , log(500 ), 0.1 )),
261+ iter = 1 : (chains * iter )
262+ ) %> %
263+ pivot_longer(- iter , names_to = ' distribution' )
264+
265+ ggplot(alpha , aes(x = value , fill = distribution ))+
266+ geom_histogram(bins = 100 ,position = ' identity' , alpha = 0.7 )+
267+ theme_minimal()
268+
269+ comp_alpha <- rbind(
270+ alpha %> %
271+ mutate(
272+ distribution = paste0(distribution , ' _hierarchical' ),
273+ model = ' hierarchical'
274+ ),
275+ alpha_settlement %> %
276+ mutate(
277+ distribution = paste0(distribution , ' _independant' ),
278+ model = ' independant'
279+ )
280+ ) %> %
281+ filter(! grepl(' prior' ,distribution ))
282+
283+
284+ ggplot(comp_alpha , aes(x = value , y = distribution , fill = model ))+
285+ geom_boxplot()+
286+ theme_minimal()+
287+ guides(fill = ' none' )
288+
289+ comp_alpha %> %
290+ group_by(distribution ) %> %
291+ summarise(
292+ mean(value ),
293+ sd(value ),
294+ quantile(value , probs = 0.025 ),
295+ quantile(value , probs = 0.975 )
296+
297+ )
298+
299+
300+ pop_posterior_lognormal_hierarchical <- tibble(
301+ source = factor (c(
302+ rep(' predicted_poisson_lognormal_independent' , iter * chains * input_data $ n_obs ),
303+ rep(' predicted_poisson_lognormal_hierarchical' , iter * chains * input_data $ n_obs ),
304+ rep(' observed' , input_data $ n_obs )),
305+ levels = c(' observed' ,
306+ ' predicted_poisson_lognormal_hierarchical' ,
307+ ' predicted_poisson_lognormal_independent' )),
308+ value = c(
309+ as.vector(samples_poisson_lognormal_independent $ pop_post_pred ),
310+ as.vector(samples_poisson_lognormal_hierarchical_cp $ pop_post_pred ),
311+ input_data $ pop )
312+ )
313+
314+
315+ ggplotly(ggplot(pop_posterior_lognormal_hierarchical , aes(x = value , fill = source , after_stat(density )))+
316+ geom_histogram(bins = 50 , position = ' identity' , alpha = 0.5 )+
317+ theme_minimal())
318+
319+
320+ # New validation: cluster-based
321+ comp_obs_poisson_lognormal_hierarchical_cp <- as_tibble(samples_poisson_lognormal_hierarchical_cp $ pop_post_pred ) %> %
322+ summarise(across(
323+ everything(), ~ c(mean(. ), quantile(. , probs = c(0.025 , 0.5 , 0.975 )))
324+ )) %> %
325+ mutate(
326+ metrics = c(' mean' , paste0(' q' , c(0.025 , 0.5 , 0.975 )))
327+ ) %> %
328+ pivot_longer(
329+ - metrics
330+ ) %> %
331+ pivot_wider(names_from = metrics , values_from = value ) %> %
332+ mutate(
333+ obs = input_data $ pop
334+ )
335+
336+ ggplot(comp_obs_poisson_lognormal_hierarchical_cp , aes(x = obs , y = q0.5 , ymin = q0.025 , ymax = q0.975 ))+
337+ geom_pointrange(col = ' grey20' )+
338+ theme_minimal()+
339+ labs(x = ' observations' , y = ' predictions' )+
340+ geom_abline(intercept = 0 , slope = 1 , size = 1 , color = ' orange' )
231341
232342# What about breaking down the variance? -----------------------------------
233343
0 commit comments