В этой статье мы разработаем модель машинного обучения с контролируемым обучением с использованием алгоритма k-ближайших соседей (kNN) в Python.

Алгоритм kNN

Алгоритм kNN — это алгоритм обучения с учителем, который можно использовать для решения задач как классификации, так и регрессии.

По алгоритму kNN вычисляются расстояния каждого из наблюдений определенного класса до значений наблюдений, класс которых неизвестен, и выбираются k наблюдений с наименьшим расстоянием. Расстояние до каждой единицы наблюдения можно рассчитать с помощью формулы Евклида, Манхэттена или аналогичной формулы расстояния. В этом примере мы будем использовать евклидово расстояние, чтобы найти ближайшие значения данных.

Прогнозирование наличия у людей диабета с помощью алгоритма kNN

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

Цель этого проекта — разработать модель, которая может предсказать, есть ли у людей диабет, если указаны их характеристики. Мы будем реализовывать kNN, чтобы делать прогнозы в Python, используя sklearn.

Установить и импортировать

import pandas as pd

from sklearn.metrics import classification_report, roc_auc_score
from sklearn.model_selection import GridSearchCV, cross_validate
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
pd.set_option('display.max_columns', None)

Исследовательский анализ данных

df = pd.read_csv('dataset/diabetes.csv')
df.head()

df.shape

df.describe().T

df['Outcome'].value_counts()
# df.head()

#    Pregnancies  Glucose  BloodPressure  SkinThickness  Insulin   BMI  \

# 0            6      148             72             35        0  33.6   

# 1            1       85             66             29        0  26.6   

# 2            8      183             64              0        0  23.3   

# 3            1       89             66             23       94  28.1   

# 4            0      137             40             35      168  43.1   

#    DiabetesPedigreeFunction  Age  Outcome  

# 0                     0.627   50        1  

# 1                     0.351   31        0  

# 2                     0.672   32        1  

# 3                     0.167   21        0  

# 4                     2.288   33        1

Предварительная обработка данных

y = df['Outcome']

X = df.drop(['Outcome'], axis=1)

В методах, основанных на расстоянии, переменные должны быть стандартизированы. StandardScaler будет методом, который мы будем использовать здесь:

X_scaled = StandardScaler().fit_transform(X)

Чтобы получить информацию о столбце, массив numpy должен быть преобразован в фрейм данных.

X = pd.DataFrame(X_scaled, columns=X.columns)

Модель и прогноз

knn_model = KNeighborsClassifier().fit(X, y)
random_user = X.sample(1, random_state=23)  #choose a random user
knn_model.predict(random_user)

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

Оценка модели

Чтобы предсказать для всех единиц наблюдения, определите y_pred для матрицы путаницы:

y_pred = knn_model.predict(X)

Нам нужно, чтобы вероятности принадлежали классу 1, а не y_pred (прогнозируемые значения) выше.

y_probe для AUC:

roc_auc_score(y, y_prob) # 0.90

Что на самом деле нужно сделать; оценить производительность модели на данных, которые она не видит. С этой целью будет использоваться метод перекрестной проверки для расчета точности, значений f1-score и roc-auc.

cv_results = cross_validate(knn_model,

                            X,

                            y,

                            cv=5,

                            scoring=['accuracy', 'f1', 'roc_auc'])
cv_results['test_accuracy'].mean()  # 0.73

cv_results['test_f1'].mean()        # 0.59

cv_results['test_roc_auc'].mean()   # 0.78

Как повысить эти показатели достижений?

Оптимизация может быть сделана для соответствующего алгоритма. Гиперпараметр n_neighbors в алгоритме kNN можно изменить.

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

Оптимизация гиперпараметров

knn_model = KNeighborsClassifier()

knn_model.get_params()

Цель состоит в том, чтобы найти оптимальное значение, изменив значение гипермараметра n_neighbors!

knn_params = {'n_neighbors': range(2, 50)}
knn_gs_best = GridSearchCV(knn_model,

                          knn_params,

                          cv=5,

                          n_jobs=-1,

                          verbose=1).fit(X, y)
knn_gs_best.best_params_

Окончательная модель

Теперь нам нужно посмотреть на ошибку теста финальной модели:

knn_final = knn_model.set_params(**knn_gs_best.best_params_).fit(X, y)
cv_results = cross_validate(knn_final,

                            X,

                            y,

                            cv=5,

                            scoring=['accuracy', 'f1', 'roc_auc'])
cv_results['test_accuracy'].mean()  # 0.77

cv_results['test_f1'].mean()        # 0.62

cv_results['test_roc_auc'].mean()   # 0.81

Как видно здесь, мы увеличили успех нашей модели за счет оптимизации гиперпараметров.

Давайте сделаем прогноз для 3 случайных пользователей!

random_user = X.sample(3)       

knn_final.predict(random_user)

Если вы зайдете на мою страницу Github, вы можете увидеть весь этот проект в скрипте.