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

Фемистокл, продавая поместье, велел глашатаю объявить, что у него и сосед хороший.
Плутарх
Продолжаем работу над совершенствованием диагностики рака молочной железы. Мы уже познакомились с логистической регрессией, которая предсказала отношение опухоли к добро- или злокачественной категории с 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 %.
Ссылки на ноутбук: