(включая код и данные)

Вступление

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

В этом посте мы хотели бы пройти через такой процесс с помощью Python (2.7). Задача, над которой мы будем работать, уже решена много лет назад классическими методами обработки сигналов с алгоритмом, разработанным Pan and Tompkins.

Хотя есть еще много возможностей для улучшения в отношении анализа сигналов ЭКГ или классификации QRS, мы попытаемся воссоздать только результаты Пана и Томпкинса с реализацией нейронной сети Tensorflow. Полный репозиторий, используемый в этом руководстве, доступен на Github.

Единственная нетривиальная зависимость, которую мы будем использовать, - это пакет wfdb, используемый для чтения данных, хранящихся в формате Physionet. Вы можете установить самую последнюю версию прямо с github:

git clone https://github.com/MIT-LCP/wfdb-python.git
cd wfdb-python
pip install . -U

Если у вас есть это, клонируйте основной репозиторий для этого руководства:

git clone https://github.com/Nospoko/qrs-tutorial.git
cd qrs-tutorial

Чтобы начать любое исследование, нам нужно иметь доступ к данным. База данных MIT Arrhythmia содержит 48 записей 2-канальных сигналов ЭКГ, каждая из которых хранится в 3 файлах, содержащих различные типы информации и идентифицируемых по имени файла без расширения. Более подробную информацию вы можете найти на официальной странице Physionet о нас.

Чтобы загрузить один из этих файлов и выполнить базовую проверку:

Функция get_records () загрузит для вас все необходимые файлы данных. Его можно легко настроить для загрузки и других баз данных Physionet.

Фактические числовые значения сигналов ЭКГ хранятся в массиве атрибутов p_signals, мы можем построить небольшой фрагмент из одного из каналов.

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

Большинство сигналов ЭКГ, доступных в базе данных Physionet, должным образом аннотированы, и информация о положении каждого комплекса QRS может быть извлечена:

Обратите внимание, что есть аннотации, касающиеся информации, отличной от положения QRS, например знак + в начале сигнала выше. Есть страница, объясняющая все типы аннотаций, с которыми вы можете столкнуться при работе с сигналами из базы данных Physionet.

Определение цели

Мы столкнулись с проблемой обнаружения событий в высокочастотном (более 1 Гц) сигнале. Для простоты мы начнем создавать решение на основе механизма движущегося окна. Это означает, что мы хотели бы построить конвейер машинного обучения, который принимает на вход фрагменты ЭКГ постоянной ширины и возвращает информацию о наличии каких-либо событий QRS. Итак, желаемое преобразование может выглядеть так:

Здесь ширина окна была выбрана равной 2,5 секунды, что соответствует 900 точкам выборки. Это значение будет одним из определяющих параметров модели, и мы постараемся подготовиться к тестированию различных значений.

Еще один важный фактор, который мы хотели бы контролировать, - это характер выходного сигнала, генерируемого нашей моделью. В конце нам нужно получить точные позиции образцов локализованного комплекса QRS (второй график), но из-за отсутствия единообразия в аннотациях Physionet (одинаковые доли могут быть отмечены в разных точках разными аннотаторами), может быть хорошей идеей спрогнозировать форму колоколообразной кривой (третий график), интерпретируемую как плотность вероятности и определяемую вручную на более позднем этапе обработки сигнала.

Генерация набора данных

База данных по аритмии MIT содержит 48 записей, каждая из которых содержит 2 сигнала по 650000 образцов. Всего более 60 миллионов образцов или 120 тысяч фрагментов шириной 500 образцов. Это число может быть легко увеличено за счет увеличения сигнала, генерации искусственных сигналов, включения других баз данных, уменьшения ширины и шага окна фрагментации и т. Д.

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

Из 48 доступных файлов данных мы будем использовать 30 для обучения, 9 для проверки и 9 для окончательного тестирования. Каждый из них будет сгенерирован в виде массива Numpy, а затем будет использоваться для извлечения пакетов данных. Если объем данных, с которыми вы будете работать, не превышает возможности памяти вашего компьютера, абстрактная функция, создающая и сохраняющая правильный набор массивов, должна быть довольно простой.

Вся предварительная обработка данных, манипуляции и нарезка должны выполняться внутри функции convert_data (), в частности, здесь должна контролироваться ширина окна.

Разделение данных сводится к выбору записей ЭКГ для каждого набора данных.

Доступ к набору данных

Чтобы обучить любую нейронную сеть с использованием этих данных, нам необходимо предоставить механизм для извлечения рандомизированных пакетов любой заданной формы. Вы, возможно, встречали реализацию Tensorflow для набора данных MNIST. Мы собираемся использовать аналогичный подход, сосредоточив внимание на функции next_batch ().

Следите за обновлениями части 2.