New Features
BalanceDFOutcomes.relative_response_rates()now accepts an explicitrelative_to={"self", "target"}denominator selector while preserving the existingtarget=API.- The CLI now exposes IPW
penalty_factorthrough--penalty_factor, accepting either comma-separated numbers or a JSON list and forwarding the parsed list intoSample.adjust(). - The CLI now validates
--transformationsat parse time, accepting only the supporteddefaultandNonecommand-line modes. rake()now accepts keyword-onlytarget_marginsdictionaries 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
canonicaltraining_sample_weights/training_target_weightskeys used by
predict_weights(). The oldfit_sample_weights/fit_target_weights
model-dict keys are no longer emitted; downstream code that reads
ipw(...)["model"]directly should switch to thetraining_*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 directasmd(...)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_actionhandling, 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
perfplaceholder with a
synthetic NaN deviance-explained value; consumers should use rake-specific
metadata such asiterationsandconverged. - 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
nulladjustment), 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.
- Added
- Add regression coverage that rake metadata without an IPW-style
perf
placeholder still works through high-level summary and diagnostics APIs.