Skip to content

v0.8.2

This release is a focused round of defect governance: seven batches of fixes covering special-value declarations, warning visibility, bool features, evaluation of single-class datasets, and SMF's side effects on the caller's DataFrame.

Unlike earlier patches, this release changes results on some paths

Patch releases up to 0.8.1 promised "zero numerical difference on healthy inputs". 0.8.2 does not meet that promise — several of the defects it fixes were themselves producing wrong numbers, so the numbers change once they are fixed. The following three kinds of runs are affected; please check them before upgrading:

Case Impact
A non-integer special value is declared (such as 0.5) Scoring on the default path changes (ordinary samples with the value 0 used to wrongly receive the WOE of [sv=0.5])
FeatureValidationPipeline without OOT Integer features are no longer degraded to object by an empty placeholder table; the correlation matrix, correlation filtering, and target-free PSI work again, so the selected variables may change
Reading your own table after calling plot_woe / plot_woe_group Your column names are no longer lowercased (see Section 7)

The remaining fixes target paths that previously raised exceptions outright, so there is no question of "results changing".

1. Declared Special Values That Never Appear in the Fit Sample

A new unseen_special_policy parameter (MonotoneWOEBinner / monotone_woe_params of the one-click pipelines):

  • normal_bin (default, same as the old behavior): these values fall into ordinary bins;
  • neutral: create a placeholder bin with WOE=0 and sv_policy_applied="unseen_at_fit".

0.9.0 plans to flip the default to neutral. Fixes in the same batch:

  • Integer truncation of non-integer special-value labels: special-value bin labels were truncated to an integer key, so ordinary samples with the value 0 received the WOE of [sv=0.5]. This changes scoring on the default path.
  • CreditModelPipeline now declares -999999 by default only when it actually appears in the WOE fit sample (binning and scoring are unchanged).
  • FVP freezes unseen_special_stats per split (unseen_special_stats_by_split / woe_artifacts["unseen_special_stats_by_target"]).

Known limitations

The sv_decisions of a neutral table contains unseen_at_fit, which the 0.8.1 loader rejects wholesale (scoring is unaffected). unseen_category_policy="raise" only warns, and does not raise, for unseen special values.

2. Importing SMF No Longer Suppresses All Warnings

Modeling_Tool.WOE.WOE_Monotone_Binner (loaded as soon as you import Modeling_Tool) and Modeling_Tool.Model.Backward_Tool executed warnings.filterwarnings("ignore") at import time. That was process-level: once SMF was imported, SMF's own guard warnings, your own code's warnings, and third-party deprecation notices all disappeared. Both occurrences have been removed; computed results are identical, and these messages are simply visible again.

3. Cleaning Up the Warning Noise from SMF's Own Calls, and the Defects It Was Hiding

SMF's own deprecation and numerical warnings were fixed one by one (seaborn distplot/bw, log(0) in WOE/IV, round/pd.cut overflow, VIF, 0/0 in lift, FutureWarnings of pandas concat/groupby/agg, sklearn feature names, pyodps Schema, shap global random state). The seaborn migration reproduces distplot's (mean, 0) anchor and draws onto the axes passed in; 12 plots including edge cases are pixel-for-pixel identical.

Defects exposed and fixed along the way:

  • When FVP ran without OOT, integer features and the target column were degraded to object by an empty placeholder table: integer features were treated as categorical, lost the min/mean/max of IV/KS, and were excluded from the raw-value correlation matrix; once the target column became object, correlation filtering failed for every feature (correlated_detail was always empty), and target-free PSI logged a TypeError for every feature. The new concat_non_empty excludes empty frames from row concatenation. Variable selection in runs without OOT may change as a result; correlation screening run on 0.8.1 or earlier should be redone.
  • bool features were lost on both paths of the FVP distribution summary (describe() drops bool columns mixed with numeric ones); they are now reported as categorical features.
  • The Excel title of a single-column table was lost (merge_range rejects a 1×1 region and silently writes nothing); it now writes the cell directly.
  • N_BUMP / N_BINS in the gains summary no longer degrade to object when a split is missing.
  • The scatter jitter of ModelExplainer.summary_plot now has a fixed random seed.

