I think the confusion is that there's not a matrix per-se that's output here.
It's the behavior of the print() function on the fit object. The fit object
separates the samples by chain and structures them by parameter, I believe.
But I'm not familiar with the internals.
We really want to nail down the details rather than have them trickled
out as you realize there are things you don't like. Unless you literally
mean exactly this output is OK for you.
Should the quantiles be progammable?
Would you rather defaults other than 2.5%, 25%, 50%, etc? If so, should
we change CmdStan's print to match (it's now just doing 90% intervals and
50% quantile, I think).
Is the camel-case "Rhat" OK along with the C++-like "n_eff"?
>> Don't you like structured objects here? So if "Sigma" is an M x N
>> parameter, how do I access the summary stats for Sigma[m,n]?
>
> Sure, we could do that, but that seems like a lot of work to me and it's not clear that there are many cases where people will want to access the summaries in that way. That said, perhaps it would be logical to have a primitive function that computes mean, se_mean, sd, quantiles, n_eff, and Rhat for a single scalar parameter. Also I'm not actually quite sure how we are computing n_eff, Rhat, etc. for constrained parameters such as cov matrices.
I'm not sure which is easier given the existing structure.
But it is a question of what you want. With only a flat
structure, it's a pain to pull out a summary for just an array.
Should we be able to create sub-summary objects? That is,
take a summary, give it a sequence of parameter names and
get a new summary back? I don't know if that's how print works
or whether print gets more arguments for the things to print.
The point is that all of this needs to be specified and documented.
You can look at the existing doc now, which is pretty thorough, to decide
if things behave the way you want them to.
I'm pretty sure we're computing n_eff and Rhat with the constrained
values directly. If that's wrong, we need a deeper rethink of what's
going on. They are all (inverse) transforms of the unconstrained
parameters.
>>> foo.waic <- stan_waic_xval(foo.fit.multiple): returns a list of waic, elpd_waic, p_waic, elpd_loo, p_loo, pointwise, total, and se. This function only works if one of the returned parameters in foo.fit.multiple is something called log_lik. If there is no log_lik, it returns NULL. We could start with the function on page 14-15 of this paper:
http://www.stat.columbia.edu/~gelman/research/unpublished/waic_stan.pdf
>>>
>>
>> So you want a list rather than an object so you're OK with users
>> getting p_loo using the syntax foo.waic$p_loo or foo.waic[["p_loo"]]?
>
> I don't have a strong feeling here. It somehow seems like overkill to have extractor functions for all of these, but maybe that would be simpler, to just have functions waic(), elpd_waic(), p_waic(), elpd_loo(), p_loo(), etc. This might be easiest for the user. But if we do it that way, we will have to relabel "pointwise", "total", and "se". Also we have to decide if we want the "stan_" prefix for all these functions.
OK --- I was just reacting to you saying you didn't want to see
the $ signs.
I think the point is that they'd be methods on an object, so you'd
doc them along with the WAIC return object, not as standalone functions.
For example, you don't see "print" documented directly when you look at the
RStan index --- you see print.stanfit. So it'd be something like
total.waic in the index if we added a total() method to the WAIC object.
Assuming you want the return type of doing WAIC to be an object.
I have no idea what people usually do in R, what users are comfortable
with, and what's the recommended practice.
>
>> Unless p_loo corresponds to a leave-one-out cross-validation, this
>> seems like a confusing name.
>
> Yes, loo is leave-one-out cross-validation, as described in the paper.
I see --- it's "truncated importance-sampling LOO". That's a bit of
a mouthful in a variable name.
>> We'll need doc for what each of these elements is. What I really want
>> in all of our RStan and PyStan doc is:
>>
>> argument types: what kind of R object do you pass in?
>>
>> argument content: what is the argument?
>>
>> argument constraints: what constraints on the arguments passed in
>> are there, either singly or in conjunction.
>>
>> return type: what type of object does it return
>> what is the content of that object field by field
>>
>> And speaking of names, looks like you're torn between using something
>> like "_summarize()" that's a verb and "_summary()" which is the current
>> function name in R.
>
> I don't recall using "summarize". I was trying to use "summary" to be roughly consistent with R.
The point is that R's not consistent. It uses "optimize" and "summary", which
are a verb and a noun. The optimize function creates an list object and
the summary function returns a value that depends on what it's summarizing.
This is the same issue as logLik, which is what R calls it and what we'd need
to call it as a method in order for R's general logLik() function to work on
our fit objects the way they do on a glm() output. We can either go with what R uses for
compatibility with R or we can try to make Stan internally consistent.
It's not a huge deal --- I'm resigned to the fact that naming can never
be made consistent because of inconsistent existing standards (at least
that's the case in Java, C++, R, and everything else I've ever used).
- Bob