Skip to contents

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.

See also

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