Metadata-Version: 2.4
Name: pycol-optimized
Version: 0.2.0
Summary: Float32 PyTorch acceleration for selected PyCOL data-complexity metrics
Author: Muhammad Syafiq Mohd Pozi
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/spozi/pycol-optimized
Project-URL: Repository, https://github.com/spozi/pycol-optimized
Project-URL: Issues, https://github.com/spozi/pycol-optimized/issues
Project-URL: Changelog, https://github.com/spozi/pycol-optimized/blob/main/CHANGELOG.md
Keywords: data-complexity,class-overlap,imbalanced-learning,pytorch,mps,cuda
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Typing :: Typed
Requires-Python: <3.15,>=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: numpy<3,>=2.2
Requires-Dist: torch<3,>=2.13
Provides-Extra: reference
Requires-Dist: scipy<2,>=1.15; extra == "reference"
Requires-Dist: pycol-complexity==1.0.4; extra == "reference"
Provides-Extra: test
Requires-Dist: pytest<10,>=8.3; extra == "test"
Provides-Extra: dev
Requires-Dist: scipy<2,>=1.15; extra == "dev"
Requires-Dist: pycol-complexity==1.0.4; extra == "dev"
Requires-Dist: pytest<10,>=8.3; extra == "dev"
Requires-Dist: ruff<1,>=0.11; extra == "dev"
Requires-Dist: build<2,>=1.2; extra == "dev"
Requires-Dist: twine<7,>=5; extra == "dev"
Requires-Dist: check-wheel-contents<1,>=0.6; extra == "dev"
Dynamic: license-file

# PyCOL Optimized

`pycol-optimized` is a standalone float32 PyTorch implementation of the six
PyCOL data-complexity metrics used by its originating research project:

- F1;
- N1;
- class-balanced N3;
- kDN;
- CM;
- C1.

The distribution name is `pycol-optimized`; the Python import is
`pycol_optimized`.

> This is an independent compatibility implementation. It is not affiliated
> with or endorsed by the maintainers of
> [PyCOL](https://github.com/DiogoApostolo/pycol).

## Installation

Install the optimized implementation:

```bash
python -m pip install pycol-optimized
```

Install the optional pinned scientific-reference adapter:

```bash
python -m pip install "pycol-optimized[reference]"
```

For local development:

```bash
python -m pip install -e ".[dev]"
```

## Quick start

```python
import numpy as np

from pycol_optimized import compute_metrics

vectors = np.asarray(
    [
        [0.0, 0.0],
        [0.1, 0.2],
        [0.8, 0.7],
        [1.0, 1.0],
    ],
    dtype=np.float32,
)
labels = np.asarray([0, 0, 1, 1])

result = compute_metrics(
    vectors,
    labels,
    metrics=("F1", "N1", "N3", "kDN", "CM", "C1"),
    neighbors=2,
    device="auto",
)

print(result.metrics)
print(result.project_composite)
print(result.diagnostics["device"])
```

`device="auto"` selects CUDA, then Apple MPS, then CPU. Explicit values are
`"cpu"`, `"mps"`, and `"cuda"`.

For a before/after study, freeze the scaling range to the original cohort:

```python
reference_min = original_vectors.min(axis=0)
reference_max = original_vectors.max(axis=0)

before = compute_metrics(
    original_vectors,
    original_labels,
    device="cpu",
    reference_min=reference_min,
    reference_max=reference_max,
)
after = compute_metrics(
    augmented_vectors,
    augmented_labels,
    device="cpu",
    reference_min=reference_min,
    reference_max=reference_max,
)
```

## Multilabel targets

Pass a binary `[samples, labels]` indicator matrix:

```python
result = compute_metrics(
    vectors,
    multihot_labels,
    multilabel=True,
    label_names=["payment", "termination", "liability"],
    neighbors=5,
    device="mps",
)
```

Constant label columns are skipped. `result.metrics` contains the unweighted
macro average across valid one-vs-rest problems. Per-label values and
positive-prevalence-weighted values are available through `result.per_label`
and `result.label_weighted_metrics`.

## Scientific compatibility

- F1 uses equal one-vs-one class-pair and feature weighting, population
  variance, and PyCOL 1.0.4's nonfinite-ratio behavior.
- N3 uses one neighbor and is averaged equally across true classes.
- kDN is the sample-micro fraction of disagreeing labels over the requested
  neighbor prefix.
- CM uses the strict `different_neighbors * 2 > k` condition.
- C1 averages same-label purity over every ordered neighbor prefix.
- N1 uses a deterministic minimum-spanning forest and excludes distances
  `<= 1e-8`.

The kNN implementation excludes only the diagonal, retains eligible
zero-distance duplicates, and resolves computed equal distances using the
smallest original sample index.

The optional reference can be called with:

```python
from pycol_optimized import compute_n1_reference

reference = compute_n1_reference(vectors, labels)
```

## Devices and numerical behavior

The CPU and Apple MPS paths are validated. The CUDA code path uses the same
PyTorch operations but has not yet been benchmarked on NVIDIA hardware.

The implementation intentionally uses float32. Results normally agree with
the official float64 reference within the documented tolerances, but
float32-collapsed points and equal or nearly equal distances can alter
neighbor or minimum-spanning-tree order. In the validation suite, the only
out-of-tolerance non-N1 result was C1 on a deliberately adversarial tied,
cross-class-duplicate fixture; no reported metric or dataset ranking changed.

## Scaling limitation

The current exact implementation materializes a dense `n x n` float32 distance
matrix and a same-sized working copy for kNN construction. Memory and distance
computation are therefore quadratic in the number of samples. Sampling is
recommended for large datasets; exact blockwise kNN is not implemented yet.

## Development

```bash
ruff check .
ruff format --check .
pytest
python -m build
twine check dist/*
check-wheel-contents dist/*.whl
```

See `RELEASING.md` for the publication checklist and `NOTICE` for the
relationship to the separately maintained PyCOL project.
