Реализация КНН
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.
Спасибо за чтение.