kNN на NumPy: соседи, голоса и вероятности классов

Напишите ядро kNN-классификатора: найдите соседей, посчитайте доли голосов и разрешите ничью. Порядок столбцов вероятностей должен совпадать с порядком классов.

Программа курса «Классическое машинное обучение: алгоритмы и практика на Python».

Алгоритмическое ядро kNN: подсчёт голосов и разрешение ничьих

Что уже дано

Проверяющая система выполняет решение в среде Python 3.12 с установленными библиотеками numpy и scikit-learn. Вспомогательные переменные или файлы перед запуском не создаются. Проверяющий код напрямую вызывает функцию predict_knn_votes с тестовыми наборами данных.

Что нужно сделать

Реализуйте функцию predict_knn_votes(train_X, train_y, query_X, k).

Функция принимает:

  • train_X: числовая матрица признаков обучающей выборки (двумерный массив np.ndarray или вложенный список) формы (N_train, n_features);
  • train_y: одномерная последовательность (список или массив) строковых меток классов обучающей выборки длины N_train;
  • query_X: числовая матрица признаков запросов формы (N_query, n_features);
  • k: положительное целое число соседей ().

Требования к алгоритмической механике:

  1. Определение классов модели: найдите все уникальные строковые метки классов из train_y и упорядочьте их строго лексикографически (по алфавиту). Этот список образует базовый массив классов модели classes длины .
  2. Поиск соседей: для каждого запроса из query_X вычислите евклидово расстояние до каждой обучающей точки. Выберите ровно ближайших обучающих примеров. Гарантируется, что на границе -го соседа расстояния не имеют неоднозначных совпадений.
  3. Подсчёт голосов: среди соседей подсчитайте количество точек каждого из классов. Доля голосов класса вычисляется как отношение числа его голосов к . Сформируйте двумерный массив probabilities формы (N_query, C) типа float64, где каждый столбец строго соответствует классу из отсортированного списка classes.
  4. Прогноз классов и tie-break: для каждого запроса выберите итоговую строковую метку класса prediction с максимальной долей голосов среди выбранных соседей. Если несколько классов набрали одинаковое максимальное число голосов (ничья), выберите тот класс, который идёт раньше в лексикографически упорядоченном массиве classes (стандартное правило scikit-learn).

Функция должна возвращать словарь со следующими точными ключами:

  • "classes": одномерный массив строк np.ndarray формы (C,) с лексикографически отсортированными уникальными классами;
  • "probabilities": двумерный вещественный массив np.ndarray формы (N_query, C) с типом элементов float64;
  • "predictions": одномерный строковый массив np.ndarray формы (N_query,) с предсказанными метками классов.

Ввод и вывод

stdin не используется. Печатать через print в stdout ничего не нужно. Проверяющая система вызывает predict_knn_votes с тестовыми аргументами и проверяет возвращённые массивы в словаре.

Пример использования

import numpy as np

X_tr = np.array([[0.0], [1.0], [2.0], [9.0]])
y_tr = ["alert", "ok", "ok", "alert"]
X_q = np.array([[1.0]])

res = predict_knn_votes(X_tr, y_tr, X_q, k=3)
print(res["classes"].tolist())
print(np.round(res["probabilities"], 4).tolist())
print(res["predictions"].tolist())

Результат:

['alert', 'ok']
[[0.3333, 0.6667]]
['ok']
РешениеPython

Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.

Отправьте решение, чтобы увидеть результаты тестов.

Связанные задачи