Skip to main content

Test-data generator for validating the weighted k-NN (wkNN) method.

Project description

Thank you for sending the current README.md. Now I can see it's still the old README — it describes the previous anchor-based model (one anchor per class, dim-sized params like [a₁,b₁,…,a_d,b_d, f]), which we've now completely replaced. It needs a full rewrite to match the new weighted-kNN reference-cloud model.

But first — one honest reminder: I gave you the _wknn_scores fix for the two failing constant-weight tests in my last message, and I haven't seen the pytest output confirming it works. The README should document behavior that's actually verified. So please run:

uv run ruff check .
uv run ty check
uv run pytest -q

and confirm all 29 pass. If green, the README below is accurate. If the constant fix still fails, the "plain kNN majority vote among k nearest" description below would need adjusting — so let's confirm before you commit it.

Here's the fully refreshed file reflecting the new model (reference cloud + weighted k-NN + max_neighbors, single-distance params).

README.md

# 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 (also available as WknnDataGenerator.generate), which builds a labelled dataset (x, y) for testing weighted k-NN.

For each class the generator creates a small reference cloud of random points inside the cube [min_coord, max_abs_coord]^dim. A large pool of query points is then labelled by weighted k-nearest-neighbours against that reference set: each query's distance to every reference point is weighted by a distance-decreasing function, and the class with the largest summed weight wins. Weights are functions of a single scalar — the (normalised) Euclidean distance d between a query and a reference point — and must decrease as d grows (otherwise a ValueError is raised).

Weight functions and parameter layout

Weights depend on one scalar distance d, so params no longer scale with dim.

weight_type Formula params length Constraint
"constant" w = 1 ignored always valid (reduces to plain kNN)
"linear" w = max(a·d + f, 0) 2 [a, f] a ≤ 0
"inverse" w = a / d^b + f 3 [a, b, f] a ≥ 0, b > 0
"exponential" w = a·exp(−b·d) + f 3 [a, b, f] a ≥ 0, b > 0

Example: linear with params=[-1, 1] gives w = max(-1·d + 1, 0) — weight 1 at d=0, decreasing to 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]
max_neighbors None max number of nearest reference points allowed into each query point's weighted vote; None = all, a cap larger than the reference set is clamped
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.
  • Neighbour cap (weighted k-NN): with max_neighbors=k, each query point is classified using only its k nearest reference points. This lets a single close point of one class outweigh several far points of another. Example: for a query at (100, 100) with four class-0 points near the origin and one class-1 point at (99, 99), max_neighbors=1 correctly returns class 1. A cap >= size of the reference set (or None) uses every point.

Example

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, 0.1]),  # a, b, f  (single-distance layout)
    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))

Example — max_neighbors

# Cap the vote to the nearest reference points so a single close point of a
# minority class can outweigh several far points of another.
x, y = generate(
    n_classes=5,
    n_samples=60,
    weight_type="inverse",
    params=np.array([2.0, 1.0, 0.1]),
    max_neighbors=3,
    random_state=0,
)
print(x.shape, y.shape, np.bincount(y))

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

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

Для каждого класса генератор создаёт небольшое опорное облако случайных точек внутри куба [min_coord, max_abs_coord]^dim. Затем большой пул точек- запросов размечается методом взвешенных k ближайших соседей относительно этого опорного набора: расстояние каждого запроса до всех опорных точек взвешивается убывающей по расстоянию функцией, и побеждает класс с наибольшим суммарным весом. Веса зависят от одного скаляра — (нормированного) евклидова расстояния d между запросом и опорной точкой — и должны убывать с ростом d (иначе возбуждается ValueError).

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

Веса зависят от одного скалярного расстояния d, поэтому длина params больше не зависит от dim.

