Мини-проект машинного обучения

Обнаружение важных характеристик с помощью генетических алгоритмов

(для прогноза выживаемости при сердечной недостаточности)

Оригинальный документ выглядит следующим образом:

Chicco, D., Jurman, G. Машинное обучение может прогнозировать выживаемость пациентов с сердечной недостаточностью только на основе креатинина сыворотки и фракции выброса. BMC Med Inform Decis Mak 20, 16 (2020). Https://doi.org/10.1186/s12911-020-1023-5

Этот набор данных имеет 12 функций, и вы можете загрузить его из Репозитория машинного обучения UCI. Это бинарная классификация, контролируемая задача обучения с DEATH_EVENT в качестве целевой переменной, 1 означает смерть и 0 означает выживание.

Возникает вопрос: как наиболее эффективно найти лучшего обучающегося (алгоритм) и лучшее подмножество функций? Иногда удивительно небольшие подмножества функций работают лучше, чем полный набор функций. Как лучше всего найти этот набор?

Во-первых, давайте оставим в стороне вопрос о лучшем ученике. Мы знаем одно: некоторые ученики обучаются быстрее, чем другие. Если вы хотите протестировать алгоритм генетического обучения для выбора функций, вы обнаружите, что использование логистической регрессии - самый быстрый путь, в то время как что-то на основе дерева, такое как Random Forest или LightGBM, занимает намного больше времени и может даже не работать правильно, в зависимости от библиотеки, которую вы используете.

РЕЗУЛЬТАТЫ ДОКУМЕНТОВ

Что обнаружили Chicco и Jurman:

  • Случайный лес был лучшим алгоритмом
  • Как статистические методы, так и методы машинного обучения показывают, что ejection_fraction и serum_creatinine являются одними из наиболее важных функций, и вы можете построить модель практически на их основе.

РЕЗУЛЬТАТЫ ДАННОГО ЭКСПЕРИМЕНТА

  • Генетические алгоритмы могут выбирать множество подмножеств функций
  • Результаты этого зависят от вашего выбора гиперпараметров для алгоритма, но это также требует, чтобы вы тщательно проверяли каждого из кандидатов, используя некоторую форму перекрестной проверки. Даже ваши параметры перекрестной проверки (количество складок и повторов) могут изменить результаты.
  • serum_creatinine и ejection_fraction, как они сказали, очень важны. В первых экспериментах, описанных в статье, не использовалась функция время, которая означала время в месяцах после последующего наблюдения, поскольку сама по себе она не является клинической характеристикой. Однако во второй эксперимент в своей статье они все же включили его. В этом проекте я исключаю функцию времени.

УСТАНОВИТЕ БИБЛИОТЕКИ

В основном это sklearn-генетический для методов генетического алгоритма (GA), и если вы хотите использовать некоторые методы типа autoML, установите pycaret. Кроме этого, нам просто нужны numpy и pandas.

Что такое генетические алгоритмы?

По сути, в нашем случае мы рассматриваем включение или исключение функции как двоичную строку, то есть строку из единиц и нулей, где 1 означает, что функция включена, а 0 означает, что она не включена. Это означает, что, поскольку у нас есть 12 функций, очевидно, что необходимо рассмотреть возможность 2¹² или подмножества всего набора функций. Смысл ГА состоит НЕ в том, чтобы проверить их все, а в том, чтобы рассмотреть несколько подмножеств - назовем их несколько «индивидуумов», а затем оценить их значение «пригодности», которое, конечно, подразумевает математическую функцию. Итак, предположим, что вместо использования «особей» 2¹², мы используем, может быть, около 20 или 50 особей, находим тех, которые имеют большее значение «приспособленности», и позволяем им, э-э, «воспроизводиться», и производить потомство, у которого есть некоторые особенности их родителей, а также допускающие случайные мутации - Биология 101! Конечно, степень смешивания и мутации - это то, что вы контролируете, это случайность, но вероятности - это гиперпараметры алгоритма, которые вы можете настроить. Вы также можете решить, сколько поколений вы хотите - очевидно, чем больше у вас поколений, тем больше у вас шансов найти глобальный оптимум, популяцию, гены которой являются «наиболее приспособленными». У вас также есть какие-то критерии ранней остановки, о которых следует подумать, просто чтобы процесс не застрял в локальных минимумах или не затянулся дольше, чем нужно. Вот диаграмма, поясняющая общий процесс:

Скорость кроссовера определяет, как гены передаются потомству, то есть в какие моменты и с какой вероятностью потомство перенимает гены от своих родителей. Другими словами, он определяет степень «смешения» или генетического сходства между родителями и потомством. Очевидно, вы не хотите, чтобы потомство было копией своих родителей - и вы, вероятно, также хотите иметь потомство-мутант, просто чтобы добавить еще немного генетического разнообразия в смесь, с надеждой, что где-то в будущем идеальный мутант приходит неукротимая физическая форма, а вместе с ней и ваша непреодолимая модель машинного обучения. Таким образом, у вас также есть гиперпараметр частота мутаций.

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

Логистическая регрессия + генетический алгоритм

Вот код генетического алгоритма, который выберет для нас подмножество функций:

