# Visualization 15: Bayesian interpretation (posterior probability)
# Simple Bayesian analysis using normal approximation
# Prior: Normal(0, 1) - skeptical prior
# Likelihood: Normal(observed_diff, SE)
# Posterior: Normal with updated mean and variance
se_diff <- sqrt(var(chatbot_change)/length(chatbot_change) + var(usual_change)/length(usual_change))
prior_mean <- 0
prior_sd <- 1
likelihood_mean <- observed_diff
likelihood_sd <- se_diff
# Posterior parameters
posterior_precision <- 1/prior_sd^2 + 1/likelihood_sd^2
posterior_sd <- sqrt(1/posterior_precision)
posterior_mean <- (prior_mean/prior_sd^2 + likelihood_mean/likelihood_sd^2) / posterior_precision
# Calculate probability that effect > 0
prob_positive <- 1 - pnorm(0, posterior_mean, posterior_sd)
# Create Bayesian plot
x_vals <- seq(-2, 2, by = 0.01)
prior_density <- dnorm(x_vals, prior_mean, prior_sd)
likelihood_density <- dnorm(x_vals, likelihood_mean, likelihood_sd)
posterior_density <- dnorm(x_vals, posterior_mean, posterior_sd)
bayesian_data <- data.frame(
x = rep(x_vals, 3),
density = c(prior_density, likelihood_density, posterior_density),
distribution = rep(c("Prior", "Likelihood", "Posterior"), each = length(x_vals))
)
# Define annotation positions for easy adjustment
posterior_x <- -1.99
posterior_y_start <- 0.8
likelihood_x <- -1.99
likelihood_y_start <- 0.5
interpretation_x <- -0.4
interpretation_y_start <- 0.85
null_x <- 0.1
null_y_start <- 0.6
prior_x <- 0.8
prior_y_start <- 0.4
bayesian_plot <- ggplot(bayesian_data, aes(x = x, y = density, color = distribution)) +
geom_line(linewidth = 1.5) +
geom_vline(xintercept = 0, color = "red", linewidth = 1, linetype = "dashed") +
geom_vline(xintercept = posterior_mean, color = "blue", linewidth = 2) +
# Reposition posterior mean text to avoid overlap and fix blurriness
annotate("text", x = posterior_mean + 0.1, y = max(posterior_density) + 0.05,
label = paste0("Posterior mean = ", round(posterior_mean, 3), " (confidence = ", round(dnorm(posterior_mean, posterior_mean, posterior_sd) * 100, 1), "%)"),
color = "blue", size = 3, hjust = 0, fontface = "bold") +
# Add comprehensive explanations for each distribution
# POSTERIOR annotation (top left) - moved up more and left more
annotate("text", x = posterior_x, y = posterior_y_start,
label = "POSTERIOR (Blue):", size = 3, fontface = "bold", hjust = 0, color = "darkblue") +
annotate("text", x = posterior_x, y = posterior_y_start - 0.05,
label = "Updated belief after data", size = 2.5, hjust = 0, color = "darkblue") +
annotate("text", x = posterior_x, y = posterior_y_start - 0.08,
label = paste0("Confidence in posterior mean = ", round(dnorm(posterior_mean, posterior_mean, posterior_sd) * 100, 1), "%"), size = 2.5, hjust = 0, color = "darkblue") +
annotate("text", x = posterior_x, y = posterior_y_start - 0.11,
label = "Combines prior + likelihood", size = 2.5, hjust = 0, color = "darkblue") +
annotate("text", x = likelihood_x, y = likelihood_y_start,
label = "LIKELIHOOD (Orange):", size = 3, fontface = "bold", hjust = 0, color = "darkorange") +
annotate("text", x = likelihood_x, y = likelihood_y_start - 0.05,
label = "H0: No difference vs H1: Some difference", size = 2.5, hjust = 0, color = "darkorange") +
annotate("text", x = likelihood_x, y = likelihood_y_start - 0.08,
label = paste0("Observed difference = ", round(observed_diff, 3)), size = 2.5, hjust = 0, color = "darkorange") +
annotate("text", x = likelihood_x, y = likelihood_y_start - 0.11,
label = paste0("Confidence in observed effect = ", round(dnorm(observed_diff, observed_diff, likelihood_sd) * 100, 1), "%"), size = 2.5, hjust = 0, color = "darkorange") +
# PRIOR annotation (top right) - moved up more
annotate("text", x = prior_x, y = prior_y_start,
label = "PRIOR (Grey):", size = 3, fontface = "bold", hjust = 0) +
annotate("text", x = prior_x, y = prior_y_start - 0.05,
label = "Skeptical belief before data", size = 2.5, hjust = 0) +
annotate("text", x = prior_x, y = prior_y_start - 0.08,
label = "Centered at 0 (no effect)", size = 2.5, hjust = 0) +
annotate("text", x = prior_x, y = prior_y_start - 0.11,
label = "Wide spread = uncertainty", size = 2.5, hjust = 0) +
# Add interpretation of the null hypothesis line
annotate("text", x = null_x, y = null_y_start,
label = "NULL HYPOTHESIS (Red):", size = 3, fontface = "bold", hjust = 0, color = "darkred") +
annotate("text", x = null_x, y = null_y_start - 0.05,
label = "H0: No treatment effect", size = 2.5, hjust = 0, color = "darkred") +
annotate("text", x = null_x, y = null_y_start - 0.08,
label = "Values < 0 = Usual care better", size = 2.5, hjust = 0, color = "darkred") +
annotate("text", x = null_x, y = null_y_start - 0.11,
label = "Values > 0 = Chatbot better", size = 2.5, hjust = 0, color = "darkred") +
# Add natural language interpretation aligned with NULL HYPOTHESIS
annotate("text", x = interpretation_x, y = interpretation_y_start,
label = "INTERPRETATION:", size = 3, fontface = "bold", hjust = 0, color = "darkgreen") +
annotate("text", x = interpretation_x, y = interpretation_y_start - 0.05,
label = paste0("If I had 50% credence that there was no difference"), size = 2.5, hjust = 0, color = "darkgreen") +
annotate("text", x = interpretation_x, y = interpretation_y_start - 0.08,
label = paste0("before this evidence, after updating on ONLY this"), size = 2.5, hjust = 0, color = "darkgreen") +
annotate("text", x = interpretation_x, y = interpretation_y_start - 0.11,
label = paste0("I should now believe it with confidence of ", round(prob_positive * 100, 1), "%"), size = 2.5, hjust = 0, color = "darkgreen") +
annotate("text", x = interpretation_x, y = interpretation_y_start - 0.14,
label = paste0("Prior confidence in effect size = ", round(dnorm(observed_diff, 0, 1) * 100, 1), "%"), size = 2.5, hjust = 0, color = "darkgreen") +
annotate("text", x = interpretation_x, y = interpretation_y_start - 0.17,
label = paste0("After updating: confidence in effect size = ", round(dnorm(observed_diff, posterior_mean, posterior_sd) * 100, 1), "%"), size = 2.5, hjust = 0, color = "darkgreen") +
labs(title = "Bayesian Analysis: Prior, Likelihood, and Posterior",
subtitle = paste("Confidence in posterior mean =", round(dnorm(posterior_mean, posterior_mean, posterior_sd) * 100, 1), "%",
"| Posterior mean =", round(posterior_mean, 3)),
x = "Effect Size (Difference in PHQ-9 Change)", y = "Density",
caption = "Red line = H0 (no effect) | Blue line = Posterior mean | Gray = Prior | Orange = Likelihood | Blue = Posterior") +
theme_minimal() +
theme(plot.title = element_text(hjust = 0.5),
plot.subtitle = element_text(hjust = 0.5)) +
scale_color_manual(values = c("Prior" = "gray", "Likelihood" = "orange", "Posterior" = "blue"))
print(bayesian_plot)