Metadata-Version: 2.4
Name: my-sire-that-is-an-outlier
Version: 0.1.0
Summary: Outlier detection for semi-normal distributions using the mirroring technique
License: MIT
Project-URL: Homepage, https://github.com/KushBagri/mirror_mirror
Project-URL: Issues, https://github.com/KushBagri/mirror_mirror/issues
Keywords: outlier,detection,statistics,distribution,anomaly
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
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 :: Mathematics
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: numpy>=1.21
Requires-Dist: scipy>=1.7
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: pandas>=1.3; extra == "dev"

# mirror-mirror

**Outlier detection for semi-normal distributions.**

Most outlier detection methods assume your data is fully normal. But what if it's only *half* normal — a clear peak with one meaningful tail? `mirror-mirror` handles exactly that.

## How it works

1. Find the **peak** of your distribution (via KDE or max value)
2. Take the **tail-side** data (everything at or below the peak)
3. **Mirror** it across the peak to create a synthetic full normal distribution
4. Compute **mean and std** of the synthetic distribution
5. Flag anything below `mean − threshold × std` as an **outlier**

## Installation

```bash
pip install mirror-mirror
```

## Quick start

```python
from mirror_mirror import find_outliers

# Example: exam scores — most students score high, outliers at the low end
scores = [95, 97, 92, 88, 91, 99, 100, 94, 96, 72, 65, 55, 48]

result = find_outliers(scores, method="mode", threshold=2)

print(result["outliers"])   # array([48])
print(result["cutoff"])     # e.g. 62.4
```

## API

```python
find_outliers(data, method="mode", threshold=2.0)
```

| Parameter   | Type                              | Default  | Description                                      |
|-------------|-----------------------------------|----------|--------------------------------------------------|
| `data`      | list / np.ndarray / pd.Series     | required | 1-D numeric data. NaNs are ignored.              |
| `method`    | `"mode"` or `"max"`              | `"mode"` | How to locate the peak of the distribution.      |
| `threshold` | float                             | `2.0`    | Sigmas below the mirror mean to cut off at.      |

### Return value

A `dict` with:

| Key            | Description                                              |
|----------------|----------------------------------------------------------|
| `outliers`     | `np.ndarray` of values identified as outliers            |
| `cutoff`       | The threshold value — points below this are outliers     |
| `mirror_mean`  | Mean of the synthetic mirrored distribution              |
| `mirror_std`   | Std dev of the synthetic mirrored distribution           |

### `method` parameter

- **`"mode"`** *(default)* — uses KDE to find the most-dense region of the data as the peak. Best for real-world, noisy data.
- **`"max"`** — uses the maximum value as the peak. Useful when your data is naturally bounded at the top (e.g. a 100-point exam, property values with a known ceiling).

### `threshold` parameter

Controls sensitivity. A value of `2.0` means any point more than 2 standard deviations below the mirror mean is flagged. Increase for fewer (more extreme) outliers; decrease for more.

## When to use this

`mirror-mirror` works well when your data:

- Has a clear, single peak
- Has one natural tail (skewed left or right)
- Is **not** bimodal or uniformly distributed

Examples: exam scores, property values, response times, sensor readings with a hard ceiling.

## License

MIT
