Привет! Меня зовут Рувим, я врач, в настоящее время живу в Индии. Это моя первая запись в серии статей, которые, как я надеюсь, будут основаны на использовании науки о данных в контексте проблем здравоохранения. Я не считаю себя экспертом в области науки о данных или алгоритмов машинного обучения, но у меня есть большой интерес к этой теме, и я надеюсь использовать этот блог, чтобы публиковать сообщения о моем прогрессе и проектах, которые я считаю интересными.

В своем первом проекте я решил протестировать алгоритм KNN на наборе данных, содержащем информацию о различных клеточных параметрах, чтобы отличить злокачественные клетки от доброкачественных. Хотя я пробовал использовать как R, так и Python, лично я предпочитаю R. Так что это то, что я буду использовать в этом проекте. Я буду использовать приложение под названием RStudio, которое служит средой, в которой я могу тестировать свой код и выполнять анализ.

Алгоритм KNN - это алгоритм, который на основе набора данных, на котором он обучен, смотрит на новое, ранее невидимое тестовое наблюдение, а затем определяет его «K ближайших соседей» (отсюда и название), где «K» - заранее определенное число. .

Но что означает «ближайший сосед»? Это просто относится к наблюдениям в наборе данных, к которым ближе всего новое тестовое наблюдение. Например, в наборе данных, классифицирующем различные продукты питания на фрукты или овощи по шкале сладости от 1 до 10, алгоритм KNN, обученный на этом наборе данных, будет рассматривать новое тестовое наблюдение (возможно, виноград) и определять, насколько похожи это к другим наблюдениям в наборе данных. Он делает это путем измерения евклидова расстояния (да, я немного объясню этот термин) между соответствующими переменными каждого наблюдения. По сладости виноград был бы ближе к манго, чем к огурцу. Таким образом, разница в сладости между киви и огурцом будет больше, чем между киви и манго. Если большинство элементов в «k ближайших соседях» классифицируются как фрукты, алгоритм также классифицирует виноград как фрукт.

Хорошо, давайте рассмотрим термин «евклидово расстояние», чтобы мы действительно поняли, что происходит, когда начнется собственно машинное обучение. Допустим, огурец в моем гипотетическом наборе данных о фруктах и ​​овощах имеет показатель хрусткости 8 и сладость 2. С другой стороны, манго имеет показатель хрусткости 2 и показатель сладости 9. Давайте назовем это наши обучающие наблюдения, так как это то, на чем будет обучаться наш алгоритм. Если этот алгоритм обнаруживает новый продукт питания, например, виноград с оценкой хрусткости 4 и сладостью 7, он рассчитывает расстояние между различными продуктами.

dist (виноград, огурец) = √ [(8–4) ² + (2–7) ²] ≈ 6,4

dist (виноград, манго) = √ [(2–4) ² + (9–7) ²] ≈ 2,8

Виноград явно ближе к манго, чем к огурцу. Алгоритм KNN идентифицирует «K» ближайших соседей, а затем определяет категорию теста на основе того, какая категория чаще всего встречается среди этих соседей. Если бы наш гипотетический набор данных был больше и мы выбрали K = 7, алгоритм бы отыскал категорию (фрукты или овощи), которая встречается чаще всего среди 7 ближайших соседей, и определит, что тестовое наблюдение относится к этой категории большинства.

Без лишних слов, давайте перейдем непосредственно к работе. И я начну с обсуждения самого набора данных. Я получил данные из репозитория UCI Machine Learning ^ [1]. Он состоит из фрейма данных с 569 наблюдениями (строки) и 32 переменными (столбцы). Каждое наблюдение представляет различные размеры клеточных ядер (площадь, кривизна и т. Д.), Вычисленные на основе изображений аспиратов тонкой иглой (метод диагностики для отбора образцов ткани из органа) ткани груди.

Приведенный выше код импортирует набор данных в RStudio, а затем выводит следующее:

Прежде чем я смог даже изучить данные, мне нужно было лучше понять некоторые ключевые параметры. Например, были ли у столбцов имена? Самому алгоритму не нужны имена столбцов, но я хотел подготовить несколько графиков, используя данные в столбцах. Это было бы довольно сложно, если бы я не знал, что означает каждая колонка! На рисунке ниже показан код, который я использовал для проверки первых пяти имен столбцов, а также результат этого кода.

Ясно, что столбцы этих данных безымянны. Итак, первое, что я сделал, это получил имена столбцов отсюда.

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

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

Я все же пройдусь по нескольким интересным столбцам. Самый первый столбец - это просто идентификатор для каждого наблюдения. Что касается нашей цели, то это абсолютно бесполезно. Идентификатор не дает вам реальной информации об основных данных, поэтому мы скоро удалим весь столбец.

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

Двигаясь дальше, я хотел убедиться, что в наборе данных нет пропущенных значений. Пропущенные значения могут быть проблемой, поэтому лучше проверить их как можно раньше. Я написал функцию для проверки отсутствующих значений и передал в функцию фрейм данных. Функция проверяет каждый столбец на наличие пропущенных значений, а затем сообщает количество пропущенных значений для этого столбца.

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

Прежде чем я обучу этот набор данных, я хотел бы поделиться некоторыми очень простыми визуализациями, чтобы укрепить логику алгоритма. Ниже приведены различия в площади ядра, компактности и радиусе соответственно между доброкачественными и злокачественными образцами. Хотя я мог закодировать эти графики на R, я решил использовать Tableau Public, потому что использовать графический интерфейс всегда проще.

