Metadata-Version: 2.4
Name: ybgix
Version: 0.1.0
Summary: A local group-interaction explanation method for nonlinear correlated tabular data.
Author: Ilhan Uysal
License-Expression: MIT
Project-URL: Source, https://github.com/iuysal1905/yb-groupinteract-xai
Project-URL: Issues, https://github.com/iuysal1905/yb-groupinteract-xai/issues
Keywords: explainable artificial intelligence,XAI,feature interaction,tabular data,local explanation
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.23
Requires-Dist: pandas>=1.5
Requires-Dist: scipy>=1.9
Requires-Dist: scikit-learn>=1.2
Requires-Dist: matplotlib>=3.6
Requires-Dist: networkx>=3.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"
Dynamic: license-file

# YBGIX

**YBGIX** is a Python research package for explaining interactions between groups of correlated features in tabular classification models. It produces model-aware group-pair scores, a regularized local surrogate containing group interaction terms, and visualizations of the explanation.

The method is intended as an exploratory **local interaction explainer**, not a causal inference tool or a replacement for feature-level explanation methods.

## Installation

YBGIX requires Python 3.9 or later and a fitted classification model with a `predict_proba(X)` method.

After the package is published on PyPI:

```bash
pip install ybgix
```

Until publication, install from a checkout of the repository:

```bash
python -m pip install .
```

## Quick start

The example creates three distinct groups of correlated features. The target depends on a nonlinear interaction between the first two latent variables.

```python
import matplotlib.pyplot as plt
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from ybgix import YBGroupInteractExplainer

rng = np.random.default_rng(42)
n = 600
z = rng.normal(size=(n, 3))

X = np.column_stack([
    z[:, group_id] + 0.03 * rng.normal(size=n)
    for group_id in range(3)
    for _ in range(2)
])
y = np.logical_xor(z[:, 0] > 0, z[:, 1] > 0).astype(int)

model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X, y)

explainer = YBGroupInteractExplainer(
    model=model,
    X_train=X,
    feature_names=["A1", "A2", "B1", "B2", "C1", "C2"],
    random_state=42,
)

explanation = explainer.explain(X[10], num_samples=500, class_index=1)

print("Learned herds:", explanation.groups)
print("Top interaction pair:", explanation.top_pair)
print(explanation.top_pairs(3)[["pair", "synergy", "joint_effect", "score"]])
print("Local surrogate fidelity (in-mask R²):", explanation.local_fidelity)

explanation.plot_pair_importance(top_n=3)
explanation.plot_network(top_n=3)
explanation.plot_mask_response()
explanation.plot_group_heatmap()
plt.show()
```

The IDs in a pair refer to **learned herds** in `explanation.groups`, not to individual columns.

## How YBGIX works

1. **Global herd discovery:** The training data are standardized, and a graph connects features when their absolute Pearson correlation is at least `corr_threshold=0.45`. Connected components form herds. This grouping is learned once from `X_train`.
2. **Global reference:** Masked features are replaced with their corresponding training-set means. This is the reference used for pair ranking and local surrogate perturbations.
3. **Model-aware pair ranking:** For two herds, let `f(x)` be the predicted probability of the explained class and let `x\r`, `x\s`, and `x\{r,s}` denote masking those herds. YBGIX computes:

   ```text
   synergy(r,s) = |f(x) - f(x\r) - f(x\s) + f(x\{r,s})|
   joint(r,s)   = |f(x) - f(x\{r,s})|
   score(r,s)   = 0.70 * synergy(r,s) + 0.30 * joint(r,s)
   ```

4. **Interaction surrogate:** A weighted, regularized regression approximates the model response to group masks, using both group main effects and selected products of group masks.
5. **Outputs:** Ranked herd pairs, group-level scores, coefficients, masking responses, a weighted surrogate R², and four plots.

The default candidate selection considers herds with at least two features, capped at eight candidate herds and ten selected interaction pairs. When fewer than two herds satisfy the minimum-size rule, the implementation falls back to all herds. These heuristics are part of the current research configuration.

## Main API

```python
YBGroupInteractExplainer(
    model,
    X_train,
    feature_names=None,
    corr_threshold=0.45,
    lambda_main=1.0,
    lambda_interaction=0.1,
    p_keep_group=0.5,
    fixed_groups=None,
    balanced_masks=True,
    max_candidate_groups=8,
    max_pairs=10,
    min_group_size=2,
    alpha_synergy=0.70,
    random_state=42,
)
```

`local_k` is still accepted for backward compatibility but does not affect the current global-reference explanations. The library currently supports **classification models exposing `predict_proba`**.

The returned `YBExplanation` object includes `groups`, `selected_pairs`, `pair_scores`, `main_coef`, `interaction_coef`, `group_scores`, `feature_scores`, `local_fidelity`, `masks`, and model/surrogate responses.

## Interpreting results and limitations

- **Correlation is not causation.** A herd is a feature cluster, not a verified causal mechanism. Pair scores depend on the masking reference and the trained model.
- **Over-grouping can occur.** In highly interconnected real datasets, a fixed correlation threshold may merge many features into one large herd, leaving few meaningful pair candidates. Inspect `explanation.groups` before interpreting pair rankings.
- **Singleton screening matters.** The default `min_group_size=2` preferentially excludes singleton herds from pair selection; results can be sensitive to the eligible search space.
- **Score components trade off.** The frozen score combines synergy and joint masking effect; on synthetic validation data, pure synergy sometimes recovered the known interaction more often. The released default is retained for reproducibility, not claimed to be universally optimal.
- **Masking changes the input distribution.** Replacing correlated features with marginal means can create unrealistic combinations, so perturbation effects should not be interpreted as interventions.
- **Local fidelity is not held-out accuracy.** `local_fidelity` is a weighted R² measured on the sampled masks used to fit that particular surrogate. Independent-mask validation is a separate evaluation.
- **No universal superiority claim.** Performance varies with the model, dependence structure, noise, and task. Comparisons with feature-attribution methods answer different questions.

## Development

In a source checkout:

```bash
python -m pip install -e ".[dev]"
python -m pytest -q
python -m build
python -m twine check dist/*
```

The regression tests include a frozen numerical reference for the research configuration and compatibility checks for the visualizations.

## Status

This is research software. The current package version is a prerelease (`0.1.0.dev0`) until an initial public version is explicitly published. A paper citation and persistent identifier will be added when available; no published DOI is claimed here.
