Skip to content

Releases: maschulz/pyinfluence

v0.5.0

Choose a tag to compare

@maschulz maschulz released this 29 Aug 19:15

This release corrects several bugs in the attribution estimators. Upgrading changes numerical results — refit-based loss magnitudes halve, and some negative-class and near-parity signs change. Re-run analyses that pinned scores from an earlier version.

Breaking

  • Requires Python 3.10 or newer (3.9 reached end of life in October 2025).

Fixed

  • Loss scores use half squared error throughout, so InfluenceFunctions and the refit-based attributors (LOOInfluence, BanzhafInfluence, BootstrapInfluence) share one scale. Refit-based loss magnitudes are now half their previous values; rankings are unchanged.
  • Prediction-mode influence for classifiers without predict_proba (e.g. RidgeClassifier) uses the margin toward the true class. Negative-class scores flip sign relative to earlier versions.
  • target="absolute" and worst_group_mean are attributed by exact perturbation evaluation, correcting scores that the previous linearization mispredicted near a zero crossing or a group tie.
  • The influence(method="auto") bootstrap fallback for unsupported models is seeded and uses 200 runs, so results are reproducible.
  • fit, explain, and functional_value raise on mismatched X/y (or X_ref/y_ref) row counts instead of silently broadcasting into a wrong result.
  • InfluenceFunctions rejects positive=True (NNLS) models; method="auto" falls back to a refit method that handles them.

Added

  • py.typed, so type checkers use the package's annotations.

Documentation

  • The AUROC attribution's agreement with exact refit (r > 0.99) is a property of the package benchmark, not a general guarantee; the perturbation approximation is dataset-dependent, so validate against RefitFunctionalInfluence on your data.
  • BootstrapInfluence documents its in-bag multiplicity bias (a point appears ~1.58 times on average when present, inflating magnitudes); the ranking is the reliable output.

v0.4.0

Choose a tag to compare

@maschulz maschulz released this 16 Jul 00:21

Changed (breaking)

  • functionals.auroc no longer accepts a tau parameter. The
    sigmoid-smoothed surrogate is removed; the closed form now attributes
    the exact Mann-Whitney AUROC via perturbation evaluation (below).

Added

  • Perturbation evaluation for non-differentiable functionals.
    Functional gained a differentiable flag (default True). Rank
    statistics and other piecewise-constant functionals are attributed by
    evaluating the exact functional on each removal's linearized value
    change, score[j] = F(v + dv_j) - F(v), computed in memory-bounded
    column blocks. This preserves the quantized structure of the estimand
    (removals that swap no pair score exactly zero) and agrees with exact
    leave-one-out refitting at r > 0.99 in the test suite. For smooth
    functionals the perturbation and chain-rule paths agree to first
    order; the estimator API is unchanged.
  • README code blocks are executed as part of the test suite.

v0.3.1

Choose a tag to compare

@maschulz maschulz released this 15 Jul 18:12

Added

  • Every fit warns when the model performs worse than a trivial
    baseline on the data it was given (negative log-likelihood against
    class frequencies for probabilistic classifiers, accuracy/R^2
    otherwise). This catches preprocessing mismatches such as passing raw
    features to the inner estimator of a Pipeline that was fit on
    transformed features.
  • influence(method='auto') warns when an unsupported model type falls
    back to a refit-based method, and notes that model-agnostic
    estimators can disagree substantially at the per-point level on
    non-linear models; compare estimators and run removal_curve before
    acting on individual rankings.
  • Functionals and fitted functional attributors are picklable.
  • Row-alignment validation on group functionals and auroc, with clear
    error messages for mismatched audit arrays.

Fixed

  • scikit-learn's "X does not have valid feature names" warning is
    suppressed for internal predictions on DataFrame-fitted models.
  • stability_replicates deduplicates repeated per-replicate warnings
    and documents its cost model.
  • viz.report raises a clear error for functional attributors;
    plot_top_influencers uses a neutral default title for 1-D scores.
  • influence_by_group rejects composite (tuple) keys with an
    actionable message.

Documentation

  • Every README code block runs as written, top to bottom.
  • New worked example: explaining a single prediction.
  • Documented pandas conventions (positional indices; the index is not
    used for alignment), the AUROC per-point fidelity considerations, the
    distinction between scores_std_ and stability_replicates, the
    leave-one-out regularization-scaling protocol, and a known issue with
    numpy 2.0.x on macOS (spurious matmul RuntimeWarnings from the
    Accelerate backend).

v0.3.0

Choose a tag to compare

@maschulz maschulz released this 15 Jul 18:12

