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

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

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

вес киви (в граммах) = [90, 80, 85, 75, 82, 71, 88, 91, 85, 81]
вес яблок (в граммах) = [140, 145, 143, 160, 135, 142, 150, 173, 150, 155]

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

Как мы видим, точки в левом кластере (зеленые) представляют вес киви, а точки в правом кластере (красный) представляют вес яблок.

Теперь предположим, что машина должна классифицировать фрукт весом 130 грамм, чтобы он был представлен, как на рисунке ниже (тестовый фрукт отмечен синим цветом).

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

В этом примере мы используем расстояние как — |x -xₜ| где x — новый вход, а xₜ — точка, от которой мы хотим рассчитать расстояние. Обычно при реализации KNN мы используем евклидово расстояние или расстояние Махаланобиса, поскольку они более обобщены и могут использоваться для входных векторов признаков различных размеров. [Примечание — евклидово расстояние = SQRT((x -xₜ)²)].

Краткое объяснение алгоритма KNN —

  1. загрузите данные обучения (поместите эти точки в наше векторное пространство)
  2. Загрузите тестовый вектор (нанесите его на карту), а затем рассчитайте расстояние (может быть разного типа — Евклидово, Махаланобиса и т. д.) каждой обучающей точки от точки вектора тестового признака.
  3. расположите расстояния в порядке возрастания.
  4. Решите, сколько соседей должно определять класс контрольной точки. «K» в KNN означает количество соседей, поэтому, скажем, если K = 3, мы определим класс тестового вектора на основе трех самых близких точек к тестовому вектору. Это решение может быть простым голосованием (например, если 2 из ближайших точек относятся к классу «А» и одна к классу «В», то мы классифицируем ее как класс А) или решение может быть основано на взвешенном голосовании (где ближе к делу, тем больший вес будет иметь его голос)
  5. На основе K-ближайших соседей мы классифицируем тестовый вектор, т. е. предсказываем его принадлежность к определенному классу.

Теперь, возвращаясь к нашему примеру выше, давайте рассмотрим алгоритм KNN для классификации фруктов весом 130 г.

Шаг 1) уже выполнен, поскольку мы представили эти точки (вычислений не требуется).
для шага 2 — вычисляем евклидовы расстояния для нашей точки 130 со всеми остальными точками обучающих данных.

3) предполагая, что мы используем (k=3) для нашего KNN (3 — ближайшие соседи), мы выбираем 3 ближайших соседа, и они получаются — 135g, 140g и 142g — все 3 ближайших соседа принадлежат к классу — « Яблоко"

4) следовательно, мы предсказываем, что неизвестный фрукт весом 130 г должен быть яблоком.

Теперь мы усложним игру и усложним модель. Мы бы попробовали использовать векторы 2D-признаков и набор данных, чьи метки немного сложнее различить.

Допустим, наши данные основаны на классификации двух разных типов листьев (большой лист и маленький лист), чтобы лучше различать листья, мы записываем их длину и вес в виде двумерного вектора — (x единиц, y единиц), где x единиц относятся к весу листа, а y единиц относятся к его длине.

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

Итак, теперь давайте предположим, что нам нужно проверить лист с длиной и весом как (10 единиц, 6 единиц) — поэтому мы представляем тестовый вектор как — (10, 6)

А затем вычисляем евклидово расстояние тестового вектора со всеми обучающими точками и узнаем ближайших соседей к нашему тестовому вектору

На рисунке ниже мы видим, что тестовый вектор (зеленый) ближе всего к красным точкам (векторы признаков Большого листа), а 3 ближайших соседа — это «Большой лист», поэтому мы классифицируем/предсказываем тестовый вектор как принадлежащий Семья «Большой лист».

Теперь давайте рассмотрим простую реализацию классификации KNN на основе Python с использованием scikit-learn.

  1. мы получаем входные данные и отделяем набор обучающих данных от набора тестовых данных, чтобы проверить, будет ли наша модель работать с данными, которые она не обучала ранее — в приведенном ниже примере мы используем тестовые данные, чтобы они составляли 20% от общего объема данных, что означает, что 80% всех данных будут использоваться в качестве обучающих данных.
from sklearn.model_selection import train_test_split
# input_data = [<<data : Extracted Feature Vectors>>]
# input_labels = [<<corresponding data class labels >>]
training_data, test_data, training_labels, test_labels = train_test_split(input_data,input_labels,test_size=0.2)

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

from sklearn.neighbors import KNeighborsClassifier
knn_classifier = KNeighborsClassifier(n_neighbors=3)
knn_classifier.fit(training_data, training_labels)

3. Теперь, после того, как тестовые прогнозы сделаны, мы вычислим показатели точности и матрицу путаницы следующим образом:

from sklearn import metrics
from sklearn.metrics import confusion_matrix
accuracy_percentage = 100*metrics.accuracy_score(test_labels, predictions)
conf_matrix = confusion_matrix(test_labels, predictions)
# Print out the results
print(" Accuracy percentage is - {}".format(accuracy_percentage))
print(" Confusion Matrix is - \n")
print(conf_matrix)

И вуаля! у нас есть результаты

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

Пожалуйста, оставьте «Хлопки», если вам понравилась эта статья!