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

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

KNN следует очень простому правилу классификации наблюдений.

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

Принимая во внимание два наблюдения, O1 и O2 с функциями как X₁₁, X₁₂…..X₁n и X₂₁, X₂₂….X₂n соответственно; мы можем легко вычислить евклидово расстояние как,

Давайте напишем код, чтобы посмотреть, как он работает. Мы будем использовать набор данных sklearn breast_cancer для нашей цели.

#importing libraries
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
#importing data from sklearn
from sklearn.datasets import load_breast_cancer
data = load_breast_cancer()
#converting data into pandas dataframe
canc_data = pd.DataFrame(data.data, columns=data.feature_names)
#adding target field to the dataset
canc_data['target'] = pd.Series(data.target)
#creating X and y
X_feature = list(canc_data.columns)
X_feature.remove('target')
X = canc_data[X_feature]
y = canc_data['target']
#splitting data for training and testing
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 100)

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

#importing KNN from sklearn
from sklearn.neighbors import KNeighborsClassifier
knn_clf = KNeighborsClassifier(n_neighbors=5, metric='minkowski').fit(X_train, y_train)
#predicting for our test data
y_pred = knn_clf.predict(X_test)
#generating classification report
from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred))
#importing libraries to check model performance
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score
from sklearn.metrics import log_loss
from sklearn import metrics
print("Accuracy score on test: " , round((knn_clf.score(X_test, y_test)),3))
print("Accuracy score on train: ", round((knn_clf.score(X_train, y_train)),3))
#printing log loss for the model
print('log_loss : ', log_loss(y_test, y_pred))
#let find ROC and AUC score
#before we calculate roc_auc_score(), we need to find out the predicted probabilities for test data.
pred_prob = pd.DataFrame(knn_clf.predict_proba(X_test))
#we'll also add the actual label
test_result = pd.DataFrame( { 'actual' : y_test})
test_result = test_result.reset_index()
test_result['prob_0'] = pred_prob.iloc[:,0:1]
test_result['prob_1'] = pred_prob.iloc[:,1:2]
#to calculate ROC AUC score we will pass actual class labels and predicted probability
auc_score = round(metrics.roc_auc_score(test_result.actual, test_result.prob_1),3)
print("AUC Score : ",auc_score)
#generating confusion matrix
cf_matrix = confusion_matrix(y_test, y_pred)
sns.heatmap(cf_matrix, annot=True, cmap='Blues')
plt.ylabel("True Label")
plt.xlabel("Predicted Label")
plt.show()

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

GrisSearchCV будет принимать следующие параметры:

  1. оценщик : модель мл.
  2. param_grid : словарь с именами параметров в качестве ключа и списком значений параметров в качестве значений.
  3. оценка: показатель точности. 'r2'для регрессии, 'отзыв', "точность" и т. д. для классификации.
  4. cv : количество сгибов в k-кратном (каждый набор значений будет оцениваться путем перекрестной проверки в K-кратном порядке, поэтому окончательный балл будет представлять собой среднее значение балла по всем кратным перекрестным проверкам в K-кратном размере) )
#hyperparameter tuning using grid search
from sklearn.model_selection import GridSearchCV
#we'll create a dictionary with possible hyperparameter values
param_val = [{'n_neighbors' : range(3,10), 'metric' : ['euclidean', 'minkowski', 'canberra']}]
#grid search configuration
clfr = GridSearchCV(KNeighborsClassifier(), param_val, cv = 10, scoring = 'roc_auc')
#fitting into our data
clfr.fit(X_train, y_train)

После запуска GridSearchCV мы можем увидеть лучшие параметры следующим образом:

#we'll see for best score and parameters
print(clfr.best_score_)
print(clfr.best_params_)

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

# creating empty list variable
acc = []
# running KNN algorithm for 3 to 50 nearest neighbours(odd numbers) and storing the accuracy values
for i in range(3,50,2):
  neigh = KNeighborsClassifier(n_neighbors=i)
  neigh.fit(X_train, y_train)
  train_acc = np.mean(neigh.predict(X_train) == y_train)
  test_acc = np.mean(neigh.predict(X_test) == y_test)
  acc.append([train_acc, test_acc])
import matplotlib.pyplot as plt # library to do visualizations
# train accuracy plot
plt.plot(np.arange(3,50,2),[i[0] for i in acc],"ro-")
plt.show()

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