k-Nearest-Neighbors (k-NN) - это модель машинного обучения с учителем. Контролируемое обучение - это когда модель учится на данных, которые уже помечены. Модель контролируемого обучения принимает набор входных объектов и выходных значений. Затем модель обучается на этих данных, чтобы узнать, как сопоставить входные данные с желаемыми выходными данными, чтобы она могла научиться делать прогнозы на основе невидимых данных.
Модели k-NN работают, беря точку данных и глядя на «k» ближайших помеченных точек данных. Затем точке данных присваивается метка большинства «k» ближайших точек.
Например, если k = 5 и 3 точки являются «зелеными», а 2 - «красными», то рассматриваемая точка данных будет помечена как «зеленая», поскольку «зеленые» составляют большинство (как показано на приведенном выше графике. ).
Scikit-learn - это библиотека машинного обучения для Python. В этом руководстве мы построим модель k-NN с помощью Scikit-learn, чтобы предсказать, есть ли у пациента диабет.
Чтение обучающих данных
Для нашей модели k-NN первым шагом является считывание данных, которые мы будем использовать в качестве входных. В этом примере мы используем набор данных о диабете. Для начала мы будем использовать Pandas для чтения данных. Я не буду вдаваться в подробности о Pandas, но это библиотека, с которой вам следует ознакомиться, если вы хотите глубже погрузиться в науку о данных и машинное обучение.
import pandas as pd #read in the data using pandas df = pd.read_csv(‘data/diabetes_data.csv’) #check data has been read in properly df.head()
Затем давайте посмотрим, сколько у нас данных. Мы вызовем функцию shape в нашем фрейме данных, чтобы увидеть, сколько строк и столбцов содержится в наших данных. В строках указано количество пациентов, а в столбцах указано количество характеристик (возраст, вес и т. Д.) В наборе данных для каждого пациента.
#check number of rows and columns in dataset df.shape
Мы видим, что у нас есть 768 строк данных (потенциальные пациенты с диабетом) и 9 столбцов (8 входных функций и 1 целевой выход).
Разделите набор данных на входы и цели
Теперь давайте разделим наш набор данных на входные (X) и нашу цель (y). Мы будем вводить все столбцы, кроме «диабета», потому что «диабет» - это то, что мы будем пытаться предсказать. Следовательно, нашей целью будет «диабет».
Мы будем использовать функцию pandas «drop», чтобы удалить столбец «диабет» из нашего фрейма данных и сохранить его в переменной «X». Это будет наш вклад.
#create a dataframe with all training data except the target column X = df.drop(columns=[‘diabetes’]) #check that the target variable has been removed X.head()
Мы вставим столбец «диабет» нашего набора данных в нашу целевую переменную (y).
#separate target values y = df[‘diabetes’].values #view target values y[0:5]
Разделите набор данных на обучающие и тестовые данные
Теперь мы разделим набор данных на данные обучения и данные тестирования. Обучающие данные - это данные, на которых модель будет учиться. Данные тестирования - это данные, которые мы будем использовать, чтобы увидеть, насколько хорошо модель работает с невидимыми данными.
В Scikit-learn есть функция, которую мы можем использовать под названием «train_test_split», которая позволяет нам легко разделить наш набор данных на данные для обучения и тестирования.
from sklearn.model_selection import train_test_split #split dataset into train and test data X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1, stratify=y)
Train_test_split принимает 5 параметров. Первые два параметра - это входные и целевые данные, которые мы разделили ранее. Затем мы установим test_size на 0,2. Это означает, что 20% всех данных будет использоваться для тестирования, в результате чего 80% данных останется в качестве обучающих данных для модели, на которой можно будет учиться. Установка ‘random_state’ на 1 гарантирует, что мы получим одно и то же разбиение каждый раз, чтобы мы могли воспроизвести наши результаты.
Установка параметра «stratify» на y заставляет нашу тренировочную группу представлять долю каждого значения в переменной y. Например, в нашем наборе данных, если 25% пациентов страдают диабетом, а 75% не страдают диабетом, установка для параметра «стратификация» значения y гарантирует, что в случайное разделение будут включены 25% пациентов с диабетом и 75% пациентов без диабета.
Построение и обучение модели
Далее нам нужно построить модель. Вот код:
from sklearn.neighbors import KNeighborsClassifier # Create KNN classifier knn = KNeighborsClassifier(n_neighbors = 3) # Fit the classifier to the data knn.fit(X_train,y_train)
Сначала мы создадим новый классификатор k-NN и установим для n_neighbors значение 3. Напомним, это означает, что если по крайней мере 2 из 3 ближайших точек к новой точке данных являются пациентами без диабета, то новая точка данных будут помечены как «нет диабета», и наоборот. Другими словами, новая точка данных маркируется большинством из 3 ближайших точек.
Мы установили n_neighbors равным 3 в качестве отправной точки. Ниже мы более подробно рассмотрим, как лучше выбрать значение для «n_neighbors», чтобы модель могла улучшить свою производительность.
Далее нам нужно обучить модель. Чтобы обучить нашу новую модель, мы будем использовать функцию «fit» и передавать наши обучающие данные в качестве параметров, чтобы подогнать нашу модель к обучающим данным.
Тестирование модели
После обучения модели мы можем использовать функцию «прогнозирования» в нашей модели, чтобы делать прогнозы на основе наших тестовых данных. Как было видно при проверке «y» ранее, 0 указывает на то, что у пациента нет диабета, а 1 указывает на то, что у пациента действительно диабет. Для экономии места мы покажем print только первые 5 прогнозов нашего тестового набора.
#show first 5 model predictions on the test data knn.predict(X_test)[0:5]
Мы видим, что модель предсказала «отсутствие диабета» для первых 4 пациентов в тестовой выборке и «диабет» для 5-го пациента.
Теперь давайте посмотрим, насколько точна наша модель на всем тестовом наборе. Для этого мы воспользуемся функцией «score» и передадим тестовые входные и целевые данные, чтобы увидеть, насколько хорошо наши прогнозы модели соответствуют фактическим результатам.
#check accuracy of our model on the test data knn.score(X_test, y_test)
Наша модель имеет точность примерно 66,88%. Это хорошее начало, но ниже мы увидим, как повысить производительность модели.
Поздравляю! Вы построили потрясающую модель k-NN!
k-кратная перекрестная проверка
Перекрестная проверка - это случайное разбиение набора данных на «k» групп. Одна из групп используется в качестве тестового набора, а остальные используются в качестве обучающего набора. Модель обучается на обучающем наборе и оценивается на тестовом наборе. Затем процесс повторяется до тех пор, пока каждая уникальная группа не будет использоваться в качестве тестового набора.
Например, для 5-кратной перекрестной проверки набор данных будет разделен на 5 групп, а модель будет обучена и протестирована 5 раз, так что каждая группа получит шанс стать тестовым набором. Это можно увидеть на графике ниже.
Метод «поезд-тест-разделение», который мы использовали ранее, называется «задержка». Перекрестная проверка лучше, чем использование метода удержания, потому что оценка метода удержания зависит от того, как данные разделяются на наборы для обучения и тестирования. Перекрестная проверка дает модели возможность протестировать на нескольких разделениях, чтобы мы могли лучше понять, как модель будет работать с невидимыми данными.
Чтобы обучить и протестировать нашу модель с помощью перекрестной проверки, мы будем использовать функцию cross_val_score со значением перекрестной проверки 5. cross_val_score принимает нашу модель k-NN и наши данные в качестве параметров. Затем он разбивает наши данные на 5 групп и сравнивает и оценивает наши данные 5 раз, каждый раз записывая оценку точности в массив. Мы сохраним оценки точности в переменной «cv_scores».
Чтобы найти среднее из 5 оценок, мы будем использовать функцию numpy mean, передавая "cv_score". Numpy - полезная математическая библиотека на Python.
from sklearn.model_selection import cross_val_score import numpy as np #create a new KNN model knn_cv = KNeighborsClassifier(n_neighbors=3) #train model with cv of 5 cv_scores = cross_val_score(knn_cv, X, y, cv=5) #print each cv score (accuracy) and average them print(cv_scores) print(‘cv_scores mean:{}’.format(np.mean(cv_scores)))
Используя перекрестную проверку, наш средний балл составляет около 71,36%. Это более точное представление того, как наша модель будет работать с невидимыми данными, чем наше предыдущее тестирование с использованием метода удержания.
Параметры модели гипертюнинга с использованием GridSearchCV
При построении нашей исходной модели k-NN мы устанавливаем параметр «n_neighbors» равным 3 в качестве отправной точки без какой-либо реальной логики, стоящей за этим выбором.
Параметры гипертюнинга - это когда вы выполняете процесс поиска оптимальных параметров для вашей модели с целью повышения точности. В нашем случае мы будем использовать GridSearchCV, чтобы найти оптимальное значение для «n_neighbors».
GridSearchCV работает, обучая нашу модель несколько раз по диапазону параметров, которые мы указываем. Таким образом, мы можем протестировать нашу модель с каждым параметром и определить оптимальные значения для получения наилучших результатов точности.
Для нашей модели мы укажем диапазон значений для «n_neighbors», чтобы увидеть, какое значение лучше всего подходит для нашей модели. Для этого мы создадим словарь, установив «n_neighbors» в качестве ключа и используя numpy для создания массива значений от 1 до 24.
Наша новая модель, использующая поиск по сетке, примет новый классификатор k-NN, наш param_grid и значение перекрестной проверки 5, чтобы найти оптимальное значение для «n_neighbors».
from sklearn.model_selection import GridSearchCV #create new a knn model knn2 = KNeighborsClassifier() #create a dictionary of all values we want to test for n_neighbors param_grid = {‘n_neighbors’: np.arange(1, 25)} #use gridsearch to test all values for n_neighbors knn_gscv = GridSearchCV(knn2, param_grid, cv=5) #fit model to data knn_gscv.fit(X, y)
После обучения мы можем проверить, какие из наших тестируемых нами значений параметра «n_neighbors» оказались наиболее эффективными. Для этого мы вызовем в нашей модели "best_params_".
#check top performing n_neighbors value knn_gscv.best_params_
Мы видим, что 14 - оптимальное значение для «n_neighbors». Мы можем использовать функцию «best_score_» для проверки точности нашей модели, когда «n_neighbors» равно 14. «best_score_» выводит среднюю точность оценок, полученных посредством перекрестной проверки.
#check mean score for the top performing value of n_neighbors knn_gscv.best_score_
Используя поиск по сетке для поиска оптимального параметра для нашей модели, мы повысили точность нашей модели более чем на 4%!
Спасибо за прочтение! Репозиторий GitHub для этого руководства (блокнот jupyter и набор данных) можно найти здесь.
Если вы хотите быть в курсе моих материалов по машинному обучению, подписывайтесь на меня :)