Реализация КНН

K-Nearest Neighbours — очень простой алгоритм обучения с учителем. Его можно применять как к задачам классификации, так и к задачам регрессии. Хотя он был введен в 1950-х годах, он все еще используется сегодня.

Давайте воспользуемся простым 2D-примером, чтобы лучше понять. У нас есть помеченный набор данных, содержащий 3 группы. Наша цель — выяснить, к какой группе принадлежит данное новое наблюдение.

Сначала находятся расстояния данной новой точки до других точек.

Существуют различные методы расчета расстояний. Наиболее часто используются евклидово расстояние и манхэттенское расстояние.

Евклидово расстояние

Вы знаете это из начальной школы. Гипотенузу вы нашли в теореме Пифагора.

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

Манхэттен Расстояние

Манхэттенское расстояние (другими словами, расстояние такси) рассчитывается по сеткам.

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

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

В задаче регрессии берется среднее значение k ближайших выбранных значений точек.

Алгоритм KNN чувствителен к выбросам и несбалансированным наборам данных.

Значение K контролирует баланс между переоснащением и недообучением.

  • Малый K: низкое смещение, высокая дисперсия -> переобучение
  • Большой K: высокое смещение, низкая дисперсия -> недообучение

Код Python

Реализация Sklearn

Давайте используем набор данных Iris для демонстрации.

from sklearn import datasets
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import confusion_matrix, accuracy_score

iris = datasets.load_iris()
X, y = iris.data, iris.target
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=1234
)

Выше кода (с нуля)

model = Knn()
model.fit(X_train, y_train)
y_pred = clf.predict(X_test)
cm = confusion_matrix(y_test, y_pred)
print(cm)
print("Manual Accuracy:", accuracy(y_test, y_pred))
#OUT
[[ 9  0  0]
 [ 0 12  1]
 [ 0  0  8]]
Manual Accuracy: 0.9666666666666667

Склерн

model = KNeighborsClassifier(n_neighbors=5)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
cm = confusion_matrix(y_test, y_pred)
print(cm)
print("Manual Accuracy:", accuracy(y_test, y_pred))
#OUT
[[ 9  0  0]
 [ 0 12  1]
 [ 0  0  8]]
Manual Accuracy: 0.9666666666666667

Выбор правильного значения K

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

k_list = list(range(1,50,2))
cv_scores = []
for k in k_list:
    knn = KNeighborsClassifier(n_neighbors=k)
    scores = cross_val_score(knn, X_train, y_train, cv=10, scoring='accuracy')
    cv_scores.append(scores.mean())
MSE = [1 - x for x in cv_scores]
plt.figure()
plt.figure(figsize=(15,10))
plt.title('K vs Error', fontsize=20, fontweight='bold')
plt.xlabel('K', fontsize=15)
plt.ylabel('Error', fontsize=15)
sns.set_style("whitegrid")
plt.plot(k_list, MSE)
plt.show()

Мы можем выбрать k равным 9.

Спасибо за чтение.

Читать далее…







Рекомендации

https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm

https://www.ibm.com/topics/knn