Вернуться на страницу brain2net:

https://brain2net.ru/post/algoritm-k-blizhajshih-sosedej/#more-55

Классификация - метод k ближних соседей

In [1]:
import numpy as np
import pandas as pd
import random
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier, KNeighborsRegressor
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
In [2]:
%matplotlib inline
In [3]:
# Загружаем учебный набор данных.
cancer = load_breast_cancer()
# Делим этот набор на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(
cancer.data, cancer.target, stratify=cancer.target, random_state=66)
In [4]:
training_accuracy = []
test_accuracy = []
# пробуем n_neighbors от 1 до 10
neighbors_settings = range(1, 11)
In [5]:
for n_neighbors in neighbors_settings:
    # строим модель
    clf = KNeighborsClassifier(n_neighbors=n_neighbors)
    clf.fit(X_train, y_train)
    # записываем правильность на обучающем наборе
    training_accuracy.append(clf.score(X_train, y_train))
    # записываем правильность на тестовом наборе
    test_accuracy.append(clf.score(X_test, y_test))
In [6]:
plt.plot(neighbors_settings, training_accuracy, label="правильность на обучающем наборе")
plt.plot(neighbors_settings, test_accuracy, label="правильность на тестовом наборе")
plt.ylabel("Правильность")
plt.xlabel("количество соседей")
plt.legend()
Out[6]:
<matplotlib.legend.Legend at 0x1673bd78708>

Построение модели заключается в простом запоминании обучающего набора данных.

Для того, чтобы сделать прогноз для новой точки данных, алгоритм находит ближайшие к ней точки обучающего набора, то есть находит «ближайших соседей».

При использовании лишь одного соседа каждая точка обучающего набора имеет очевидное влияние на прогнозы, и предсказанные значения проходят через все точки данных. Это приводит к очень неустойчивым прогнозам.

Увеличение числа соседей приводит к получению более сглаженных прогнозов, но при этом снижается правильность подгонки к обучающим данным

Регрессия - метод k ближних соседей

In [8]:
n_x = 50
a_x = -3
b_x = 3
x =[random.uniform(a_x, b_x) for _ in range(n_x)]
In [9]:
a_y = 1.5
b_y =0.5
s_y = 0.5
y = [a_y * u + b_y + random.gauss(0, s_y) for u in x ]
In [10]:
plt.plot(x,y,'bo')
plt.grid()
In [11]:
X = [[u] for u in x]
In [12]:
x = np.array(x)
y = np.array(y)
In [13]:
# разбиваем набор данных wave на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
In [14]:
# создаем экземпляр модели и устанавливаем количество соседей равным 3
reg = KNeighborsRegressor(n_neighbors=3)
# подгоняем модель с использованием обучающих данных и обучающих ответов
reg.fit(X_train, y_train)
Out[14]:
KNeighborsRegressor(algorithm='auto', leaf_size=30, metric='minkowski',
                    metric_params=None, n_jobs=None, n_neighbors=3, p=2,
                    weights='uniform')
In [15]:
print("R^2 на тестовом наборе: {:.2f}".format(reg.score(X_test, y_test)))
R^2 на тестовом наборе: 0.95
In [ ]:
 
In [16]:
# создаем 1000 точек данных, равномерно распределенных между -3 и 3
line = np.linspace(-3, 3, 1000).reshape(-1, 1)
In [17]:
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
for n_neighbors, ax in zip([1, 3, 9], axes):
    # получаем прогнозы, используя 1, 3, и 9 соседей
    reg = KNeighborsRegressor(n_neighbors=n_neighbors)
    reg.fit(X_train, y_train)
    ax.plot(line, reg.predict(line))
    ax.plot(X_train, y_train, '^', )
    ax.plot(X_test, y_test, 'v', )
    ax.set_title(
        "{} neighbor(s)\n train score: {:.2f} test score: {:.2f}".format(
        n_neighbors, reg.score(X_train, y_train),
        reg.score(X_test, y_test)))
    ax.set_xlabel("Признак")
    ax.set_ylabel("Целевая переменная")
axes[0].legend(["Прогнозы модели", "Обучающие данные/ответы",
"Тестовые данные/ответы"], loc="best")
Out[17]:
<matplotlib.legend.Legend at 0x1673bf80288>

На практике обычно хорошо работает использование небольшого числа соседей (например, 3-5). Но этот параметр может быть настроен в каждом конкретном случае.

По умолчанию используется евклидово расстояние, которое хорошо работает во многих ситуациях.

Одним из преимуществ метода ближайших соседей является то, что эту модель очень легко интерпретировать и, как правило, этот метод дает приемлемое качество без необходимости использования большого количества настроек. Он является хорошим базовым алгоритмом, который нужно попробовать в первую очередь, прежде чем рассматривать более сложные методы. Построение модели ближайших соседей происходит очень быстро при небольшом количестве выборки.

В случае большой обучающей выборки (с точки зрения количества характеристик или количества точек в обучающей выборке) получение прогнозов может занять значительное время. При использовании алгоритма ближайших соседей важно выполнение предварительной обработки данных.

Метод k ближайших соседей не целесообразно применять, когда речь идет о наборах данных с большим количеством признаков (сотни и более).

Также метод плохо работает в ситуации, когда подавляющее число признаков в большей части наблюдений имеют нулевые значения (так называемые разреженные наборы данных или sparse datasets).

Вернуться на страницу brain2net:

https://brain2net.ru/post/algoritm-k-blizhajshih-sosedej/#more-55

In [ ]: