Отслеживание активности с помощью телефона и MATLAB
Этот пост расскажет о том, как использовать Android-устройство в паре с алгоритмами машинного обучения MATLAB и Statistics and Machine Learning Toolbox для отслеживания физической активности в режиме реального времени.
Установка и настройка
Нам понадобится:
- компьютер с MATLAB R2014b или старше, установленным пакетом поддержки Android Sensors, и Statistics and Machine Learning Toolbox;
- Android-смартфон с приложением MATLAB Mobile;
- Интернет-соединение на смартфоне.
Связь смартфона и MATLABа делается с помощью MATLAB Connector, плагин можно скачать по ссылке.
Больше информации о сборе данных с датчиков смартфонов тут.
Вступление
Наблюдая за кем-то, нам легко определить, чем занят человек, даже если мы видим его впервые. Мы по умолчанию умеем распознавать человеческую деятельность. Мозг сравнивает наблюдаемые действия с тысячами увиденных ранее и выдает нужное совпадение. Аналогично компьютер (телефон) распознает те действия, которым его обучили.
Используя алгоритмы машинного обучения, можно научить компьютер распознавать специфическую деятельность человека, и совершенствовать это умение по мере поступления новых данных. Такое распознавание, включающее в себя разбиение данных по обособленным «классам», называется классификацией. Еще один пример классификации — постановка больному диагноза на основе наличия определенных симптомов.
Алгоритм классификации для таких задач применяется в два этапа: обучение и обнаружение. На этапе обучения строится модель, которая сортирует обучающие данные по определенным категориям. На этапе обнаружения новые данные привязываются к уже существующим категориям.
В разработанном приложении использовался датчик ускорения (акселерометр) телефона, при помощи которого определялся вид деятельности. Был выбран классификатор на основе K-ближайшего соседа (KNN). Это удобный алгоритм для такого приложения, поскольку он быстро обнаруживает движение и очень точен в работе с данными низкой размерности (малым набором свойств). Основываясь на большинстве значений своих K-ближайших соседей в наборе обучающих данных, он обнаруживает категорию, к которой принадлежит точка в новых данных.
Процесс распознавания движений происходил в три этапа:
- сбор данных: с акселерометра Android-устройства собирались значения ускорений в трех плоскостях;
- извлечение свойств: для каждого отслеживаемого вида деятельности из показаний акселерометра извлекались и идентифицировались отличительные свойства;
- классификация деятельности: чтобы обучить классификатор, использовались свойства, извлеченные для различных видов деятельности. Затем классификатор использовался на новых показаниях акселерометра, чтобы определить, какой вид движений происходил.
Сбор данных
Так как обнаружение проводилось классификатором, для дальнейшей работы ему надо было обучиться на наборе заранее известных точек данных. MATLAB Mobile в сочетании с пакетом поддержки MATLAB для датчиков Android (MATLAB Support Package for Android Sensors) позволяет собирать данные акселерометра устройства и отправлять измерения в сессию MATLAB на PC.
После установки связи с Android, был создал экземпляр объекта «mobiledev» для записи данных с датчиков устройства. Затем акселерометр на устройстве был включен, и MATLAB начал сбор данных.
mobileSensor = mobiledev() % create mobiledev object
mobileSensor.AccelerationSensorEnabled = 1; % enable accelerometer
mobileSensor.start; % start sending data
После выполнения последней команды я не двигался 10 секунд. Затем встал и ходил следующие 70 секунд. Затем подошел к лестнице, спустился вниз и пробежался примерно 60 секунд. После еще 70 секунд прошелся, затем поднялся по лестнице и вернулся в офис. В завершение я сел и не двигался. От акселерометра я получил трёхмерные записанные данные и визуализировал их.
[accel, time] = accellog(mobileSensor); % acquire data from logs
plot(time, accel); % plot data
График ниже содержит данные по всем действиям: неподвижность, ходьба, бег, подъем и спуск с лестницы. Как видно, их невозможно обнаружить, просто глядя на график. Поэтому потребовалось выделить и идентифицировать те свойства, которые помогут распознать каждое действие и отличить его от других.
Извлечение свойств
Хотя во временной области «сырые» показания акселерометра выглядят одинаково для каждого вида деятельности, на самом деле они содержат уникальные характеристики, которые можно использовать для того, чтобы опознавать различные виды движений. Это может быть, например, максимальное значение всех точек данных или количество точек данных вне какого-либо диапазона. Такие характеристики называются свойствами.
Благодаря этим свойствам можно провести классификацию. Можно рассмотреть множество свойств:
- среднее значение,
- медиана,
- дисперсия,
- максимум,
- минимум,
- величина частотной составляющей и так далее.
Однако чтобы эффективно их извлечь, надо найти такой минимальный набор свойств, который позволит различать разную деятельность и при этом не будет слишком ресурсозатратным.
Из всех возможных свойств следующие шесть оказались наиболее подходящими. Они обозначены «Feature_N»:
- Feature_1: Средняя величина данных.
- Feature_2: Квадрат суммы величины данных ниже 25 процентиля.
- Feature_3: Квадрат суммы величины данных ниже 25 процентиля.
- Feature_4: Пик частоты в спектре данных по оси Y ниже 5 Гц.
- Feature_5: Количество пиков в спектре данных по оси Y ниже 5 Гц.
- Feature_6: Интеграл спектра данных по оси Y от 0 до 5 Гц.
Величина данных — это квадратный корень из суммы квадратов показаний ускорения по оси Y и оси Z. Показания по оси Х можно проигнорировать, потому что они не сильно отличаются для разных видов деятельности — это связано с положением телефона в кармане. Из 5-секундных отрезков записи каждого вида деятельности были извлечены соответствующие шесть свойств. Окно измерений в 5 секунд выбрано из-за длины, достаточной, чтобы зафиксировать последовательные и стабильные свойства. Длину окна можно варьировать, помня о том, что в слишком длинных окнах (около минуты и больше) велика вероятность погрешности из-за возможной смены деятельности.
Рассчитав в рамках процедуры обучения указанные выше свойства для каждого типа деятельности, алгоритму задали два входа: свойства и соответствующий ответ (т.е. активность, которой принадлежат эти свойства). Переменная функция рассчитана на основе «сырых» трёхмерных измерений акселерометра во время бега и определяет размер упомянутых выше свойств. Например:
feature = [30, 15, 7.6, 2.3, 5, 8];
activity = 'running';
Здесь переменная функция выглядит, как: [Feature_1, Feature_2, Feature_3, Feature_4, Feature_5, Feature_6]. Каждая пара «свойство-деятельность» представляет 1 точку обучающих данных. Узнать больше о том, как получить эти точки обучающих данных можно через скрипт MATLAB recordTrainingData в прилагаемом архиве. Исходные показания акселерометра для каждого вида деятельности хранятся в MAT-файле. Чтобы избежать сбора данных во время смены деятельности, добавлены запросы на ввод между каждым видом активности. Это гарантирует, что исходные данные для выделения свойств каждого вида деятельности чисты и последовательны.
Чтобы извлечь свойства из исходных данных, сохраненных в каждом MAT-файле, используйте extractTrainingFeature из скачанного архива. Обратите внимание, что исходные данные акселерометра дискретизуются с частотой около 200 Гц, но частота может быть значительно меньше из-за особенностей работы Android. Кроме того, частота дискретизации может меняться во время измерения, тем самым делая данные неравномерно дискретными.
Чтобы привести данные к однородной частоте дискретизации, разработан алгоритм «ресемплинга». Алгоритм помог улучшить идентификацию свойств и дальнейшую классификацию.
В графике, расположенном ниже, красная линия со знаком 'х' обозначает неравномерно дискретные исходные данные Y-оси акселерометра, а синяя линия со знаком 'о' обозначает обработанные данные. Отметим, что первые три свойства из списка выше находятся во временной области, в то время как остальные — в частотной.
Из следующих графиков видно, что свойства различных видов деятельности группируются вместе (например, все красные точки на графике соответствуют свойствам, связанным с бегом). Такой характер свойств (различные кластеры для различных видов деятельности) позволяет точно определить выполняемый вид деятельности для новых показаний акселерометра:
Классификация деятельности
Обычно алгоритм обучения требует много точек обучающих данных для построения надежной модели распознавания. Так, чтобы обучить классификатор, собрали более тысячи точек данных каждого вида деятельности. Для начала, свойства сгруппировали в массив в следующем порядке — ходьба, бег, положение покоя, подъем наверх и спуск вниз:
data = [featureWalk; featureRun; featureIdle; featureUp; featureDown];
В строке кода выше, featureWalk — это массив из шести свойств с размерностью 1000×6. Свойства рассчитаны на исходных данных акселерометра, собранных при ходьбе. Аналогично, featureRun — это массив размерностью 1000×6 из шести свойств, рассчитанных на необработанных данных акселерометра, собранных во время бега, и так далее.
Когда свойства для всех видов деятельности были собраны в единый массив данных, оказалось, что свойства бега масштабнее свойств ходьбы или неподвижности. Из-за этого свойства различных типов деятельности смещаются и влияют на способность алгоритма точно определять вид деятельности по новым данным (которые могут масштабироваться по-разному). Поэтому надо нормализовать данные, чтобы ограничить диапазон их значений от 0 до 1:
График выше иллюстрирует исходные значения Feature_1, рассчитанные по всем видам деятельности, а также нормализованные значения. Как видно, после нормализации значения Feature_1 лежат между [0, 1]. Аналогично нормализовали данные остальных пяти свойств.
После нормализации и подготовки данных к использованию, надо определить, как алгоритм машинного обучения реагирует на входной массив данных. Входные данные и отклик на них затем обучат алгоритм классифицировать новые данные.
Чтобы построить вектор выходного отклика, cначала назначаются целые числа для каждого вида деятельности: -1, 0, 1, 2, 3 — спуск вниз, состояние покоя, подъем по лестнице, ходьба и бег соответственно. Так как нужен отклик для каждого набора входных свойств, создано вектор-столбец (содержащий эти целые числа) той же длины, что и вектор отклика. Чтобы обнаруженная деятельность легко считывалась, вектор отклика преобразовывается в массив категорий со значениями «Going Downstairs», «Idling», «Climbing Upstairs», «Walking», «Running» и «Transition»:
Down = -1 * ones(length(featureDown), 1);
Idle = zeros(length(featureIdle), 1);
Up = ones(length(featureUp), 1);
Walk = 2 * ones(length(featureWalk), 1);
Run = 3 * ones(length(featureRun), 1);
responseVector = [Walk; Run; Idle; Up; Down]; % building the output response vector
valueset = [-1:3, -10];
cateName = {'Going downstairs', 'Idling', 'Climbing upstairs', 'Walking', ...
'Running', 'Transition'};
response = categorical(responseVector, valueset, ...
cateName); % converting to a categorical array
Сгенерировав массив откликов выше, алгоритм K-NN обучили создавать модели. Для этого использовалась функция FITCKNN из Statistics and Machine Learning Toolbox; после нескольких попыток для приложения было выбрано значение свойства 'NumNeighbors' K равное 30, так оно обеспечило нужную производительность и точность обнаружения. Получив модель с помощью обучающих данных, ее надо подтвердить на новых данных, поступающих со смартфона.
mdl = fitcknn(data, response);
mdl.NumNeighbors = 30;
Для этого была создана функция extractFeatures для расчета шести свойств, необходимых для классификации. Рассчитанные свойства (сохраненные в новой переменной Feature) затем используются вместе с моделью для распознавания деятельности: модель обучена различать 5 ее видов. Возникает естественный вопрос: что делать, если обнаруженная деятельность отличается от них?
newFeature = [0.15, 0.28, 0.2, 0.35, 0.65, 0.7]; % features for the new activity
result = predict(mdl,newFeature); % predicting the activity
Детектор продолжит классифицировать деятельность в текущем окне обнаружения и назначать малые вероятности для каждой из 5 категорий. Такие же малые вероятности могут возникнуть при переходе из одного вида деятельности в другой в рамках одного окна обнаружения — это затруднит классификацию. Чтобы избежать такого некорректного обнаружения, предиктор реализован так, чтобы выдавать «Transition» в при вероятности предсказания меньше 95%.
То же правило применяется при переходе от одной классифицируемой деятельности к другой, например, от ходьбы («Walking») к бегу («Running»). Это разумно, ведь на последовательных окнах обнаружения значения свойств при таком переходе могут быть неустойчивыми.
Ниже график исходных данных, собранных с телефона в течение минуты, и распознанных действий. Для удобства линия распознанной деятельности находится снизу и промаркирована как:
x — ходьба (Walking), * — бег (Running), o — состояния покоя (Idling), ˄ — подъем по лестнице (Walking Upstairs), ˅ — спуск по лестнице (Walking Downstairs), • — переход (Transition):
Обратите внимание, что для обучения алгоритм машинного обучения использует исходные данные акселерометра для различных выполненных действий. Если использовать алгоритм обучения с готовыми данными из архива (см. ссылку в конце статьи), то алгоритм обнаружения для данных, собранных с вашего телефона, скорее всего, будет не точным. Даже если вы положите телефон, как и автор, в правый передний карман брюк, все равно алгоритм останется не точным. Так получается из-за разницы в походках, зависимости измерений от роста и веса конкретного человека.
Чтобы создать детектор активности, который точно определит ваши действия, надо начать со сбора нескольких наборов данных акселерометра телефона для тех видов деятельности, которые хотите распознавать. Затем для каждого набора данных извлечь 6 свойств, перечисленных выше, с помощью тренинга extractTrainingFeatures. После использовать извлеченные свойства для тренировки алгоритма машинного обучения. Теперь можно использовать полученный алгоритм для распознавания ваших новых действий.
В посте рассмотрена только одна из многих возможностей применения полученного приложения. Такое приложение можно применить к любой другой системе распознавания, например, для мобильного робота. Можно дополнить приложение данными от датчиков GPS, гироскопов, магнетометров, для получения более функционального трекера.
» Код примера