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

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

Это как, расскажи мне о своих близких друзьях, и я скажу, кто ты! «K» количество близких друзей, где K - целое число, которое нам нужно определить.

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

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

Итак, начнем с внедрения KNN. На самом деле это всего лишь 3 простых шага:

  1. Вычислите расстояние (евклидово, манхэттенское и т. Д.) Между точкой тестовых данных и каждой точкой данных обучения. Это для того, чтобы увидеть, кто ближе, а кто насколько далеко.
  2. Отсортируйте расстояния и выберите K ближайших расстояний (первые K записей) от него. Это будут K ближайших соседей для данной точки тестовых данных.
  3. Получить метки выбранных соседей K. Наиболее распространенная метка (метка с большинством голосов) будет прогнозируемой меткой для нашей тестовой точки данных.

Повторите все вышеизложенное для всех точек тестовых данных в вашем тестовом наборе.

Теперь давайте напишем код для реализации KNN без использования Scikit learn.

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

Импорт основных библиотек

import numpy as np
import scipy.spatial
from collections import Counter

загрузка набора данных Iris-Flower из Sklearn

from sklearn import datasets
from sklearn.model_selection import train_test_split
iris = datasets.load_iris()
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state = 42, test_size = 0.2)

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

Мы определим класс «KNN», внутри которого мы определим каждую важную функцию, которая заставит наш алгоритм работать. У нас будут следующие методы внутри нашего класса.

  1. fit: как обсуждалось ранее, он просто хранит данные при себе, поскольку KNN не выполняет никакого явного процесса обучения.
  2. Расстояние: здесь мы рассчитаем евклидово расстояние.
  3. Прогноз: это этап, на котором мы будем прогнозировать класс для нашего тестового экземпляра, используя полные данные обучения. Мы реализуем трехэтапный процесс, описанный выше, в этом методе.
  4. Оценка. Наконец, у нас будет метод оценки, позволяющий рассчитать оценку нашей модели на основе данных тестирования.
  5. А как насчет «K»? Наиболее важным здесь является K, мы передадим «K» в качестве аргумента при инициализации объекта для нашего класса KNN (внутри __init__)

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

Сначала я напишу полный курс, а затем мы обсудим последовательность действий:

class KNN:
    def __init__(self, k):
        self.k = k
        
    def fit(self, X, y):
        self.X_train = X
        self.y_train = y
        
    def distance(self, X1, X2):
        distance = scipy.spatial.distance.euclidean(X1, X2)
    
    def predict(self, X_test):
        final_output = []
        for i in range(len(X_test)):
            d = []
            votes = []
            for j in range(len(X_train)):
                dist = scipy.spatial.distance.euclidean(X_train[j] , X_test[i])
                d.append([dist, j])
            d.sort()
            d = d[0:self.k]
            for d, j in d:
                votes.append(y_train[j])
            ans = Counter(votes).most_common(1)[0][0]
            final_output.append(ans)
            
        return final_output
    
    def score(self, X_test, y_test):
        predictions = self.predict(X_test)
        return (predictions == y_test).sum() / len(y_test)

Посмотрите, что происходит:

Мы передадим K при создании объекта для класса «KNN».

Метод Fit принимает только данные обучения, и ничего больше.

Мы использовали scipy.spatial.distance.euclidean для вычисления расстояния между двумя точками.

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

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

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

Престижность! Вот и все. Это действительно так просто! Теперь давайте запустим нашу модель и протестируем наш алгоритм на тестовых данных, которые мы разделили ранее.

clf = KNN(3)
clf.fit(X_train, y_train)
prediction = clf.predict(X_test)
for i in prediction:
    print(i, end= ' ')

Это наш прогноз по тестовым данным! Мы были бы не против сравнить его с реальными тестовыми этикетками, чтобы увидеть, как мы справились. Посмотрим.

prediction == y_test

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

clf.score(X_test, y_test)

Готово! Это действительно так просто и аккуратно. KNN имеет очень простой и минималистский подход, который во многом интуитивно понятен, но при этом представляет собой мощный и универсальный алгоритм машинного обучения, способный решать широкий спектр проблем.

Вот и все, ребята! :)