github facebookresearch/balance 0.22.0
# 0.22.0 (2026-07-15)

8 hours ago

New Features

  • BalanceDFOutcomes.relative_response_rates() now accepts an explicit relative_to={"self", "target"} denominator selector while preserving the existing target= API.
  • The CLI now exposes IPW penalty_factor through --penalty_factor, accepting either comma-separated numbers or a JSON list and forwarding the parsed list into Sample.adjust().
  • The CLI now validates --transformations at parse time, accepting only the supported default and None command-line modes.
  • rake() now accepts keyword-only target_margins dictionaries so callers with known marginal distributions can fit raking weights without first constructing a row-level target frame.

Code Quality & Refactoring

  • Breaking: IPW fit metadata now stores training design weights under the
    canonical training_sample_weights / training_target_weights keys used by
    predict_weights(). The old fit_sample_weights / fit_target_weights
    model-dict keys are no longer emitted; downstream code that reads
    ipw(...)["model"] directly should switch to the training_* names. Stored
    fit matrices are copied before being persisted so sample and target caches
    cannot share slice views with the fit-time design matrix.
  • ASMD input validation now rejects duplicate DataFrame column labels before
    computing statistics, making direct asmd(...) calls match the unique-column
    invariant enforced by SampleFrame construction.
  • find_items_index_in_list(...) now precomputes first-position lookups instead
    of rebuilding membership sets and rescanning the source list for every item.
  • Rake predict_weights() replay code is split into focused validation, transformation, NA-handling, cell-mapping, target-total, and index-restoration helpers while preserving existing replay and transfer behavior.
  • Rake, poststratify, and IPW now share a single NA-policy helper for fit-time na_action handling, keeping drop/add-indicator semantics consistent across weighting methods.
  • Rake now uses the shared weighting-method input validator already used by
    IPW and poststratify, so DataFrame/weight type, length, and index checks are
    reported consistently across all three methods.
  • Breaking: Rake model metadata no longer emits the IPW-style perf placeholder with a
    synthetic NaN deviance-explained value; consumers should use rake-specific
    metadata such as iterations and converged.
  • Transfer-scoring guards for rake and poststratify now reject functools.partial(...) wrappers around known data-dependent transformation helpers (quantize / fct_lump), closing a replay-safety gap where partial-wrapped helpers could bypass direct callable checks.
  • Rake now uses the shared adjustment warning helper when fit metadata is stored with transformations="default", keeping transfer-scoring guidance centralized with the corresponding replay-safety guard.

Bug Fixes

  • Model-matrix construction now stringifies pandas categorical levels before calling patsy, so interval-backed categoricals get stable dummy-column names and categorical covariates work in ASMD aggregation/regression coverage.
  • The CLI now rejects blank path/column values, malformed comma-separated column lists, unsupported adjustment methods (while allowing the core null adjustment), and invalid delimiter arguments during argument parsing instead of failing later in execution.

Tests

  • Add regression test for CBPS rank-deficient SVD handling when covariate
    columns are collinear (near-zero singular values filtered during SVD
    preprocessing).
  • Expanded poststratification adjustment coverage
    • Added Sample.adjust(method="poststratify") coverage for the normalized
      direct poststratification example to keep the high-level API aligned with
      the weighting method.
  • Add regression coverage that rake metadata without an IPW-style perf
    placeholder still works through high-level summary and diagnostics APIs.

Contributors

@neuralsorcerer, @talgalili

Full Changelog

0.21.0...0.22.0

Don't miss a new balance release

NewReleases is sending notifications on new releases.