Using estimand aggregators

The nlp_shap.estimation.estimands package provides estimand aggregators that turn coalition masks and payoffs \(v(S)\) into per-player attributions. Each aggregator reports which estimand it implements.

Quick start

from itertools import product

from nlp_shap import BanzhafAggregator, Estimand, ShapleyAggregator

num_players = 3
masks = [tuple(bits) for bits in product([False, True], repeat=num_players)]

def majority_payoff(mask: tuple[bool, ...]) -> float:
    return 1.0 if sum(mask) >= 2 else 0.0

payoffs = [majority_payoff(mask) for mask in masks]

shapley = ShapleyAggregator().aggregate(masks, payoffs)
banzhaf = BanzhafAggregator().aggregate(masks, payoffs)

print("Shapley:", shapley)   # ~[0.333, 0.333, 0.333]
print("Banzhaf:", banzhaf)   # [0.5, 0.5, 0.5]

Coalition weights

Inspect weights without full aggregation:

from nlp_shap import ShapleyAggregator, BanzhafAggregator

shapley = ShapleyAggregator()
banzhaf = BanzhafAggregator()

n = 4
for k in range(n):
    print(f"k={k}", shapley.coalition_weight(k, n), banzhaf.coalition_weight(k, n))

Explain results and manifests

Label outputs explicitly for archives and papers:

from nlp_shap import Estimand, ExplainResult, RunManifest, parse_manifest

result = ExplainResult(
    estimand=Estimand.SHAPLEY,
    values=(0.333, 0.333, 0.333),
)

manifest = RunManifest(estimand=result.estimand, run_id="run-42")
payload = manifest.to_dict()
restored = parse_manifest(payload)

assert restored.estimand is Estimand.SHAPLEY

Wire values for JSON manifests use EstimandWire ("shapley" | "banzhaf").

Notebook

See the runnable walkthrough in Examplesexamples/estimands_toy_game.ipynb.

Further reading