Scalar-property attribution is now a first-class, domain-neutral
engine; the fairness module is a thin vocabulary layer over it. No
compatibility shims.

Added

  • Engine (top level): Functional (a scalar function of per-sample
    model scores or losses on a reference set, with optional analytic
    gradient), attributed by FunctionalInfluence (closed form),
    RefitFunctionalInfluence (exact leave-one-out), and
    SubsampledFunctionalInfluence (Monte-Carlo subsets); evaluated by
    functional_value(model, X, F, y). fit is functional-independent:
    one fitted attributor can explain any number of functionals via
    explain(..., functional=...).
  • pyinfluence.functionals: builders with analytic gradients —
    mean(of), group_gap(groups, keep=None, of), cohens_d(groups),
    worst_group_mean(groups, of), and auroc(pos_label). Each is
    validated against exact refitting in the test suite.

Changed (breaking)

  • pyinfluence.fairness now provides vocabulary and workflow only:
    disparity(metric, sensitive, *, target_of=... | pos_label=...) maps
    'dp'/'eopp'/'fpr'/'worst_group_loss' onto the builders;
    disparity_value(_hard), group_removal_effect, and
    disparity_removal_curve keep their signatures (metric accepts a
    name or any Functional).
  • Removed FairnessInfluenceFunctions, RefitFairnessInfluence, and
    SubsampledFairnessInfluence (replaced by the engine classes plus
    disparity), the raw-callable metric form, and the top-level
    re-exports of fairness utilities.
  • cohens_d moved to pyinfluence.functionals as a builder returning
    a Functional with an analytic gradient.

v0.2.0

Choose a tag to compare

@maschulz maschulz released this 15 Jul 18:12

Correctness release; the numerical claims below are enforced by tests
against exact refitting or brute-force enumeration.

Breaking changes

  • Fairness explain audit arguments are keyword-only.
  • viz.plot_heatmap no longer accepts cluster=.
  • BanzhafInfluence returns NaN (with a warning) instead of 0.0 for
    training points whose subset refits all fail.
  • InfluenceFunctions rejects configurations it cannot represent
    (class_weight, l1/elasticnet penalties) instead of returning
    degraded scores; influence(method='auto') falls back with a
    warning.
  • removal_curve requires mode='loss'.
  • Labels outside model.classes_ raise instead of being mapped to the
    negative class.
  • viz requires matplotlib >= 3.9.

Fixed

  • Binary label encodings other than {0,1} produced incorrect scores for
    LogisticRegression (train- and test-side NLL gradients used raw
    label values). Scores are now invariant across {0,1}, {1,2}, {-1,+1},
    and string encodings; the same fix applies to the fairness closed
    form.
  • Fairness eopp and fpr were swapped for non-{0,1} encodings
    (conditioning on the literal value 1 instead of the model's positive
    class); disparity_value_hard's worst-group error compared decisions
    against raw labels.
  • NaN scores corrupted the analysis utilities (top_influential ranked
    NaN as most helpful; a single NaN emptied find_mislabeled and
    poisoned influence_summary/compare_attributors). All utilities
    and plots exclude NaN from rankings and statistics, with a warning.
  • Small-subset sampling bias in BanzhafInfluence (subsets of size one
    were excluded from Monte-Carlo sampling).
  • disparity_removal_curve reported the wrong base_disparity when
    fractions did not start at 0.
  • Clear early errors replace cryptic failures for sparse inputs,
    multi-output targets, unfitted models passed to refit-based
    attributors, multiclass classifiers without predict_proba, and
    wrapped estimators under method='auto'.
  • KernelRidge with a callable kernel failed, and kernel_params was
    ignored; the kernel reconstruction now mirrors scikit-learn's.
  • liblinear-solver logistic models trigger a warning (the regularized
    intercept violates the Hessian assumption).

Added

  • Custom fairness metrics via callables, with analytic or
    finite-difference gradients in the closed form; bundled cohens_d.
  • Monte-Carlo standard errors: BanzhafInfluence and
    BootstrapInfluence expose scores_std_;
    viz.plot_top_influencers(..., xerr=...) draws error bars.
  • New plots: plot_disparity_curve, plot_detection_curve,
    plot_influence_concentration.
  • stability_replicates utility feeding plot_top_k_stability.
  • supports(model): capability check for InfluenceFunctions that
    never raises or warns.
  • self_influence computes the diagonal directly for
    InfluenceFunctions, LOOInfluence, and BootstrapInfluence (O(n) memory
    instead of the full matrix).
  • README figures and an explicit limitations section.