На что обратить внимание в коде:

  • Выбор ученика: это может занять много времени. Первое, что нужно сделать, чтобы сэкономить время: используйте логистическую регрессию (LR), поскольку она всегда является одной из самых быстрых для обучения. Авторы статьи упоминают, что модели случайного леса хороши, но если вы используете RF для этого процесса GA, вы обнаружите, что он занимает намного больше времени, чем LR. Однако древовидные модели могут учитывать взаимодействие функций и другие вещи, которые могут повлиять на выбор функций. Поэтому вы можете включить RF в процесс выбора функции, чтобы убедиться, что вы ничего не упускаете.
  • Схема перекрестной проверки. Поначалу старайтесь меньше делений, что означает 5-кратное перекрестное вычисление, и не делайте вначале столько повторений. Конечно, в идеале вам нужно 100 или 1000 повторов, но, возможно, сначала вы сделаете 1, 5 или 20 повторов, и это даст вам достаточно четкое представление о том, какие функции важны.
  • Население установлено на 50. Вы можете увеличить его, например 100, 200, 500. Частота мутаций - чем они выше, тем больше у вас шансов получить разнообразие, но это не гарантия того, что вы получите оптимальный выбор. Это зависит от того, сколько поколений потребуется для мутации и кроссоверов, чтобы создать более подходящих кандидатов.
  • Оценка для каждого эксперимента берется из selector.generation_score, который представляет собой список оценок (коэффициент корреляции Мэтьюза) для каждого поколения - как правило, оценка улучшает каждое поколение, поэтому я просто использовал последнюю оценку в качестве окончательной оценки модели (селектор. Generation_score [-1])

Короче - поиграйте с параметрами. Вот таблица, показывающая, что у меня получилось:

«Победитель» этого алгоритма: подмножество признаков с мощностью 5, в котором в качестве признаков используются {возраст, креатинин_фосфокиназа, диабет, фракция выброса, сыворотка_креатинин}. Мы можем ожидать, что оценка MCC составит около 0,40. Теперь давайте проверим это более тщательно, используя pycaret, пакет типов autoML, который упрощает все.

Функции compare_models показывают нам это:

Итак, вы можете видеть, что, как утверждают авторы статьи, лучше всего подходит классификатор случайного леса. Здесь используется 5-кратная схема с 20 повторениями. Давайте посмотрим, что произойдет, когда мы создадим модель случайного леса, но с 5 разделениями и 50 повторениями, то есть 250 обученными моделями:

Вы можете видеть, что стандартное отклонение 0,1305 довольно велико. Это говорит о том, что, хотя RF лучше, чем у большинства, он не всегда может работать лучше на данном наборе поезд / значение.

Вы можете видеть в таблице сравнения учащихся, что XGBoost и LightGBM, похоже, имеют нули по всем направлениям. Я не уверен, почему это так, но я только что провел эксперимент, используя обычный склеарн и ту же схему cross-val. XGBoost набрал 0,359, а LGBM - 0,378 в этом эксперименте, поместив их в середину списка.

БАЗОВАЯ СТРАНИЦА - Без выбора функций

Без какого-либо выбора функций pycaret показывает нам это

Мы видим, что общие баллы MCC ниже, чем при выборе генетических признаков. Это также соответствует тому, что было заявлено в статье.

Когда вы делаете это, но с параметром pycaret «feature_selection», установленным на True (он выполняет свой собственный выбор функций), мы находим это

Это несколько удивительно, учитывая, что не только LDA является лучшей моделью, но и RF и другие GBM работают не так хорошо, как обычно.

Выбрать из модели

Выбор из модели - это один из встроенных методов выбора функций sklearn. Мы используем это как средство сравнения с ГА. Он выбирает следующие характеристики: {«возраст», «креатинин_фосфокиназа», «фракция выброса», «тромбоциты», «сыворотка_креатинин», «сыворотка_ натрий»}. Затем мы берем этот набор функций и снова запускаем его через pycaret, и вот что мы обнаружили:

Так что это подмножество функций тоже неплохое, но немного уступает меньшему подмножеству из генетического алгоритма. Ясно одно: наличие выбора функций имеет тенденцию улучшать оценку. Подробнее см. Мой открытый Блокнот Google Colab.

Таким образом, вы можете видеть, что хотя подмножества функций были упорядочены по производительности в процессе оценки алгоритма GA, это не означает, что они оцениваются в таком порядке, когда cross_val изменяется на 100 повторов. Наивысший балл получил шестой кандидат, который имеет в качестве выбранных характеристик {«возраст», «креатинин_фосфокиназа», «фракция выброса», «сывороточный_креатинин», «курение», время »} и набрал 0,868 .

При этом все они, за исключением последнего, выше 0,86. Фактически, предпоследний имеет оценку 0,863 и имеет только функции {«фракция выброса», «сывороточный_креатинин», «пол» и «время»} . Это означает, что разумно просто использовать это подмножество функций, если вы пытаетесь или вам нужна более экономная модель. Любая из этих моделей работает также, если не лучше, чем базовая модель со всеми функциями, поэтому нет веских причин для сохранения всех функций в модели.

Логистическая регрессия + выбор из модели

Это SelectFromModel в sklearn:

В этом процессе победителем становится {«возраст», «фракция выброса», «сывороточный_креатинин», «время»} с результатом 0,864.

Логистическая регрессия + последовательный выбор плавающих функций (SFSS)

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

Вы можете получить SFSS из экспериментальной сборки sklearn, но я получил его только из mlxtend, что мне проще. Вместо того, чтобы тянуть это, вот ссылка на ячейку в моей записной книжке Colab с моим кодом.