Skip to content
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

Add LOO Difference Plot #178

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

ParadaCarleton
Copy link

Implement plot from Bayesian workflow paper

@ParadaCarleton
Copy link
Author

Closes #127

@codecov-commenter
Copy link

codecov-commenter commented May 28, 2021

Codecov Report

Merging #178 (a0417dd) into master (0117858) will decrease coverage by 2.31%.
The diff coverage is 0.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #178      +/-   ##
==========================================
- Coverage   95.15%   92.84%   -2.32%     
==========================================
  Files          28       29       +1     
  Lines        2663     2697      +34     
==========================================
- Hits         2534     2504      -30     
- Misses        129      193      +64     
Impacted Files Coverage Δ
R/loo_difference_plot.R 0.00% <0.00%> (ø)
R/effective_sample_sizes.R 88.18% <0.00%> (-9.45%) ⬇️
R/importance_sampling.R 87.23% <0.00%> (-5.32%) ⬇️
R/loo.R 93.82% <0.00%> (-4.53%) ⬇️
R/loo_moment_matching.R 98.42% <0.00%> (-0.79%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0117858...a0417dd. Read the comment docs.

Copy link
Member

@jgabry jgabry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey Carlos, thanks for working on this! There are a bunch of small things I put in review comments (most of it related to things that matter for package development but not necessarily when writing code outside of package development), but this is a really really great start. Once we sort out some of smaller issues I commented on we can then get some other people, e.g. @avehtari or the other loo package authors to also take a look and see what they think about the plot itself and the different options provided.

alpha = 1,
jitter = 0,
quantiles = FALSE,
sortByGroup = FALSE
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use sort_by_group instead of SortByGroup to match the style already used in the package (and also in this function, e.g. psis_object_1)

#'
#' # Plot using groups from WHO
#'
#' plot_loo_dif(factor(GM@data$super_region_name), loo3, loo2,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like here in the doc it's plot_loo_dif but in the code it's plot_loo_variation.

#'
#' # Plot using groups from WHO
#'
#' plot_loo_dif(factor(GM@data$super_region_name), loo3, loo2,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now none of these examples run because the data GM and loo objects (loo2, loo3) don't exist. For the Examples section in the doc we'll need to change this to a self contained example or add all this data to the loo package itself so it can be used in the example. One possibility is to use a toy example here in the doc and then potentially add a more real example (e.g. this one from the paper) in one of the package vignettes. I'll think a bit more about this too.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is the only problem that's left unresolved; as I mentioned in the email, I'd like to see if it's possible to add this data to the LOO package, since I think the example here is really great.

psis_object_2,
...,
group = FALSE,
outlier_thresh = FALSE,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this argument has documentation

Comment on lines 100 to 106
values <- group_by(tibble(group, elpdDif), factor(group)) %>%
arrange(.by_group = TRUE)

elpdDif <- pull(values, elpdDif)
group <- pull(values, group)

}
Copy link
Member

@jgabry jgabry May 28, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this is using tibble and dplyr code but we should avoid that if possible. I like those packages in general but for package development we don't want to add two new dependencies to the loo package for functionality that can be accomplished without those dependencies, even if the code is a bit more cumbersome.

Comment on lines 109 to 113
plot <- ggplot(mapping=aes(y, elpdDif)) +
geom_hline(yintercept=0) +
xlab(ifelse(sortByGroup, "y", "Index")) +
ylab(expression(ELPD[i][1] - ELPD[i][2])) +
labs(color = "Groups")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to call functions from ggplot (or any other package) inside of the loo package source code we need to prefix them with ggplot2::, e.g. ggplot2::geom_hline().

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example, here are some calls to the parallel package from a different file in the loo package:

loo/R/loo_moment_matching.R

Lines 130 to 133 in 0117858

cl <- parallel::makePSOCKcluster(cores)
on.exit(parallel::stopCluster(cl))
mm_list <- parallel::parLapply(cl = cl, X = I,
fun = function(i) loo_moment_match_i_fun(i))

We need to do the same thing with ggplot2.

psis_object_1,
psis_object_2,
...,
group = FALSE,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use NULL instead of FALSE. To me a default of FALSE gives the impression that the possible values are TRUE and FALSE, but group=TRUE isn't a possible value. So I think NULL makes more sense as the default. Same with outlier_thresh. On the other hand, FALSE makes sense for quantiles since it seems to actually be an argument that needs a logical/boolean value.

