Metadata-Version: 2.4
Name: evo-imp
Version: 0.1.0
Summary: Evolutionary Symbolic Imputer — a scikit-learn-compatible missing-value imputer that evolves interpretable, non-linear symbolic expressions per feature with Genetic Programming (evo-suite)
Author: Axel Skrauba
License: MIT
Project-URL: Homepage, https://github.com/AxelSkrauba/evo-suite
Project-URL: Documentation, https://evo-suite.readthedocs.io/
Project-URL: Repository, https://github.com/AxelSkrauba/evo-suite
Project-URL: Changelog, https://github.com/AxelSkrauba/evo-suite/blob/main/packages/evo-imp/CHANGELOG.md
Project-URL: Bug Tracker, https://github.com/AxelSkrauba/evo-suite/issues
Keywords: missing data,imputation,genetic programming,symbolic regression,DEAP,machine learning,scikit-learn,evolutionary computation
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: numpy>=1.24
Requires-Dist: pandas>=1.5
Requires-Dist: scikit-learn>=1.6
Requires-Dist: deap>=1.4
Requires-Dist: scipy>=1.9
Provides-Extra: viz
Requires-Dist: matplotlib>=3.6; extra == "viz"
Provides-Extra: simplify
Requires-Dist: sympy>=1.12; extra == "simplify"
Provides-Extra: dev
Requires-Dist: pytest>=7.4; extra == "dev"
Requires-Dist: pytest-cov>=4.1; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"
Requires-Dist: mypy>=1.8; extra == "dev"
Requires-Dist: matplotlib>=3.6; extra == "dev"
Requires-Dist: sympy>=1.12; extra == "dev"

# evo-imp - Evolutionary Symbolic Imputer

[![PyPI](https://img.shields.io/pypi/v/evo-imp.svg)](https://pypi.org/project/evo-imp/)
[![Python versions](https://img.shields.io/pypi/pyversions/evo-imp.svg)](https://pypi.org/project/evo-imp/)
[![Docs](https://readthedocs.org/projects/evo-suite/badge/?version=latest)](https://evo-suite.readthedocs.io/en/latest/)
[![CI](https://github.com/AxelSkrauba/evo-suite/actions/workflows/ci.yml/badge.svg)](https://github.com/AxelSkrauba/evo-suite/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](../../LICENSE)

A **scikit-learn-compatible** missing-value imputer for tabular data, powered
by [DEAP](https://github.com/DEAP/deap). `evo-imp` evolves an interpretable
symbolic expression per feature with Genetic Programming, capturing
non-linear relationships that `SimpleImputer`/`KNNImputer`/`IterativeImputer`
cannot represent. It is a natural first step in the pipeline, upstream of
[`evo-gpfe`](../evo-gpfe) (feature engineering) and [`evo-gafs`](../evo-gafs)
(feature selection).

Part of the [`evo-suite`](../../README.md) family (import name: `evo_imp`).
Documentation: <https://evo-suite.readthedocs.io/>

## Why evo-imp?

| Capability | evo-imp |
|------------|---------|
| **Interpretable, non-linear imputation**: a symbolic expression per feature | Yes |
| **Holdout-validated fitness**: reported RMSE/fallback decision use a held-out split, not in-sample | Yes |
| **Never worse than the mean**: automatic fallback when GP does not improve over `SimpleImputer(mean)` | Yes |
| Native scikit-learn transformer `EvoImputer`, usable in a `Pipeline` | Yes |
| Optional `sympy`-based expression simplification for readability | Yes |
| Built-in multi-dataset `EvoImpBenchmarkRunner` and MCAR evaluation helpers | Yes |

## Installation

```bash
pip install evo-imp            # core
pip install "evo-imp[viz]"     # + matplotlib for the plotting helpers
pip install "evo-imp[simplify]"  # + sympy for simplify_expressions=True
```

## Quickstart

```python
from sklearn.datasets import load_diabetes
from evo_imp import EvoImpConfig, EvoImputer, introduce_mcar

X = load_diabetes(as_frame=True).data
X_missing, _ = introduce_mcar(X.values, missing_rate=0.20, random_seed=42)

imputer = EvoImputer(
    config=EvoImpConfig(population_size=150, n_generations=30, verbose=False)
)
X_imputed = imputer.fit_transform(X_missing)

print(imputer.summary())
print(imputer.get_expressions())
```

Unlike the rest of `evo-suite`, `EvoImputer` is unsupervised (`fit(X,
y=None)`) and its whole purpose is to accept `NaN` input — see the
[Concepts guide](https://evo-suite.readthedocs.io/en/latest/evo-imp/guide/concepts.html)
for why this is a deliberate exception to the family's usual scikit-learn
conventions.

## Documentation & examples

- **Full documentation** (user guide + API reference): <https://evo-suite.readthedocs.io/>
- **Runnable examples**: the repository's [`examples/evo-imp/`](../../examples/evo-imp) directory.

## Citation

```bibtex
@software{evo_imp,
  author    = {Skrauba, Axel},
  title     = {evo-imp: Evolutionary Symbolic Imputer for tabular data},
  year      = {2026},
  version   = {0.1.0},
  url       = {https://github.com/AxelSkrauba/evo-suite}
}
```

## License

[MIT](../../LICENSE)
