# k-NN (k-Nearest Neighbors)

Этот проект реализует алгоритм k-ближайших соседей (k-NN) для задач классификации и регрессии. Код написан на Python и включает методы для обучения модели, предсказания значений, автоматической настройки гиперпараметров, вычисления точности (accuracy) и визуализации данных.

---

## Описание

Алгоритм k-NN — это метод машинного обучения, используемый для задач классификации и регрессии. Модель предсказывает значение целевой переменной на основе значений ближайших соседей в пространстве признаков. В данном случае реализованы как невзвешенный k-NN, так и взвешенный k-NN с использованием различных ядерных функций.

---

## Использование

Для использования класса `KNN` выполните следующие шаги:

1. Импортируйте необходимые библиотеки:

   ```python
   import numpy as np
   import matplotlib.pyplot as plt
   ```
2. Создайте экземпляр класса `KNN`.
3. Обучите модель, передав матрицу признаков `X` и вектор меток `y` в метод `fit`.
4. Используйте методы `predict`, `tune_parameters`, `accuracy_score` и `plot` для оценки качества модели и визуализации данных.

---

## Методы класса

### 1. `__init__(kernel_type='Gaussian', distance_metric='euclidean', k=3, h=0.1, task="classification")`

Инициализация модели k-NN.

- **Параметры:**
  - `kernel_type`: Тип ядерной функции (`'Rectangular'`, `'Triangular'`, `'Epanechnikov'`, `'Quartic'`, `'Triweight'`, `'Tricube'`, `'Gaussian'`, `'Cosine'`, `'Logistic'`, `'Sigmoid'`, `'Silverman'` или `None` для невзвешенного k-NN).
  - `distance_metric`: Метрика расстояния (`'euclidean'` или `'manhattan'`).
  - `k`: Число соседей.
  - `h`: Ширина ядра (для ядрового взвешивания).
  - `task`: `'classification'` или `'regression'`.

---

### 2. `_init_kernels()`

Инициализирует словарь с ядерными функциями.

---

### 3. `_kernel_function(u)`

Вычисляет значение ядерной функции.

- **Аргументы:**
  - `u`: Аргумент функции ядра.
- **Возвращает:**
  - Значение ядерной функции.

---

### 4. `_distance(x1, x2)`

Вычисляет расстояние между двумя точками.

- **Поддерживаемые метрики:**
  - `'euclidean'`: Евклидово расстояние.
  - `'manhattan'`: Манхэттенское расстояние.

---

### 5. `fit(X_train, y_train)`

Обучает модель, сохраняя обучающую выборку.

- **Параметры:**
  - `X_train`: Массив признаков размером `(n_samples, n_features)`.
  - `y_train`: Вектор меток размером `(n_samples,)`.

---

### 6. `predict(X)`

Предсказывает значения целевой переменной для объектов `X`.

- **Параметры:**
  - `X`: Массив объектов размером `(n_samples, n_features)`.
- **Возвращает:**
  - Предсказанные значения целевой переменной.

---

### 7. `tune_parameters(X_val, y_val, k_candidates=None, h_candidates=None)`

Автоматическая настройка гиперпараметров `k` и `h` с использованием валидационной выборки.

- **Параметры:**
  - `X_val`: Массив признаков валидационной выборки.
  - `y_val`: Вектор меток валидационной выборки.
  - `k_candidates`: Список кандидатов для параметра `k`.
  - `h_candidates`: Список кандидатов для параметра `h`.
- **Возвращает:**
  - Лучшие параметры и соответствующую метрику качества.

---

### 8. `accuracy_score(y_true, y_pred)`

Вычисляет точность модели (для задачи классификации).

- **Параметры:**
  - `y_true`: Истинные значения.
  - `y_pred`: Предсказанные значения.
- **Возвращает:**
  - Accuracy-значение.

---

### 9. `plot(X, y)`

Визуализирует обучающую выборку и целевые точки (для двумерных данных).

- **Параметры:**
  - `X`: Массив объектов размером `(n_samples, 2)`.
  - `y`: Вектор меток размером `(n_samples,)`.
- **Примечание:** Метод поддерживает только двумерные данные.

---

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

```python
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split

# Генерация синтетических данных
X, y = make_classification(n_samples=100, n_features=2, n_informative=2, n_redundant=0, random_state=42)



# Разделение данных на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(
    pd.DataFrame(X), pd.DataFrame(y), test_size=0.2, random_state=42
)

# Создание и обучение модели
model = KNN()
model.fit(X_train, y_train)

# Предсказание и оценка точности
y_pred = model.predict(X_test)

accuracy = model.accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.2f}")

# Визуализация данных
model.plot(X_test, y_test)
model.plot(X_test, y_test)
```

---

## Требования

Для работы с кодом необходимо установить следующие библиотеки:

- `numpy`
- `matplotlib`

Установите их с помощью pip:

```bash
pip install numpy matplotlib
```
