Converts a fitted state into a mixture. By default the weights come across as they stand and nothing is dropped.
Usage
ripr_finish(
state,
threshold = 0,
correct_weights = FALSE,
identify = FALSE,
record_gap = FALSE,
max_rounds = 10L
)Arguments
- state
A ripr_state.
- threshold
Drop atoms with weight at or below this. Must be below 1.
- correct_weights
Re-solve the weights before dropping any. Off by default.
- identify
Zero atoms whose removal does not increase KL. Off by default.
- record_gap
Sweep the Frank–Wolfe oracle over the returned mixture, filling
gap_final. Off by default, since it costs a full oracle sweep.- max_rounds
Cap on refinement rounds.
Value
A ripr_fit, whose W0 is the mixing measure (a finite_dist),
P_star the mixture it induces, and kl, gap_fit and gap_final
describe it. The state it was finished from, with its trace and
snapshots, is kept as fit@state.
Details
Experimental: two optional refinements, both off by default.
correct_weights re-solves the weights over the current atoms, as
weight_step() does.
identify zeroes, lightest first, each atom whose removal does not increase
KL. With both on they alternate until a round removes nothing. They are sound
only because the atoms have stopped moving; identify never increases KL but
does not certify that a removed atom is zero at the optimum.
Atoms with weight at or below threshold are then dropped: by default only
those identify zeroed. A positive value may raise KL.
Refining lowers KL but can raise the gap, since the weights are optimised over the current support and dropping atoms leaves more of the null uncovered. Choose according to whether you want the fit or a certificate resting on the gap.
References
Fercoq O, Gramfort A, Salmon J (2015). “Mind the duality gap: safer rules for the Lasso.” In Bach F, Blei D (eds.), Proceedings of the 32nd International Conference on Machine Learning, volume 37 of Proceedings of Machine Learning Research, 333–342. https://proceedings.mlr.press/v37/fercoq15.html.
Examples
set.seed(1)
fam <- multinomial_family(n_trials = 4L, k = 3L)
plurality <- null_model(
fam,
list(
simplex_region(vertices = rbind(c(0.5, 0.5, 0), c(0, 1, 0), c(0, 0, 1))),
simplex_region(vertices = rbind(c(0.5, 0, 0.5), c(0, 1, 0), c(0, 0, 1)))
)
)
Q <- fam(c(0.4, 0.35, 0.25))
state <- ripr_init(Q, plurality) |> fw_step(times = 10L)
fit <- ripr_finish(
state,
correct_weights = TRUE,
identify = TRUE,
record_gap = TRUE
)
fit
#> <ripr_fit>
#> mixture multinomial_family mixed over 3 atoms
#> KL 0.00348918
#> gap 0.00171 final, 0.00937 while fitting
#> refined 1 round
#> trace 11 rows, 0 snapshots
fit@kl
#> [1] 0.003489178
fit@gap_fit
#> [1] 0.009371803
fit@gap_final
#> [1] 0.001711678