Skip to content

The interactive API

Description

The in-depth guide to part (c) of effector's API: construct an engine once, then query it as you go. A map of the verbs; each verb has its own page.

Reading time

Approx. 5' to read; each verb page is another 4' to 7'.

The lifecycle

flowchart LR
    C["<b>construct</b><br/>PDP(X, model)"] --> F["<b>fit</b><br/><i>the only model touch</i>"]
    F --> Q["<b>query, free</b><br/>plot · eval · importance<br/>heter_score · find_regions"]
    Q -. "zero model calls" .-> F

Construct the engine once; it holds what is expensive. Every question you ask afterwards is answered from cached local effects, without touching the model again.

pdp = effector.PDP(X_test, predict)   # construct
pdp.fit(features="all")               # the only model touch (optional; queries do it lazily)
pdp.plot(0)                           # free
pdp.importance(0)                     # free
pdp.find_regions(0)                   # free

The five engines

They differ in what they compute; they do not differ in how you call them.

pdp    = effector.PDP(X_test, predict)
ale    = effector.ALE(X_test, predict)
rhale  = effector.RHALE(X_test, predict, jacobian)
shapdp = effector.ShapDP(X_test, predict)
derpdp = effector.DerPDP(X_test, predict, jacobian)

The verbs

Every verb has its own in-depth page, on a shared real example (bike sharing, the same run as the report guide) plus a synthetic model where it sharpens the point.

verb the question it answers
PDP(X, model) and .fit() which engine, on what data, configured how?
.plot(f) what does feature f do?
.eval(f, xs) …as numbers, on my grid?
.importance(f) how much does f move the output?
.heter_score(f) is the average hiding something?
.find_regions(f) where is it hiding it?
.select_regions() which splits actually earn their keep?
compare / plot_triage do the methods agree, and where to look first?

The one picture to remember

The running synthetic example is a model with a conditional interaction: the slope of x_0 flips with the sign of x_1.

pdp = effector.PDP(X_test, predict)
pdp.plot(feature=0)

Global PDP

⚠️ The mean curve is flat, and the model is anything but. That flat line is the average of a +10 slope and a -10 slope cancelling out. The band around it is screaming; the line is not. That is what heterogeneity is for, and the whole regional pipeline (scoresfind_regionsselect_regions) exists to chase it.

It ends where the report begins

parts = pdp.find_regions(features="heterogeneous")
chain = pdp.select_regions(partitions=parts)

This is exactly what the one-liner runs for you; drive it by hand when you want to hold the values (Partition, CalmSequence) instead of the frozen Report. The bridge back: pdp.explain() produces the same Report from your already fitted engine.


Where to next