Metadata-Version: 2.3
Name: generate-test-data-for-wknn
Version: 0.0.1
Summary: Test-data generator for validating the weighted k-NN (wkNN) method.
Keywords: knn,weighted-knn,wknn,machine-learning,test-data
Author: Ferubko Andrey, Kazakov Oleg
Author-email: Ferubko Andrey <andrey.ferubko@petsplace.ru>
License: MIT
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
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
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Dist: numpy>=1.24
Maintainer: Ferubko Andrey, Kazakov Oleg
Maintainer-email: Ferubko Andrey <andrey.ferubko@petsplace.ru>
Requires-Python: >=3.10
Project-URL: Homepage, https://github.com/89605502155/generate-test-data-for-wknn
Project-URL: Repository, https://github.com/89605502155/generate-test-data-for-wknn
Project-URL: Issues, https://github.com/89605502155/generate-test-data-for-wknn/issues
Description-Content-Type: text/markdown

# generate-test-data-for-wknn

[![PyPI](https://img.shields.io/pypi/v/generate-test-data-for-wknn.svg)](https://pypi.org/project/generate-test-data-for-wknn/)
[![Python](https://img.shields.io/pypi/pyversions/generate-test-data-for-wknn.svg)](https://pypi.org/project/generate-test-data-for-wknn/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)

**EN** — Synthetic test-data generator for validating the **weighted k-NN (wkNN)** method.
**RU** — Генератор синтетических тестовых данных для проверки метода **взвешенного k-NN (wkNN)**.

*Authors / Авторы:* Ferubko Andrey, Kazakov Oleg
*Organization / Организация:* Bryansk State Technological University of Engineering /
Брянский государственный инженерно-технологический университет.

---

## Installation / Установка

```bash
pip install generate-test-data-for-wknn
# or with uv:
uv add generate-test-data-for-wknn
```

---

## English documentation

The library exposes a single public function, `generate`, which builds a
labelled dataset `(x, y)` for testing weighted k-NN.

Each class is given a random **anchor** point inside the cube
`[min_coord, max_abs_coord]^dim`. Every other random point is assigned to the
class whose **total weight** is largest. Weights are functions of the
per-coordinate absolute differences `x_i = |p_i - anchor_i|` and must
**decrease** as distance grows (otherwise a `ValueError` is raised).

### Weight functions and parameter layout

| `weight_type`  | Formula | `params` length | Constraint |
|----------------|---------|-----------------|------------|
| `"constant"`   | `w = 1` | ignored | always valid (reduces to plain kNN) |
| `"linear"`     | `w = max(Σ aᵢ·xᵢ + f, 0)` | `dim + 1` → `[a₁,…,a_d, f]` | all `aᵢ ≤ 0` |
| `"inverse"`    | `w = Σ aᵢ / xᵢ^bᵢ + f` | `2·dim + 1` → `[a₁,b₁,…,a_d,b_d, f]` | `aᵢ ≥ 0`, `bᵢ > 0` |
| `"exponential"`| `w = Σ aᵢ·exp(−bᵢ·xᵢ) + f` | `2·dim + 1` → `[a₁,b₁,…,a_d,b_d, f]` | `aᵢ ≥ 0`, `bᵢ > 0` |

> Example (from the spec): for `dim=2`, `linear` with `params=[-1, -8, 9]`
> corresponds to `w = max(-1·x₁ + -8·x₂ + 9, 0)`.

### Parameters

| Name | Default | Meaning |
|------|---------|---------|
| `n_classes` | `2` | number of classes (binary by default) |
| `dim` | `2` | dimensionality of each point |
| `n_samples` | `30` | number of objects in the dataset |
| `weight_type` | `"inverse"` | one of the four weighting schemes |
| `params` | `None` | coefficient array (see table) |
| `max_abs_coord` | `1e4` | upper coordinate bound (abs value cap) |
| `min_coord` | `-1e4` | lower coordinate bound (use `0` for e.g. time series) |
| `outlier_ratio` | `0.0` | fraction of **borderline** labels to flip, must be in `[0, 1]` |
| `random_state` | `None` | RNG seed |

**Returns:** `(x, y)` — `x` is `float64` of shape `(m, dim)`, `y` is `int64` of
shape `(m,)`, where `m ≤ n_samples` (tie points are removed).

### Behavioural guarantees

- **Stratification:** classes are balanced (counts differ by at most 1).
- **Ties dropped:** points where the top-2 class weights are equal are removed.
- **Outliers:** the requested fraction of the *most borderline* points is flipped
  to the runner-up class, spread evenly across the cube (not from a single plane).
- **Monotonicity guard:** non-decreasing weight parameters raise `ValueError`.

### Example

```python
import numpy as np
from generate_test_data_for_wknn import generate

# Binary, inverse-distance weights, 2-D, reproducible
x, y = generate(
    n_classes=2,
    dim=2,
    n_samples=50,
    weight_type="inverse",
    params=np.array([2.0, 1.0, 3.0, 1.5, 0.1]),  # a1,b1,a2,b2,f
    max_abs_coord=100.0,
    min_coord=0.0,          # non-negative coords (e.g. time series)
    outlier_ratio=0.1,
    random_state=42,
)
print(x.shape, y.shape, np.bincount(y))
```

---

## Документация на русском

Библиотека предоставляет одну публичную функцию `generate`, которая строит
размеченный набор данных `(x, y)` для проверки взвешенного k-NN.

Для каждого класса создаётся случайная **опорная точка** внутри куба
`[min_coord, max_abs_coord]^dim`. Каждой другой случайной точке присваивается
класс с наибольшим **суммарным весом**. Веса зависят от модулей разностей
координат `x_i = |p_i − anchor_i|` и **должны убывать** с ростом расстояния
(иначе возбуждается `ValueError`).

### Весовые функции и формат параметров

| `weight_type`  | Формула | Длина `params` | Ограничение |
|----------------|---------|----------------|-------------|
| `"constant"`   | `w = 1` | не используется | всегда допустимо (обычный kNN) |
| `"linear"`     | `w = max(Σ aᵢ·xᵢ + f, 0)` | `dim + 1` | все `aᵢ ≤ 0` |
| `"inverse"`    | `w = Σ aᵢ / xᵢ^bᵢ + f` | `2·dim + 1` | `aᵢ ≥ 0`, `bᵢ > 0` |
| `"exponential"`| `w = Σ aᵢ·exp(−bᵢ·xᵢ) + f` | `2·dim + 1` | `aᵢ ≥ 0`, `bᵢ > 0` |

### Параметры

| Имя | По умолчанию | Смысл |
|-----|--------------|-------|
| `n_classes` | `2` | число классов (по умолчанию бинарная задача) |
| `dim` | `2` | размерность точки |
| `n_samples` | `30` | число объектов |
| `weight_type` | `"inverse"` | схема взвешивания |
| `params` | `None` | массив коэффициентов (см. таблицу) |
| `max_abs_coord` | `1e4` | верхняя граница координат по модулю |
| `min_coord` | `-1e4` | нижняя граница (для временных рядов задайте `0`) |
| `outlier_ratio` | `0.0` | доля переставляемых **пограничных** меток, из `[0, 1]` |
| `random_state` | `None` | зерно генератора |

**Возвращает:** `(x, y)` — массивы NumPy; `m ≤ n_samples` (точки с ничьей удаляются).

### Гарантии поведения

- **Стратификация:** классы сбалансированы (разница ≤ 1 объект).
- **Удаление ничьих:** точки с равными весами двух лучших классов удаляются.
- **Выбросы:** заданная доля наиболее **пограничных** точек переставляется в
  класс-«второе место», равномерно по всему кубу (а не из одной плоскости).
- **Проверка монотонности:** невозрастающие/неубывающие параметры → `ValueError`.

### Пример

```python
import numpy as np
from generate_test_data_for_wknn import generate

x, y = generate(
    n_classes=3,
    dim=2,
    n_samples=60,
    weight_type="exponential",
    params=np.array([5.0, 0.01, 4.0, 0.02, 0.0]),  # a1,b1,a2,b2,f
    outlier_ratio=0.15,
    random_state=7,
)
print(x.shape, y.shape, np.bincount(y))
```

---

## License / Лицензия

MIT © Ferubko Andrey, Kazakov Oleg — Bryansk State Technological University of Engineering.