Skip to content

calm-additive

CALM: interpretable by design. Accurate locally additive models for tabular data.


calm-additive fits CALMs (Conditionally Additive Local Models). It:

  • gives every feature a plain 1D curve, like a GAM, so the model can be read plot by plot
  • lets a feature have several curves, each valid in a region of the other features, which is how it captures interactions a GAM misses
  • finds those regions itself, from a black-box teacher, and keeps only the ones that earn their complexity
  • explains itself: a model card, the curves, and every prediction as a sum you can read line by line
  • shows its reasoning: a ledger of every split it kept and every split it rejected
  • has a scikit-learn API: fit, predict, and keyword arguments for the knobs

πŸ“– Guides | πŸš€ Quickstart | πŸ”§ API | πŸ— Examples


Installation

calm-additive requires Python 3.10+.

pip install calm-additive

Quickstart

A synthetic problem with one interaction: the effect of x3 is a sine when x2 >= 0 and a cosine when x2 < 0.

import numpy as np
import pandas as pd
from calm_additive import CALMRegressor

rng = np.random.default_rng(0)
X = pd.DataFrame(rng.uniform(-1, 1, (3000, 3)), columns=["x1", "x2", "x3"])
y = (
    X["x1"] ** 2
    + np.log(np.abs(X["x2"]))
    + 2 * np.where(X["x2"] >= 0, np.sin(np.pi / 2 * X["x3"]), np.cos(np.pi / 2 * X["x3"]))
    + rng.normal(0, 0.3, len(X))
)

calm = CALMRegressor(max_partition_depth=1).fit(X, y)
calm.print_summary()                # the model on one screen
calm.plot_curves()                  # one panel per feature, one curve per region
calm.print_prediction(X.iloc[0])    # why this prediction
calm.chain_.show()                  # why each split was kept or rejected

CALM finds the split and fits one curve per side:

The fitted CALM: x3 has two curves, a cosine when x2 < 0 and a sine when x2 >= 0

On a held-out fifth of the data (calm.print_summary(X_test, y_test) prints this comparison):

model test RΒ²
GAM (EBM, no interactions) 0.717
CALM 0.950
black box (XGBoost, the teacher) 0.939

πŸ“„ In depth: the quickstart guide walks through every line and its output.


The knobs

knob what it decides
max_conditional_interactions the most conditional interactions the model may have
max_partition_depth how many curves a feature may have: at most 2**max_partition_depth
min_heterogeneity_drop how much a split must reduce a feature's heterogeneity to be made
min_r2_gain how much a feature's partition must explain to be kept
teacher the black box the regions are learned from
effect how the teacher is read: PDP, ALE, SHAP-DP or RHALE
partition_features which features may get a partition at all
curve_fitter what is fitted inside the regions

πŸ“„ In depth: choosing the knobs.


Documentation map


Citation

@inproceedings{gkolemis2026calm,
  title     = {Interpretability-by-Design with Accurate Locally Additive Models
               and Conditional Feature Effects},
  author    = {Gkolemis, Vasilis and Kavouras, Loukas and Kyriakopoulos, Dimitrios
               and Tsopelas, Konstantinos and Rontogiannis, Dimitrios
               and Casalicchio, Giuseppe and Dalamagas, Theodore and Diou, Christos},
  booktitle = {Advances in Neural Information Processing Systems (NeurIPS)},
  year      = {2026}
}

Built on

effector, for reading the black box; InterpretML, for the EBM fitted inside the regions; XGBoost, for the default teacher.

Acknowledgments

The work leading to these results has been funded by the European Union under Grant Agreement No. 101289094 (project AIRIS). Views and opinions expressed are however those of the authors and do not necessarily reflect those of the European Union or the granting authority (HaDEA). Neither the European Union nor the granting authority can be held responsible for them.

The research leading to this work has received funding from the European Union’s Horizon Europe research and innovation program under Grant Agreement No: 101135826 (aidapt.eu).