KNN: K Nearest Neighbor - один из фундаментальных алгоритмов машинного обучения. Модели машинного обучения используют набор входных значений для прогнозирования выходных значений. KNN - одна из простейших форм алгоритмов машинного обучения, которые в основном используются для классификации. Он классифицирует точку данных по тому, как классифицируется ее сосед.

KNN классифицирует новые точки данных на основе меры сходства ранее сохраненных точек данных. Например, если у нас есть набор данных о помидорах и бананах. KNN будет хранить аналогичные меры, такие как форма и цвет. Когда приходит новый объект, он проверяет его сходство по цвету (красный или желтый) и форме.

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

Как выбрать K?

В реальных задачах, когда у нас много точек, возникает вопрос: как выбрать значение K?

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

а. K = sqrt (общее количество точек данных).

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

Когда KNN?

а. У нас есть данные с должной маркировкой. Например, если мы прогнозируем, что у кого-то диабет или нет, окончательная метка может быть 1 или 0. Это не может быть NaN или -1.

б. Данные без шума. Для набора данных о диабете мы не можем иметь уровень глюкозы как 0 или 10000. Это практически невозможно.

c. Небольшой набор данных.

Как работает KNN?

Обычно мы используем евклидово расстояние для вычисления ближайшего соседа. Если у нас есть две точки (x, y) и (a, b). Формула для евклидова расстояния (d) будет

d = sqrt ((x-a) ² + (y-b) ²)

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

Давайте попробуем KNN в одной базе данных, чтобы увидеть, как это работает. Данные можно извлечь из https://github.com/adityakumar529/Coursera_Capstone/blob/master/diabetes.csv.

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score
from sklearn.metrics import f1_score

pd и np предназначены для pandas и библиотеки NumPy. Последние 3 строки (confusion_matrix, precision_score и f1_score) предназначены для проверки точности модели. train_test_split предназначен для разделения и обучения данных. KNeighborsClassifier предназначен для K ближайшего соседа. Стандартизация наборов данных является общим требованием для многих оценщиков машинного обучения: они могут плохо себя вести, если отдельные функции не более или менее выглядят как стандартные нормально распределенные данные.

data = pd.read_csv("../input/diabetes.csv")
data.head()

Мы прочитали CSV-файл через pd.read_csv. А через головку () мы видим верхние 5 рядов. Есть некоторые факторы, значения которых не могут быть нулевыми. Например, уровень глюкозы для человека не может быть 0. Точно так же кровяное давление, толщина кожи, инсулин и ИМТ не могут быть нулевыми для человека.

non_zero = ['Glucose','BloodPressure','SkinThickness','Insulin','BMI']
for coloumn in non_zero:
    data[coloumn] = data[coloumn].replace(0,np.NaN)
    mean = int(data[coloumn].mean(skipna = True))
    data[coloumn] = data[coloumn].replace(np.NaN, mean)
    print(data[coloumn])
0      148.0
1       85.0
2      183.0
3       89.0
4      137.0
       ...  
763    101.0
764    122.0
765    121.0
766    126.0
767     93.0
Name: Glucose, Length: 768, dtype: float64
0      72.0
1      66.0
2      64.0
3      66.0
4      40.0
       ... 
763    76.0
764    70.0
765    72.0
766    60.0
767    70.0
Name: BloodPressure, Length: 768, dtype: float64
0      35.0
1      29.0
2      29.0
3      23.0
4      35.0
       ... 
763    48.0
764    27.0
765    23.0
766    29.0
767    31.0
Name: SkinThickness, Length: 768, dtype: float64
0      155.0
1      155.0
2      155.0
3       94.0
4      168.0
       ...  
763    180.0
764    155.0
765    112.0
766    155.0
767    155.0
Name: Insulin, Length: 768, dtype: float64
0      33.6
1      26.6
2      23.3
3      28.1
4      43.1
       ... 
763    32.9
764    36.8
765    26.2
766    30.1
767    30.4
Name: BMI, Length: 768, dtype: float64

Мы создали non_zero, в котором есть все столбцы, необходимые для прогнозирования конечного значения. Нам нужно убедиться, что эти столбцы не имеют никакого значения, связанного с нулем или значением NaN. Если у нас 0, мы заменим его на NaN. А затем заменив NaN на среднее значение столбца. Давайте нанесем на график подробные данные о диабете.

import seaborn as sns
p=sns.pairplot(data, hue = 'Outcome')

Мы определили non_zero со столбцом, значения которого не могут быть нулевыми. В каждом столбце мы сначала проверим, есть ли у нас 0 значений. Затем мы заменяем его на NaN. Позже мы создаем значение столбца и заменяем предыдущее на среднее.

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

X =data.iloc[:,0:8]
y =data.iloc[:,8]
X_train,X_test,y_train, y_test = train_test_split(X, y, test_size=0.2,random_state=0, stratify=y)

Для данных X мы берем все строки столбцов в диапазоне от 0 до 7. Аналогично, для y мы берем все строки для 8-го столбца.

У нас есть train_test_split, который мы импортировали во время запуска программы, и мы определили размер теста как 0,2, что означает, что из всех данных 20% будут отложены для тестирования данных на более позднем этапе.

#feature Scaling
sc_X = StandardScaler()
X_train = sc_X.fit_transform(X_train)
X_test = sc_X.transform(X_test)

StandardScaler выполняет задачу стандартизации. Обычно набор данных содержит переменные, различающиеся по масштабу. Например, набор данных будет содержать столбец инсулина со значениями по шкале 20–70 и столбец глюкозы со значениями по шкале 80–200. Поскольку эти два столбца различаются по масштабу, они стандартизированы, чтобы иметь общий масштаб при построении модели машинного обучения.

import math
math.sqrt(len(y_test))

Вне:

12.409673645990857

Мы взяли это значение, чтобы получить значение K. Нам нужно нечетное значение K, поэтому мы сделаем его 12–1 или 12 + 1.

classifier = KNeighborsClassifier(n_neighbors=13,p=2,metric='euclidean')
classifier.fit(X_train,y_train)

Вне:

KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='euclidean',
                     metric_params=None, n_jobs=None, n_neighbors=13, p=2,
                     weights='uniform')

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

y_pred =  classifier.predict(X_test)
y_pred

Вне:

array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1,
       1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0,
       1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0,
       0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0,
       0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0,
       0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1,
       0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0])

У нас есть массив данных, но нам нужно оценить нашу модель, чтобы проверить точность. Начнем с матрицы путаницы.

cm= confusion_matrix(y_test,y_pred)
cm

Вне:

array([[86, 14],
       [24, 30]])

У нас есть матрица неточностей, где диагональ с 86 и 30 показывает правильное значение, а 14, 24 показывает прогноз, который мы пропустили.

Мы проверим счет f1.

print(f1_score(y_test,y_pred))

Вне

0.6122448979591836
print(accuracy_score(y_test,y_pred))

Вне:

0.7532467532467533

У нас есть оценка f1 как 0,61 и оценка точности 0,75.

Давайте построим график для фактических данных и нашего прогнозируемого значения.

import matplotlib.pyplot as plt
plt.figure(figsize=(5, 7))

ax = sns.distplot(data['Outcome'], hist=False, color="r", label="Actual Value")
sns.distplot(y_pred, hist=False, color="b", label="Predicted Values", ax=ax)

plt.title('Actual vs Precited value for outcome')
plt.show()
plt.close()

Фактический код можно проверить на:



Https://github.com/adityakumar529/Coursera_Capstone/blob/master/KNN.ipynb.