Что такое ближайший сосед по K?

K-Nearest Neighbor или иначе известный как KNN - это алгоритм машинного обучения, который имеет список доступных случаев и классифицирует данные на основе системы измерения сходства. Эта модель участвует в контролируемом обучении и чаще всего используется в качестве алгоритма регрессии.

Что означает наличие супервизора для модели?

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

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

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

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

Что значит для модели быть алгоритмом классификации?

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

Ближайшие соседи

Давайте посмотрим на красивый рисунок, который я сделал. Как видите, есть группа фиолетовых и синих точек, которые расположены отдельно. Затем из ниоткуда появляется ярко-зеленая точка, и она никуда не годится… ЕЩЕ.

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

Так как же определить, является ли зеленая точка фиолетовой или синей?

Чтобы узнать истинный цвет зеленой точки, нам нужно рассчитать расстояние от зеленой точки до ее соседей. Допустим, мы хотим иметь 4 соседей.

Изображенный большой круг показывает 4 соседа зеленой точки в пределах круга. Чтобы определить, принадлежит ли зеленая точка к группе фиолетовых или группе синих точек, нам нужно будет вычислить расстояние между зеленой точкой и ее соседями. Для этого мы можем использовать формулу евклидова расстояния, которую можно представить как d = sqrt ((x-a) ² + (y-b) ²).

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

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

Преимущества

  • просто реализовать
  • нет времени на обучение классификации
  • KNN адаптируется к новым данным. Поскольку явного обучения нет, мы можем продолжать добавлять новые данные, а прогноз просто корректируется без необходимости переобучать модель.
  • В целом очень гибкая модель, существует множество гиперпараметров и метрик расстояния.

Недостатки

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

KNN в Python

Теперь мы изучили предысторию алгоритма K-Nearest Neighbour, но давайте также рассмотрим его с помощью Python.

О наборе данных

Информация об этом наборе данных:

Возможности

  • длина чашелистика в см
  • ширина чашелистика в см
  • длина лепестка в см
  • ширина лепестка в см

Цели

  • Ирис-Сетоса
  • Ирис-разноцветный
  • Ирис-Вирджиния

Чтобы узнать больше: https://en.wikipedia.org/wiki/Iris_flower_data_set

Импорт

Вот наш импорт:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris 
from sklearn.neighbors import KNeighborsClassifier

Нам понадобится numpy для создания массивов numpy.

Мы будем использовать patplotlib для визуализации данных.

Мы импортируем train_test_split из sklearn.model_selection для обучения наших данных.

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

Наконец, мы импортируем KNeighborsClassifier из sklearn.neighbors (наша модель knn).

Манипуляция данными

iris = load_iris()
#print(iris.data)
#print(iris.feature_names) --> shows features
#print(iris.target_names) --> prints target names, 0 = setosa, 1 = versicolor, 2 = virginica
print(iris.keys())

Мы будем хранить данные диафрагмы в переменной «iris» и использовать load_iris () для вызова данных.

При работе с данными полезно смотреть на разные части нашего набора данных, чтобы узнать больше о том, с чем мы работаем.

Если мы напечатаем iris.data, вы увидите что-то вроде массива, но гораздо длиннее:

[[5.1 3.5 1.4 0.2]
[4.9 3. 1.4 0.2]
[4.7 3.2 1.3 0.2]
[4.6 3.1 1.5 0.2]
[5. 3.6 1.4 0.2]
[5.4 3.9 1.7 0.4]]

Что это за случайные десятичные значения?
Мы можем распечатать названия наших функций, чтобы узнать, и если вы это сделаете, вы увидите список значений:

[«Длина чашелистика (см)», «ширина чашелистника (см)», «длина лепестка (см)», «ширина лепестка (см)»]

По сути, это список названий наших функций. Как видите, характеристики включают длину чашелистика, ширину чашелистика, длину лепестка и ширину лепестка. Наши характеристики представляют каждое отдельное числовое значение в нашем массиве (в порядке перечисленных функций).

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

Если вы это сделаете, вы увидите список типов ирисов.

[‘Setosa’, ‘versicolor’, ‘virginica’]

Позиции типов ириса в списке: setosa [0], versicolor [1] и virginica [2].

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

print(iris.keys)
OUTPUT: 
dict_keys([‘data’, ‘target’, ‘frame’, ‘target_names’, ‘DESCR’, ‘feature_names’, ‘filename’])

Визуализация

При работе с данными всегда очень полезно делать визуализацию. Matplotlib - отличная библиотека для этого на Python. Ниже приведен код, который отображает некоторую текущую информацию о наборе данных.

x_i = 0
y_i = 1

formatter = plt.FuncFormatter(lambda i, *args: iris.target_names[int(i)])
plt.figure(figsize=(5, 4))
plt.scatter(iris.data[:, x_i], iris.data[:, y_i], c=iris.target)
plt.colorbar(ticks=[0, 1, 2], format=formatter)
plt.title('Iris Scatter Plot')
plt.xlabel(iris.feature_names[x_i])
plt.ylabel(iris.feature_names[y_i])
plt.show()
x = iris['data']
y = iris['target']

Обучение

Мы можем использовать функцию sklearn train_test_split, чтобы разделить наши данные на два подмножества: данные обучения и данные тестирования. По сути, с этой функцией нам не нужно вручную разделять набор данных.

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.4, random_state=42)
knn = KNeighborsClassifier(n_neighbors=3)

Мы также определили нашу модель knn, которая использует алгоритм Sklearn KNeighborsClassifier, и предоставили параметр из 3 соседей.

Точность

Мы можем дополнительно подогнать наши данные x_train и y_train к модели, а затем вычислить оценку данных x_test и y_test, используя метод score (). Для этого конкретного набора данных у вас, вероятно, будет оценка точности около 98.

knn.fit(x_train, y_train)
print(knn.score(x_test, y_test))

Прогнозы

А что, если мы хотим предсказать, что произойдет со значением, которое может не быть задано в наборе данных?

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

x_new_value = np.array([[5.0, 2.9, 1.0, 0.2]])
print(knn.predict(x_new_value)) # since the output of this is 0, the flower is setosa

Свяжитесь со мной по любым вопросам 🚀

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

Если вам понравилась эта статья, вы можете проверить мою рукописную классификацию цифр MNIST, используя нейронную сеть в PyTorch :)

Привет, я Эшли, 16-летний ботаник-программист и искусственный интеллект. энтузиаст!

Надеюсь, вам понравилось читать мою статью, и если да, не стесняйтесь проверить некоторые из моих других статей на Medium :)

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

💫Электронная почта: [email protected]

💫 Linkedin

💫 Github