Все, что вам нужно знать о KNN.

«Мужчина известен своей компанией».

Я должен сказать, что идеальная вступительная фраза для представления K-Nearest Neighbours. Да, вот насколько проста концепция, лежащая в основе KNN. Он просто классифицирует точку данных на основе нескольких ближайших соседей. Сколько соседей? Это то, что мы решаем.

Похоже, вы уже многое знаете об этой простой модели. Давайте погрузимся в подробности.

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

Классификатор KNN

Данные, которые мы собираемся использовать, - это Набор данных по раку молочной железы, штат Висконсин (диагностический). Существует 30 атрибутов, которые соответствуют действительным характеристикам, вычисленным для рассматриваемого ядра клетки. Всего в этих данных представлено 569 таких образцов, из которых 357 классифицируются как доброкачественные (безвредные), а остальные 212 классифицируются как злокачественные ( вредный).

Столбец диагноз содержит значения «M» или «B» для злокачественного и доброкачественного рака соответственно. Я изменил эти значения на 1 и 0 соответственно для лучшего анализа.

Кроме того, для этого поста я буду использовать только два атрибута из данных → «средний радиус» и «средняя текстура». Позже это поможет нам визуализировать границы принятия решений, проведенные KNN. Вот как выглядят окончательные данные (после перетасовки):

Давайте закодируем KNN:

# Defining X and y
X = data.drop('diagnosis',axis=1)
y = data.diagnosis
# Splitting data into train and test
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.25,random_state=42)
# Importing and fitting KNN classifier for k=3
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(X_train,y_train)
# Predicting results using Test data set
pred = knn.predict(X_test)
from sklearn.metrics import accuracy_score
accuracy_score(pred,y_test)

Приведенный выше код должен дать вам следующий результат с небольшими вариациями.

0.8601398601398601

Что сейчас произошло? Когда мы обучили KNN на обучающих данных, он предпринял следующие шаги для каждой выборки данных:

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

Давайте визуализируем, как KNN нарисовал границу принятия решения на наборе данных поезда и как эта же граница затем используется для классификации набора тестовых данных.

С точностью обучения 93% и точностью теста 86% наша модель могла бы показать здесь переоснащение. Почему так?

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

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

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

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

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

Давайте снова построим границу принятия решения для k = 11 и посмотрим, как это выглядит.

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

Давайте теперь разберемся, как KNN используется для регрессии.

Регрессор KNN

В то время как классификатор KNN возвращает режим ближайших K соседей, регрессор KNN возвращает среднее значение для ближайших K соседей.

Мы будем использовать рекламные данные, чтобы понять регресс KNN. Вот первые несколько строк ТВ-бюджета и продаж.

# Defining X and Y
X_ad = ad.TV.values.reshape(-1,1)
y_ad = ad.sales
# Splitting data into train and test
train_x, test_x, train_y, test_y = train_test_split(X_ad, y_ad, test_size=0.25, random_state=42)
# Running KNN for various values of n_neighbors and storing results
knn_r_acc = []
for i in range(1,17,1):
    knn = KNeighborsRegressor(n_neighbors=i)
    knn.fit(train_x,train_y)
    test_score = knn.score(test_x,test_y)
    train_score = knn.score(train_x,train_y)
    knn_r_acc.append((i, test_score ,train_score))
df = pd.DataFrame(knn_r_acc, columns=['K','Test Score','Train Score'])
print(df)

Приведенный выше код будет запускать KNN для различных значений K (от 1 до 16) и сохранять результаты обучения и тестов в Dataframe. Давайте посмотрим, как эти оценки меняются по мере увеличения значения n_neighbors (или K).

При K = 1 KNN имеет тенденцию внимательно следить за данными обучения и, таким образом, показывает высокий балл обучения. Однако для сравнения результат теста довольно низкий, что свидетельствует о переобучении.

Давайте визуализируем, как KNN рисует путь регрессии для различных значений K.

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

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

Как видно на этом рисунке, модель дает наилучшие результаты при K = 4. Я использовал R² для оценки модели, и это было лучшее, что мы могли получить. Это потому, что наш набор данных был слишком маленьким и разрозненным.

Некоторые другие моменты, которые важно знать о KNN:

  • Классификатор KNN не имеет специальной фазы обучения, поскольку он использует все обучающие выборки для классификации и просто сохраняет результаты в памяти.
  • KNN - это непараметрический алгоритм, потому что он ничего не предполагает об обучающих данных. Это делает его полезным для проблем с нелинейными данными.
  • KNN может быть дорогостоящим с точки зрения вычислений как с точки зрения времени, так и с точки зрения хранения, если данные очень большие, потому что KNN должен хранить обучающие данные для работы. Обычно это не относится к другим моделям обучения с учителем.
  • KNN может быть очень чувствительным к масштабу данных, поскольку он полагается на вычисление расстояний. Для объектов с более высоким масштабом вычисленные расстояния могут быть очень большими и давать плохие результаты. Поэтому рекомендуется масштабировать данные перед запуском KNN.

Это все для этого поста. Надеюсь, вы хорошо провели время, изучая KNN. Чтобы узнать больше, следите за обновлениями.