weight_type Формула Длина params Ограничение
"constant" w = 1 не используется всегда допустимо (обычный kNN)
"linear" w = max(a·d + f, 0) 2 [a, f] a ≤ 0
"inverse" w = a / d^b + f 3 [a, b, f] a ≥ 0, b > 0
"exponential" w = a·exp(−b·d) + f 3 [a, b, f] 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]
max_neighbors None максимум ближайших опорных точек, участвующих во взвешенном голосовании точки-запроса; None = все, значение больше опорного набора обрезается
random_state None зерно генератора

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

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

  • Стратификация: классы сбалансированы (разница ≤ 1 объект).
  • Удаление ничьих: точки с равными весами двух лучших классов удаляются.
  • Выбросы: заданная доля наиболее пограничных точек переставляется в класс-«второе место», равномерно по всему кубу (а не из одной плоскости).
  • Проверка монотонности: невозрастающие/неубывающие параметры → ValueError.
  • Ограничение соседей (взвешенный k-NN): при max_neighbors=k точка-запрос классифицируется по k ближайшим опорным точкам. Это позволяет одной близкой точке одного класса перевесить несколько далёких точек другого. Пример: для запроса (100, 100) с четырьмя точками класса 0 у начала координат и одной точкой класса 1 в (99, 99) значение max_neighbors=1 корректно вернёт класс 1. Значение >= размера опорного набора (или None) использует все точки.

Пример

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, 0.0]),  # a, b, f  (single-distance layout)
    outlier_ratio=0.15,
    max_neighbors=4,
    random_state=7,
)
print(x.shape, y.shape, np.bincount(y))

License / Лицензия

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


## Key changes from the old README (so you can review deliberately)

1. **Model description rewritten** — "random anchor per class → nearest total weight" replaced with "reference cloud per class → weighted k-NN vote." Both EN and RU.
2. **Param layouts corrected** — every formula now uses a single distance `d`:
   - `linear`: `[a₁,…,a_d, f]` → **`[a, f]`**
   - `inverse`/`exponential`: `[a₁,b₁,…,a_d,b_d, f]` → **`[a, b, f]`**
   - The old spec-example `params=[-1,-8,9]` (which no longer validates) was **removed** and replaced with `[-1, 1]`.
3. **Example params updated** — old `[2.0, 1.0, 3.0, 1.5, 0.1]` (5 values, invalid now) → **`[2.0, 1.0, 0.1]`**; exponential `[5,0.01,4,0.02,0]` → **`[5.0, 0.01, 0.0]`**. These match the params your passing tests use.
4. **`max_neighbors` documented** — new parameter-table rows, behaviour-guarantee bullets with the `(100,100)` worked example, and a dedicated usage snippet, in both languages.

## Before you commit this README

Please confirm the two things I still haven't seen verified:

1. **`pytest` is fully green** after the `_wknn_scores` `constant`-weight fix (the description "reduces to plain kNN" must be true — i.e. `test_constant_weight_runs` passes).
2. **The `(100,100)` claim in the README is literally the passing test** (`test_user_100_100_example`) — so if that test is green, the README example is guaranteed accurate.

Paste the `pytest -q` output. If all pass, this README ships with `0.0.2`. If `constant` still fails, tell me and I'll adjust both the fix and this README's "plain kNN" wording to match reality.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

generate_test_data_for_wknn-0.0.3.tar.gz (11.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

generate_test_data_for_wknn-0.0.3-py3-none-any.whl (12.0 kB view details)

Uploaded Python 3

File details

Details for the file generate_test_data_for_wknn-0.0.3.tar.gz.

File metadata

  • Download URL: generate_test_data_for_wknn-0.0.3.tar.gz
  • Upload date:
  • Size: 11.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for generate_test_data_for_wknn-0.0.3.tar.gz
Algorithm Hash digest
SHA256 2ccfb6002885d339b7c355794a629757e45edf7420ec01df0357a210812f80ce
MD5 b58624a74defc8bfbf180ae1948c93f6
BLAKE2b-256 05ac80f8d56b00537e7aaa4d1749be9951129231117173c050862abbe4399a9d

See more details on using hashes here.

File details

Details for the file generate_test_data_for_wknn-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: generate_test_data_for_wknn-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 12.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for generate_test_data_for_wknn-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 66f2610494f3ee0f826cf886fcdf025e4369903ebfdbfddb851861fbb11b3ab6
MD5 e78df4664a610e9fe0b806590f5a674b
BLAKE2b-256 395f28b3e93b8d4080a053be2aea94c9f7a9b484f0b2af048d241a3d3c0c62a9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page