Я выбрал эти параметры наугад. Из того, что я узнал в медицине о злокачественных опухолях в целом, повреждение ДНК и изменение окружающих ее белков приводит к образованию ядер ненормального размера и формы. Так что я ожидал увидеть эти различия. Но даже тот, кто абсолютно ничего не знает о злокачественных клетках, может сделать эти визуализации, чтобы сделать выводы о различиях между этими двумя типами тканей. Важно то, что существуют такие измеримые различия. Алгоритм KNN будет использовать эти различия, чтобы классифицировать наши тестовые образцы как доброкачественные или злокачественные.

Прежде чем я обучил свой набор данных, я решил случайным образом переупорядочить строки, чтобы предотвратить проблемы, которые могли возникнуть из-за того, что данные были упорядочены определенным образом заранее. Например, если бы все злокачественные ткани были помещены ближе к концу, поскольку я собираюсь использовать первые 80% строк для обучения данных, у алгоритма не будет достаточно образцов злокачественных образований, на которых можно было бы учиться.

Столбец диагнозов содержит наши диагнозы, хранящиеся в виде «строк». Это просто означает, что данные в этом столбце могут быть «строкой» из любого количества символов (алфавитов или цифр). В идеале мы хотели бы, чтобы данные хранились в виде «факторов». Факторы могут принимать только ограниченный набор значений. Любое значение вне предопределенного набора будет отклонено. При работе с алгоритмами классификации лучше работать с факторами, так как вам не придется беспокоиться о том, что строка будет неправильно набрана. Это легко исправить с помощью одной быстрой строки кода.

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

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

Один из наиболее важных шагов подготовки данных при создании модели KNN - это нормализация данных. Это означает, что каждый столбец должен быть представлен по шкале от 0 до 1. Причина, по которой мы это делаем, заключается в том, что алгоритм KNN ищет сходство между тестовым наблюдением и наблюдениями в наборе данных, измеряя разницу между соответствующими переменными каждого наблюдения. Таким образом, если одна переменная измеряется в масштабе, который намного больше, чем большинство других наблюдений (например, если бы она измерялась в сантиметрах, а другие переменные измерялись в микронах), это будет иметь большое влияние на способ определения сходства алгоритмом. Поэтому я написал функцию для нормализации данных и передал в нее фрейм данных. Я передал в функцию все столбцы, кроме того, который содержит диагнозы, поскольку это наша целевая переменная, которую необходимо предсказать. Также нельзя нормализовать нечисловые значения.

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

Хорошо, похоже, у нас все готово. Теперь нам нужно разделить набор данных на два - набор для обучения и набор для тестирования. Мы воспользуемся обучающим набором для обучения алгоритма knn, а затем воспользуемся набором для тестирования, чтобы проверить точность нашей модели. Мы также извлечем метки train и test по отдельности, так как их нужно будет передать как отдельные аргументы в функцию knn. Я решил использовать деление 80–20 (больше похоже на 82–18). Таким образом, мы будем использовать около 80% набора данных для обучения алгоритма, а остальные 20% - для его тестирования. Всегда существует компромисс между наличием достаточного количества образцов для обучения данных и наличия достаточного количества образцов для тестирования данных.

Нужная нам функция knn находится в пакете «class». Если вы все еще читаете это, спасибо за ваше терпение. Теперь ваше терпение будет вознаграждено. Давайте внедрить KNN!

После небольшого проб и ошибок я обнаружил, что 11 - лучшее количество соседей, которых стоит искать. Нечетные числа лучше четных, так как это исключает возможность связи (столько же доброкачественных и злокачественных тканей у k ближайших соседей). 11 оказывается почти половиной квадратного корня из общего числа выборок. Функция knn () возвращает список прогнозируемых диагнозов. Но соответствуют ли они реальным диагнозам? Давайте разберемся.

Фактический вывод, производимый этим кодом, на самом деле чертовски запутан. Поэтому я написал код, чтобы преобразовать эти результаты в аккуратную небольшую таблицу непредвиденных обстоятельств. Посмотрим на результаты!

В приведенной выше таблице строки представляют собой фактические диагнозы, а столбцы представляют диагноз, присвоенный каждому образцу теста нашим алгоритмом. В нашем наборе данных было 57 доброкачественных и 43 злокачественных образца. Из них все 57 доброкачественных образцов были идентифицированы правильно! Из 43 образцов злокачественной опухоли только 2 были ошибочно идентифицированы как доброкачественные. Это дает алгоритму 100% -ную специфичность и 98% -ную точность.
Здесь можно было бы реализовать более продвинутые методы. Например, я мог бы присвоить каждой переменной разный вес. Также существуют методы обработки изображений. Это избавит от необходимости сначала измерить различные размеры сотовой связи и подготовить набор данных, содержащий всю эту информацию. Вместо этого модель, способная обрабатывать изображения, могла бы просто смотреть на изображения клеточной ткани для выполнения этой классификации.
Однако цель этого упражнения заключалась просто в том, чтобы продемонстрировать преимущества интеграции методов машинного обучения в здравоохранение.
Надеюсь в ближайшем будущем поработать над более сложными проектами. И я уверен, что они будут более полезными, чем этот. Но полного потенциала машинного обучения и науки о данных, даже если он только что основан на крошечной модели KNN, более чем достаточно, чтобы меня воодушевить его будущее в сфере здравоохранения.

Использованная литература:

  1. Дуа, Д. и Графф, К. (2019). Репозиторий машинного обучения UCI [http://archive.ics.uci.edu/ml]. Ирвин, Калифорния: Калифорнийский университет, Школа информационных и компьютерных наук.