#' points. `jitter` can be either a number or a vector of numbers.
#' Passing a single number will jitter variables along the x axis only, while
#' passing a vector will jitter along both axes.
#' @param quantiles Boolean that determines whether to plot the quantiles of
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me quantiles sounds like it would accept vector of quantiles (real valued) as, e.g., dnorm and pnorm. I suggest that quantiles parameter would actually allow to define which quantiles are plotted and the type of the plot would be selected with argument called, e.g., type. With options type='y' (default) and type='quantiles', which would allow then also extending to other possible types- Can you also include example of how these plots look like in the discussion thread of this PR?

Copy link
Author

@ParadaCarleton ParadaCarleton May 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For me quantiles sounds like it would accept vector of quantiles (real valued) as, e.g., dnorm and pnorm.

This does seem like it might be confusing; I think it makes sense to remove this, since users can provide transformations of the values themselves by replacing y.

I suggest that quantiles parameter would actually allow to define which quantiles are plotted and the type of the plot would be selected with argument called, e.g., type. With options type='y' (default) and type='quantiles', which would allow then also extending to other possible types

I'm not sure what you mean here; could you elaborate?

Can you also include example of how these plots look like in the discussion thread of this PR?

Will do.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If users can provide transformations of the values themselves by replacing y, and this option is not needed then I think removing it as you did is the correct action and you don't need to care about the rest I said.

@ParadaCarleton
Copy link
Author

@avehtari I've added an example of a plot using the IQ dataset from rstanarm:
image
The first model only has a constant intercept; the second model also includes a term for the mother's IQ. At the edges, the constant-based model is more accurate than the full model, while the IQ-based model is stronger in the center. This seems counterintuitive, until you realize that this reveals there is significant measurement error in IQ tests: extreme values are probably caused by mismeasurement and need to be adjusted for regression to the mean.

Other examples:
unnamed
0

@avehtari
Copy link
Collaborator

The plots looks great! Thanks for making this PR!

@ParadaCarleton
Copy link
Author

The plots looks great! Thanks for making this PR!

Thanks! Do you happen to know if the spatial data from the Bayesian visualization paper can be added to the loo package? I think it's a good example, but if it can't, I can remove it.

@jgabry
Copy link
Member

jgabry commented Jun 7, 2021

Sorry for the delay in responding to this. Regarding the issue of including the data from the visualization paper, I think we should avoid adding it to the package but I think there's still a way we can still use it. Basically, we should use a different example in the Examples section in the documentation, but then we can add an example using the visualization paper data in one of the vignettes. This works because in the vignette we're allowed to download data that isn't included in the package. For example, we do this already in one of the vignettes with some other data:

url <- "http://stat.columbia.edu/~gelman/arm/examples/arsenic/wells.dat"
wells <- read.table(url)

So we could do something similar and download the visualization paper data from https://github.com/jgabry/bayes-vis-paper. @ParadaCarleton What do you think about that option?

@ParadaCarleton
Copy link
Author

ParadaCarleton commented Jun 7, 2021

Sorry for the delay in responding to this. Regarding the issue of including the data from the visualization paper, I think we should avoid adding it to the package but I think there's still a way we can still use it. Basically, we should use a different example in the Examples section in the documentation, but then we can add an example using the visualization paper data in one of the vignettes. This works because in the vignette we're allowed to download data that isn't included in the package. For example, we do this already in one of the vignettes with some other data:

url <- "http://stat.columbia.edu/~gelman/arm/examples/arsenic/wells.dat"
wells <- read.table(url)

So we could do something similar and download the visualization paper data from https://github.com/jgabry/bayes-vis-paper. @ParadaCarleton What do you think about that option?

Sounds good! I've removed the example. Where do you think I should put this -- should I add it to an existing vignette or create a new one?

@jgabry
Copy link
Member

jgabry commented Jun 7, 2021

Where do you think I should put this -- should I add it to an existing vignette or create a new one?

Hmm, on the one hand I think it could be nice to have it in the main introduction vignette https://mc-stan.org/loo/articles/loo2-example.html. On the other hand, this would be using a totally different data set than the example in that vignette, so that's not ideal and maybe a new vignette is preferable.

I think if we go the route of a new vignette then it shouldn't just be about this one plot but rather about visualizing loo output in general (e.g., this plot, the Pareto k diagnostic plot, perhaps some of the loo related plots in bayesplot, etc.). But that would be more work than just adding this to an existing vignette so it depends how much you feel like working on this (no pressure!).

@ParadaCarleton
Copy link
Author

@jgabry btw, I think we should merge this, unless there's some change you'd like to see. I might be able to get to building a vignette before classes start again, but given that I'm focused on adding new features to ParetoSmooth.jl I'm not sure I'll be able to. We can probably add this to some other vignette later.

@avehtari
Copy link
Collaborator

@ParadaCarleton and @jgabry , what is the status of this PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants