Skip to content

Repository files navigation

treecf

Constrained, threshold-aware counterfactual explanations for tree ensembles.

treecf answers the question: "what is the minimal, feasible change to this instance such that the model's raw output lands in a target interval?" — for XGBoost, LightGBM, CatBoost and scikit-learn tree ensembles.

Status: v0.1.0 on PyPI. See the documentation for concepts and tutorials.

Why another counterfactual package?

  • Tree-native and fast. Models are parsed into a shared tree IR; the constrained genetic search runs on a bundled Rust core 44–58× faster than the equivalent numpy implementation (see the "Backends and proofs" docs page; the pure-Python engine remains available as backend="python"), and every result is float-verified against the IR before it is returned.
  • Decision thresholds are first-class. Targets are intervals on the raw model output — custom probability cutoffs, regression targets, and whole rating-grade ladders in one call.
  • Real-world constraints. Declarative layer for immutability, directionality, ranges, one-hot consistency, and arbitrary linear inter-feature constraints such as max_dpd_30d <= max_dpd_12m — compiled once, enforced by every backend.
  • Missing values are values. NaN can be a legitimate counterfactual state, with per-feature opt-in and explicit transition costs.
  • Constraint mining. Candidate invariants are mined from data and presented for human review — never auto-applied.

Installation

pip install treecf              # bundled Rust engine; numpy is the only Python dep
pip install "treecf[xgboost]"   # model parsers as extras; JSON dumps work without them
pip install "treecf[viz]"       # matplotlib plots

Quick look

from treecf import Explainer, Target, constraint, Freeze

exp = Explainer(
    model="model.json",                       # native object or dump file
    background=X_train_sample,
    constraints=[
        constraint("max_dpd_30d <= max_dpd_12m"),
        Freeze("age_of_bureau_file"),
    ],
)
res = exp.explain(x, target=Target.probability(range=(0.0, 0.04)), seed=0)

License

MIT

About

Constrained, threshold-aware counterfactual explanations for tree ensembles (XGBoost, LightGBM, CatBoost, sklearn) on a bundled Rust engine

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages