-
-
Notifications
You must be signed in to change notification settings - Fork 37
add diff diagnostics #300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
add diff diagnostics #300
Changes from 2 commits
a909cea
b940192
6fe41bb
fa0d79d
65ef286
b0ebac7
7410b81
b993b44
b118da2
25f93fd
62027d1
cc3edfe
22f442f
ca843f4
d579c06
cf20250
846a891
64b365c
185e570
8625e10
64a19c3
a84154e
16f67d4
9b43e06
4e16d2f
23a79c0
cff3c2c
8f521a5
dc9db69
3ed1c0c
89d39f5
6d73537
abcf209
794ffb0
a375c93
f3fcb28
359853a
b7db7dd
77e753f
c59414e
93fdbff
ae48d69
4f5872b
574af4f
3d008e9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -116,7 +116,30 @@ loo_compare.default <- function(x, ...) { | |
| diffs <- mapply(FUN = elpd_diffs, loos[ord[1]], loos[ord]) | ||
| elpd_diff <- apply(diffs, 2, sum) | ||
| se_diff <- apply(diffs, 2, se_elpd_diff) | ||
| comp <- cbind(elpd_diff = elpd_diff, se_diff = se_diff, comp) | ||
| # compute probabilities that a model has worse elpd than the best model | ||
| # using a normal approximation (Sivula et al., 2025) | ||
| p_worse <- pnorm(0, elpd_diff, se_diff) | ||
| p_worse[elpd_diff==0] <- NA | ||
| N <- nrow(diffs) | ||
| # diagnostics to assess whether the normal approximation can be trusted | ||
| if (N<100) { | ||
| # small N (Sivula et al., 2025) | ||
| diag_pnorm <- rep("N < 100", length(elpd_diff)) | ||
| diag_pnorm[elpd_diff==0] = "" | ||
| } else { | ||
| diag_pnorm <- rep("", length(elpd_diff)) | ||
| # similar predictions (Sivula et al., 2025) | ||
| diag_pnorm[elpd_diff>-4 & elpd_diff!=0] <- "similar predictions" | ||
| # possible outliers in differences (Sivula et al., 2025; | ||
| # Vehtari et al., 2024) | ||
| khat_diff <- rep(NA, length(elpd_diff)) | ||
| khat_diff[elpd_diff!=0] <- apply(diffs[,elpd_diff!=0, drop = FALSE], 2, \(x) posterior::pareto_khat(x, tail="both")) | ||
| diag_pnorm[khat_diff > ps_khat_threshold(N)] <- paste0("khat_diff > ", .fr(ps_khat_threshold(N), 2)) | ||
| } | ||
| rownames(comp) <- rnms | ||
| comp <- cbind(data.frame(elpd_diff = elpd_diff, se_diff = se_diff, | ||
|
||
| p_worse = p_worse, diag_pnorm = diag_pnorm), | ||
| as.data.frame(comp)) | ||
| rownames(comp) <- rnms | ||
|
|
||
| # run order statistics-based checks on models | ||
|
|
@@ -131,9 +154,10 @@ loo_compare.default <- function(x, ...) { | |
| #' @param digits For the print method only, the number of digits to use when | ||
| #' printing. | ||
| #' @param simplify For the print method only, should only the essential columns | ||
| #' of the summary matrix be printed? The entire matrix is always returned, but | ||
| #' by default only the most important columns are printed. | ||
| print.compare.loo <- function(x, ..., digits = 1, simplify = TRUE) { | ||
| #' of the summary matrix be printed? The entire matrix is always returned, bu#' @param pnorm For the print method only, should we include the normal | ||
| #' approximation based probability of model having worse performance than | ||
| #' the best model | ||
avehtari marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| print.compare.loo <- function(x, ..., digits = 1, simplify = TRUE, pnorm = FALSE) { | ||
| xcopy <- x | ||
| if (inherits(xcopy, "old_compare.loo")) { | ||
| if (NCOL(xcopy) >= 2 && simplify) { | ||
|
|
@@ -143,12 +167,16 @@ print.compare.loo <- function(x, ..., digits = 1, simplify = TRUE) { | |
| } else if (NCOL(xcopy) >= 2 && simplify) { | ||
| xcopy <- xcopy[, c("elpd_diff", "se_diff")] | ||
| } | ||
| print(.fr(xcopy, digits), quote = FALSE) | ||
| invisible(x) | ||
| if (p_worse) { | ||
jgabry marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| print(cbind(.fr(xcopy, digits), p_worse=.fr(x[,"p_worse"],2), diag_pnorm=x[, "diag_pnorm"]), quote = FALSE) | ||
| invisible(x) | ||
| } else { | ||
| print(cbind(.fr(xcopy, digits), quote = FALSE)) | ||
avehtari marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| invisible(x) | ||
| } | ||
| } | ||
|
|
||
|
|
||
|
|
||
| # internal ---------------------------------------------------------------- | ||
|
|
||
| #' Compute pointwise elpd differences | ||
|
|
@@ -172,7 +200,6 @@ se_elpd_diff <- function(diffs) { | |
| sqrt(N) * sd(diffs) | ||
| } | ||
|
|
||
|
|
||
| #' Perform checks on `"loo"` objects before comparison | ||
| #' @noRd | ||
| #' @param loos List of `"loo"` objects. | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.