Skip to content

v0.8.1

This patch release fixes the group-IV basis on the by-group WOE plots of MonotoneWOEBinner, and fixes two compatibility problems in loading and parallel execution. Modeling, screening, and WOE transform results are bit-for-bit identical to 0.8.0: changes appear only in the IV numbers on by-group plots, in the attrs attached to get_final_bins() when SV governance is enabled, and in code paths that previously raised errors.

1. Group IV on By-Group WOE Plots Now Uses the Within-Group Basis

In 0.8.0 and earlier, the per-group IV in the three bar-plot modes of plot_woe_graph(..., group_name=...) (pooled / clustered / small_multiples) had two defects:

  • The denominator was the full sample: each group's per-bin bad/good was divided by the total bad/good of the whole _df_for_group. Let the group's share of total bad samples be s_B and of good samples be s_G; the number on the plot was about s × the within-group IV — k similarly sized groups each showed only about 1/k (4 homogeneous groups showed 0.17–0.19, while the within-group IV was 0.69–0.76); when bad rates differ between groups, the shrink factors differ and cannot be converted back.
  • Special-value / missing bins were left out: only ordinary bins were accumulated, while the overall plot's IV (vr["iv"]) includes special-value bins.

From 0.8.1, the group IV is on the same basis as the overall plot's IV, just with the sample replaced by that group:

  • Ordinary bins: the denominators are the bad/good of the group's rows that fall into ordinary bins;
  • Special-value bins: the denominators are the bad/good of all the group's rows, reusing the fit-time sv_policy_applied decision without re-judging the share within the group (keep takes the empirical value, and when fit had smoothing on, it is smoothed with the fit parameters; neutral counts as 0; merged_into_missing is merged into the group's [Missing], and [Missing] uses the post-merge counts, unsmoothed);
  • Bins with a single class within the group that were not laplace-smoothed are excluded (consistent with the iv_guard basis of the screening IV). Otherwise eps would inflate an empty-class bin into an overstated IV of about 0.6 — in monthly groups with a 3.6% bad rate and 5,000 rows per month, months with a zero-bad bin once showed 0.93–0.97 (the true value was about 0.35). Laplace-smoothed special-value bins have a finite WOE and are counted as usual;
  • For categorical features, values that did not appear at fit time are excluded from the ordinary-bin denominators; groups with fewer than 5 rows or a single class still show IV=0.000.

When all unsmoothed fit bins have both classes, treating the whole fit sample as one group makes the group IV equal to vr["iv"].

Unchanged: each group's WOE line is still based on the full-sample bad/good (for bins with both classes = within-group WOE + the constant ln(group's share of total bad / group's share of total good), which makes it easy to compare groups' bad-debt levels); the bars, N/TR labels, file names, image size, and dpi are all unchanged.

2. SV Governance Decisions Round-Trip with Format-A attrs

When SV governance is enabled (sv_small_policy != "keep" or sv_woe_smoothing != "none"), attrs["smf_woe_format_a"] of get_final_bins() gains:

  • sv_decisions: the row-by-row sv_policy_applied, plus the smoothing mode and α at fit time;
  • sv_decisions_digest: an independent validation digest bound to the existing metadata_digest.

load_woe_bins() restores the decisions only when the original metadata, the decision digest, and every value pass validation, so that the group IV drawn from loaded bins matches fit time (even if the loader uses the default SV parameters).

  • The fields computed into the original metadata_digest are unchanged: old loaders can still validate and restore exactly the boundaries, bin IDs, and category members;
  • For tables without SV governance, attrs are identical to 0.8.0;
  • CSV/Excel reloads (attrs lost) and Format B carry no decisions, and special-value bins are counted with the empirical value of keep;
  • An α that cannot round-trip reliably (NaN, huge integers) writes no decisions, so export does not fail.

3. Other Fixes to By-Group Plots

  • When fitted bin IDs are non-contiguous (such as [0, 2, 3]), each group's bars, lines, and data labels took bins by position, causing misalignment and leaving the last bin undrawn; they are now aligned by actual bin ID.
  • When two special values render to the same label (such as special_values=["-999", -999]), the special-value bar got an empty subset and showed 0; it is now consistent with the group IV, taking the first non-empty subset.

4. load_woe_bins Accepts dict-Wrapped Format A Tables

load_woe_bins({feat: {"bin_df": table}}) always raised "The truth value of a DataFrame is ambiguous", because payload.get("bin_df") or ... evaluates the truthiness of a DataFrame. Now both the bin_df and df keys are equivalent to passing the table directly; if the wrapped value is not a DataFrame, a ValueError with the type name is raised.

5. ParallelApplyEngine Compatible with joblib ≥ 1.6

joblib 1.6.0 (2026-08-31) removed joblib.externals.cloudpickle and now depends on the standalone cloudpickle package. Previously, the serializability check for backend="process" put that import inside a try that rewrote exceptions, so under joblib ≥ 1.6 every process-backend call falsely reported "func, func_args, and func_kwargs must be serializable". Now joblib's built-in copy is preferred and the cloudpickle package is used when it is absent; import problems surface directly as ImportError. No new dependency.

0.8.0 and earlier + joblib ≥ 1.6

If you cannot upgrade yet, pin joblib<1.6 before using ParallelApplyEngine(backend="process").

Backward Compatibility and Upgrade Advice

  • Fit results, apply_woe(), the values of get_final_bins(), iv_summary, the overall WOE plot, and each group's WOE line are all bit-for-bit identical to 0.8.0; screening and modeling do not read the IV on by-group plots.
  • By-group plots produced by 0.8.0 and earlier: the group IV is not on the within-group basis and should not be compared with the overall IV; regenerating the plots after upgrading is recommended (likewise for the FVP woe_plot_groups artifacts).
  • Regression: pytest suite of 1134 tests, main-repository 3×2 CI matrix, 0 failed / 0 skipped.