4. Single-Class Datasets No Longer Crash Performance Evaluation

With only good samples (for example an OOT window with no bad samples) or only bad samples, TPR/FPR are all NaN, and summarize_roc takes np.argmax of all-NaN, gets -1, and looks it up by label, raising KeyError(-1) — PerformanceEvaluator.evaluate (plain/weighted/baseline/grouped/multi-target), evaluate_performance, get_perf_summary, comparison_performance, plot_roc_curve, and plot_ks_curve were all hit, and the reject-inference pipeline would also discard each method's evaluator output because of it.

Now KS / AUC are recorded as NaN, while N, bad rate, mean score, quantile target rates, and charts are produced as usual.

5. bool Features No Longer Crash Binning, WOE, and Pipelines

numpy does not accept quantiles on bool arrays (TypeError: numpy boolean subtract), so quick_binning, super_binning, the gains table, WOE_Master, MonotoneWOEBinner.fit, feature_screen, and weighted_feature_screen all raised errors on a bool column — while the same column after astype("int8") worked fine. In an FVP with WOE enabled, it showed up as a swallowed "feature insights computation failed" warning plus KeyError: WOE column 'x_woe' was not produced, aborting the whole flow.

Now bool is mapped to 0/1 at the point where quantiles are taken (pandas nullable boolean is converted to Int8, with missing values staying missing). The binning, WOE table, IV, and scoring results are bit-for-bit identical to the int8 copy of the same column; only the MIN / MAX of the WOE table are still reported as False / True for the feature itself.

6. Importing SMF No Longer Turns On pandas' future.no_silent_downcasting

Core/Binning_Tool.py, Core/kDataFrame.py, Core/Slope_Tool.py, and Core/ODPS_Tool.py each turned on this global switch at import time, so after importing SMF, unrelated replace() / fillna() calls in your own code also changed their downcasting behavior and began emitting downcasting warnings. All four occurrences were removed; SMF itself does not depend on it (the full regression shows no downcasting warnings without it). If you need it, set it explicitly in your own script.

7. Restoring pandas' SettingWithCopyWarning, and Fixing Nine Side Effects That Wrote Back into the Caller's Frame

All six occurrences of pd.options.mode.chained_assignment = None (Core/kDataFrame.py, Core/Binning_Tool.py, Core/ODPS_Tool.py, Core/Slope_Tool.py, and ExcelMaster/Template.py at import time, and Report/Report_Tool.plot_woe at call time) were removed. What it turned off is the warning pandas uses to flag real defects of the "I modified a slice and the change didn't take effect" kind, and because it was process-level, your own code lost it as well.

It had been turned off because SMF itself triggered the warning in 9 places across 6 modules. All 9 now operate on SMF's own frames, so the warning can stay on without SMF ever tripping it. Resulting behavior changes:

Location 0.8.1 and earlier 0.8.2
run_binning / super_binning Could write the bin_num / bin_range columns back into the DataFrame you passed in Only in the return value; your table is untouched
get_gains_table (when model is passed) Left a temporary _mdl_scr column on your table No longer leaves it
plot_woe / plot_woe_group (public API) Lowercased your column names and replaced inf in woe / iv in place Your table is left as-is; the plots are unchanged
scoring / select_sample_seed Only triggered the warning; the writes already landed on a copy No change

If your code depends on the old side effects in the first three rows (for example, looking up columns by lowercase name after calling plot_woe), do it explicitly yourself: df.columns = [c.lower() for c in df.columns].

Backward Compatibility and Upgrade Advice

  • No API removals; the only addition is the single unseen_special_policy parameter, whose default equals the old behavior.
  • The three kinds of runs whose results may change are listed in the warning table at the top of the page; the remaining fixes all target paths that previously raised exceptions.
  • field_meta.py does not yet include sv_* and unseen_special_policy; ModelExplainer.dependence_plot still uses global random numbers.
  • Regression: pytest suite of 1233 tests, main-repository 3×2 CI matrix, 0 failed / 0 skipped.