@@ -14,10 +14,10 @@ Developer Notes: `pred_measure` Feature
1414
1515> ** Status:** In Progress
1616> ** Base branch:** ` loo-v3.0.0 `
17- > ** Compare branch:** ` add-pred-measure `
17+ > ** Compare branch:** ` pred_measure ` (+ ` integrate-loo_compare ` )
1818> ** Related PR:** [ \# 363] ( https://github.com/stan-dev/loo/pull/363 )
1919> ** Contributors:** @florence-bockting , @avehtari , @VisruthSK , @jgabry
20- > ** Last updated:** 2026-07-03
20+ > ** Last updated:** 2026-07-07
2121
2222These notes document internal design decisions and ongoing work for the
2323` pred_measure ` feature. This PR ** adds** the new API on top of
@@ -39,7 +39,7 @@ For the merge summary, see the PR description
3939| Scoring rules (` measure_rps ` ) | Done |
4040| Documentation | In progress |
4141| ` group_ids ` grouping | Not started |
42- | ` loo_compare ` integration | Not started |
42+ | ` loo_compare ` integration | Done ( ` integrate-loo_compare ` ) |
4343
4444------------------------------------------------------------------------
4545
@@ -59,6 +59,8 @@ For the merge summary, see the PR description
5959- Website-only articles: ` overview-measures.Rmd ` ,
6060 ` pred-measure-workflow.Rmd `
6161- Test suite + pre-fitted fixtures + ` test_data_generation.R `
62+ - ` loo_compare() ` multi-measure path for ` loo_pred_measure ` objects
63+ (` integrate-loo_compare ` )
6264
6365### Changed on existing code (implementations retained)
6466
@@ -69,6 +71,11 @@ For the merge summary, see the PR description
6971- ` elpd() ` — refactored to ` .elpd_matrix_impl() ` to avoid double
7072 deprecation warnings
7173- Minor doc cross-references in ` compare.R ` , ` psislw.R `
74+ - ` loo_compare() ` — extended for ` loo_pred_measure ` objects: ` rank_by ` ,
75+ multi-measure paired diffs, updated ` print.compare.loo(measures = ...) ` ;
76+ classic ` loo ` path unchanged
77+ - ` R/loo-glossary.R ` — multi-measure comparison columns (` {measure}_diff ` ,
78+ ` rank_by ` , etc.)
7279- ` NEWS.md ` , ` NAMESPACE ` , ` _pkgdown.yml ` , pkgdown CI workflow
7380
7481------------------------------------------------------------------------
@@ -127,17 +134,51 @@ Design choices **internal to `pred_measure`** (not a migration from
127134 examples end-to-end (penguins fixture exists; confirm test/doc
128135 coverage)
129136
137+ ### D4: ` loo_compare() ` for ` loo_pred_measure ` objects
138+
139+ ** Decision:** Extend existing ` loo_compare() `
140+
141+ - When all inputs are ` loo_pred_measure ` objects, compute paired
142+ differences for every measure common to all models
143+ - Rank models by ` rank_by ` (default ` "elpd" ` ); top-ranked model is the
144+ reference for all ` {measure}_diff ` columns
145+ - ELPD-family measures keep ` elpd_diff ` / ` se_diff ` ; other measures use
146+ ` {measure}_diff ` / ` {measure}_se_diff `
147+ - ` p_worse ` and ` diag_diff ` apply to ELPD only; ` diag_elpd ` per model as
148+ before
149+ - Loss measures (MSE, RMSE, MAE, IC, Brier score, SRPS) compared on a common
150+ utility scale (higher is better): sign flipped from the raw loss orientation
151+ so worse models have negative diffs, consistent with ELPD. Orientation is
152+ read from ` measure_revert_sign ` on each ` *_pred_measure() ` result; result
153+ attribute
154+ ` sign_converted_measures ` records affected measures. A short message is
155+ emitted at compare time; full interpretation is in ` ?loo_compare ` /
156+ ` ?loo-glossary ` .
157+ - Pointwise SEs use the same paired formula as ELPD when the overall
158+ estimate is a sum or mean of pointwise contributions; otherwise
159+ ` {measure}_se_diff ` is ` NA ` (e.g. ` r2 ` , ` mse ` , ` rmse ` )
160+ - Reuse ` elpd_diffs ` , ` se_elpd_diff ` , ` diag_diff ` , ` diag_elpd ` , and
161+ many-model order-statistic check (with ` rank_by ` when applicable)
162+ - ` print.compare.loo(measures = ...) ` shows one or all measure diff tables
163+
164+ Implemented on branch ` integrate-loo_compare ` ; tests in ` test_compare.R `
165+ with fixture ` test_data_roaches_compare.Rds ` .
166+
130167------------------------------------------------------------------------
131168
132169## Open decisions
133170
134171### D1: Sign convention for pointwise estimates
135172
136- - ** Context:** Measures differ in orientation (` rps ` : lower is better;
137- ` srps ` : higher is better). Aligning orientations may help comparisons.
138- - ** Options:** ` lower_is_better ` , ` orientation = "utility" / "loss" ` ,
139- ` revert_sign ` (currently internal on some ` measure_*() ` functions)
140- - ** Decision:** * pending*
173+ - ** Context:** Measures differ in orientation (e.g. ELPD/CRPS on a utility
174+ scale; MSE and Brier score as losses). ` loo_compare() ` aligns them for
175+ paired differences.
176+ - ** Decision (for ` loo_compare ` ):** Each ` *_pred_measure() ` result stores the
177+ ` revert_sign ` value used per measure in ` measure_revert_sign ` . Built-in loss
178+ measures are sign-flipped for utility-scale ` {measure}_diff ` when
179+ ` revert_sign ` is ` FALSE ` .
180+ - ** Still open:** Whether to expose orientation metadata on ` *_pred_measure() `
181+ results themselves (e.g. when ` revert_sign = TRUE ` in ` control ` ).
141182
142183### D3: Handling of ` r_eff `
143184
@@ -163,7 +204,7 @@ Design choices **internal to `pred_measure`** (not a migration from
163204 require explicit ` measure = "ic" ` for information criterion
164205- [x] Document and test deprecated vs new API comparisons * (see
165206 appendix)*
166- - [ ] Provide an interface to ` loo_compare ` and verify consistency
207+ - [x ] Provide an interface to ` loo_compare ` and verify consistency
167208- [ ] Resolve ` r_eff ` handling * (see D3)*
168209
169210### Implementation
@@ -181,8 +222,9 @@ Design choices **internal to `pred_measure`** (not a migration from
181222- [x] Online-only articles published via ` _pkgdown.yml `
182223- [ ] Formula derivations article (` pred_measure-formulas.Rmd ` )
183224- [ ] Detailed per-measure descriptions (derivations where appropriate)
184- - [ ] Extend glossary (` R/loo-glossary.R ` ) — measure, metric, score,
185- utility, loss
225+ - [x] Extend glossary (` R/loo-glossary.R ` ) — multi-measure ` loo_compare ` columns
226+ - [ ] Extend glossary further — measure, metric, score, utility, loss
227+ (general terms)
186228
187229### Grouping via ` group_ids `
188230
@@ -200,8 +242,9 @@ Design choices **internal to `pred_measure`** (not a migration from
200242
201243- Rename ` ic ` → ` information_criteria ` for clarity?
202244- Should ` measure_elpd() ` also return ` ic ` , or keep them separate?
203- - What defines class ` "loo" ` on measure objects? (e.g. deprecated
204- ` elpd_generic ` inherits ` "loo" ` )
245+ - What defines class ` "loo" ` on measure objects? ` loo_pred_measure ` inherits
246+ ` "loo" ` (see ` integrate-loo_compare ` ); deprecated ` elpd_generic ` also
247+ inherits ` "loo" ` .
205248- Should ` elpd ` always be computed when ` ylp ` is supplied, or allow
206249 ` loo_pred_measure() ` for non-ELPD measures only?
207250
0 commit comments