Машинное обучение в медицине: диагностика опухолей молочной железы с использованием метода k-ближайших соседей

Автор: Ксения Забудская
Редакция: Дарья Филатова
Оформление: Никита Родионов
Публикация: 10.11.2021

Фемистокл, продавая поместье, велел глашатаю объявить, что у него и сосед хороший.
Плутарх

Продолжаем работу над совершенствованием диагностики рака молочной железы. Мы уже познакомились с логистической регрессией, которая предсказала отношение опухоли к добро- или злокачественной категории с accuracy (доля правильных ответов алгоритма) 97,7 %. Много это или недостаточно, мы можем узнать лишь путем сравнения с другими моделями машинного обучения.

Датасет для работы хранится по ссылке: https://www.kaggle.com/uciml/breast-cancer-wisconsin-data

Сегодня мы попробуем метод k-ближайших соседей (англ. k-nearest neighbors algorithm, k-NN), иногда называемый анализом ближайшего сходства. Этот метод, как и логистическая регрессия, решает задачу классификации. Он относит объекты к классу, которому принадлежит большинство из k его ближайших соседей в многомерном пространстве признаков. «Соседи» — это объекты, близкие к исследуемому в том или ином смысле, причем модель понимает это буквально: подобные наблюдения близки друг к другу, а непохожие наблюдения, наоборот, удалены друг от друга. Фактически, расстояние между двумя наблюдениями является критерием их различия. У каждого объекта есть несколько признаков, и предполагается, что если объекты близки по ключевым признакам, они совпадают и по остальным, и следовательно, принадлежат к одному классу.

Число k — это количество соседних объектов в пространстве признаков, которые сравниваются с классифицируемым объектом. То есть, если k = 8, то каждый объект сравнивается с восемью своими соседями.

Черпать ресурсы все также будем из библиотек языка программирования Python, практически монополиста в области анализа данных. Напомню, библиотеки — это набор готовых функций, классов и объектов для решения каких-то задач. Как в реальной библиотеке вы можете взять любую книгу и получить из нее информацию для использования, так и в программистских библиотеках уже есть то, что можно взять готовым для реализации ваших идей.

Итак, вновь наши три всадника датасаентиста. Библиотека numpy, которая содержит реализации многомерных массивов и алгоритмов линейной алгебры. Библиотека pandas, которая предоставляет широкий спектр функций по обработке табличных данных. И библиотека scikit-learn, в которой реализовано множество алгоритмов машинного обучения (и нам не нужно их писать самим!).

Практика: проделываем все те же шаги из нашей предыдущей статьи до момента «призыва» модели. Нам нужно импортировать класс KNeighborsClassifier, в котором реализован интересный нам метод. Количество соседей k соответствует параметру n_neighbors (по умолчанию 5, мы оставим это значение). Выбор параметра k неоднозначен. Если мы выберем значение k слишком маленьким, появляется риск, что единственным ближайшим объектом окажется «выброс», т. е. объект с неправильно определенным классом, и он приведет к неверному решению. С другой стороны, увеличение значения k повышает достоверность классификации, но границы между классами становятся менее четкими.

Проблему выбора оптимального значения параметра k называют «bias-variance tradeoff», или «компромисс между [выбросами] и дисперсией». На практике чаще всего используют k = [√𝑁]. Если есть уверенность в чистоте выборки, можно уменьшить значение k.

Обучим модель с помощью метода fit на обучающей выборке x_train,y_train.

В качестве метрики используем расстояние Минковского (метрику Минковского). Это параметрическая метрика на евклидовом пространстве (в котором работают аксиомы евклидовой геометрии). С ее помощью можно найти расстояние порядка р между двумя точками (нашим объектом и его соседом).
 

#обучаем модель
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors = 5, metric = 'minkowski',p = 2)
knn.fit(x_train,y_train)
#строим confusion matrix
from sklearn.metrics import confusion_matrix
y_pred = knn.predict(x_test)
cm = confusion_matrix(y_test,y_pred)
print('confusion matrix:\n',cm)

#проверяем accuracy
from sklearn.metrics import accuracy_score
knna = accuracy_score(y_test,y_pred)
print('accuracy score = ',accuracy_score(y_test,y_pred))

#вывод программы
confusion matrix:
 [[52  2]
 [ 3 29]]
accuracy score =  0.9418604651162791

Что ж… Логистическая регрессия сработала лучше: ее 97,7 % против 94,2 %.

Ссылки на ноутбук:

Нашли опечатку? Выделите фрагмент и нажмите Ctrl+Enter.