Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Последние примерно 2 месяца я ношу кольцо Oura, чтобы получать информацию о моём сне и о том, сколько я прошла шагов за день. Приложение считывает сон, разбитый на фазы (лёгкий, глубокий, быстрый), и даёт вам другие показатели, такие как частота сердечных сокращений, температура тела и частота дыхания. И для такого ботаника, как я, радостно было обнаружить, что у Oura есть API экспорта данных, чтобы я смогла лучше проанализировать их. Я загрузила данные в BigQuery и воспользовалась функцией CORR() (она потрясающая!), чтобы увидеть, какие показатели коррелируют с улучшением качества сна, а также визуализировала некоторые данные в Data Studio. Если у вас мало времени, переходите к разделу «Заключение», чтобы прочитать о том, что я узнала.
Дисклеймер: я не врач. Как раз наоборот: я ипохондрик, которому нравится писать на Python и SQL.
Получение данных из Oura в BigQuery
Я написала скрипт на Python, чтобы получить все мои текущие данные из Oura и записать их в файл JSON с разделителями новой строки (один из форматов файлов, который принимает BigQuery). Затем скрипт загружает файл в таблицу BigQuery. Я хочу написать скрипт, который запускается каждый день и добавляет самые свежие данные в мой набор данных BigQuery, но пока достаточно единоразового экспорта. Если вы пользуетесь Oura, для запуска скрипта потребуется получить токен доступа из консоли разработчика Oura. Вот мой код, который получает данные и записывает их в локальный файл:
import requests
import json
summaries = ['sleep', 'activity', 'readiness']
for data_type in summaries:
url = 'https://api.ouraring.com/v1/' + data_type + '?start=2019-03-21'
access_token = 'your_oura_access_token'
result = requests.get(url,
headers={'Content-Type':'application/json',
'Authorization': 'Bearer {}'.format(access_token)})
json_data = json.loads(result.content)
with open(data_type + '.json', 'w') as jsonfile:
for j in json_data[i]:
json.dump(j, jsonfile)
jsonfile.write('\n')
После выполнения этого скрипта у нас будет 3 файла JSON для каждого типа данных, которые предоставляет Oura: сон, активность и то, что они называют «готовностью» [к чему-либо; но это не бодрость; бодрость – cheerfulness], то есть того, что Oura вычисляет на основе качества вашего сна и уровня активности. Затем нужно импортировать библиотеку BigQuery и указать ссылку на набор данных:
from google.cloud import bigquery
client = bigquery.Client()
dataset_ref = client.dataset('your_dataset_name')
Теперь мы можем записать каждый файл в новую таблицу BigQuery следующим образом:
with open(filename, 'rb') as sourcefile:
table_ref = dataset_ref.table(data_type)
job_config = bigquery.LoadJobConfig()
job_config.source_format = bigquery.SourceFormat.NEWLINE_DELIMITED_JSON
job_config.autodetect = True
job = client.load_table_from_file(
sourcefile,
table_ref,
location="US",
job_config=job_config
)
job.result()
print('Job complete', job.output_rows)
Моя таблица сна теперь в BQ. Вот скриншот данных:
Поиск корреляций
А теперь самое интересное! Я хотела выяснить, какие факторы коррелировали с общим временем сна и с его качеством (количеством быстрых и глубоких фаз сна). Функция BigQuery CORR() идеально подходит, чтобы это сделать. Она использует коэффициент корреляции Пирсона: вы передаёте функции два параметра, и она возвращает число от -1 до 1, сигнализирующее о силе корреляции. 0 – корреляции между двумя значениями нет, -1 означает обратную корреляцию: когда первое значение растёт, второе падает), а 1 указывает на идеальную положительную корреляцию.
Вы никогда не увидите значений -1 или 1 в реальных данных, поэтому всё, что превышает |0,5|, сигнализирует о средней и сильной корреляции, а всё, что находится в пределах от |0,3| до |0.5|, сообщает о небольшой корреляции.
Обратите внимание, что многие из этих корреляций специфичны для меня. Моя подруга (моя ровесница) поделилась со мной своими данными Oura, и многие из её сильных корреляций отличались от моих. Каждый уникален!
Во-первых, какие показатели имели наиболее положительную или отрицательную корреляцию в моих данных? Давайте посмотрим, как частота пульса в состоянии покоя влияет на процент быстрого сна:
SELECT
CORR(hr_average, rem / total)
FROM
`gcp-project.bq-dataset.sleep`
Этот код вернёт значение корреляции -0,45, оно означает отрицательную среднюю корреляцию. Это имеет смысл – по мере того, как у меня увеличивается частота пульса, процент быстрых фаз сна, через которые я прохожу, снижается. Но что влияет на частоту пульса в состоянии покоя? Давайте посмотрим на температуру тела. Oura предоставляет данные об отклонении температуры тела, то есть о том, насколько ваша текущая температура отличается от средней температуры:
SELECT
CORR(hr_average, temperature_trend_deviation)
FROM
`gcp-project.bq-dataset.sleep`
Корреляция здесь 0,67 – очень сильная. Чем выше температура моего тела, тем выше частота пульса. Но как насчёт того, что я могу контролировать напрямую, например времени, когда я ложусь спать?
SELECT
CORR(hr_average, EXTRACT(hour from bedtime_start))
FROM
`gcp-project.bq-dataset.sleep`
Это соотношение составляет 0,59. Значит, как правило, чем раньше я ложусь спать, тем ниже частота пульса в состоянии покоя в течение ночи и тем больше у меня фаза быстрого сна! Быстрый сон восстанавливает ваш мозг и улучшает память, а глубокий сон помогает восстановить ваше тело. К сожалению, я не смогла найти сильной корреляции между этими факторами и процентом глубокого сна, который у меня зафиксирован. Это всё ещёе загадка для меня, хотя я читала, что полезно сократить время перед экранами до сна (по иронии судьбы я читала это на своём телефоне перед сном).
А что насчёт тренировок?
Я немного фанатик тренировок (на самом деле больше, чем немного), и, поскольку я тренируюсь почти каждый день, у меня недостаточно данных, чтобы сравнить влияние ежедневных тренировок и их отсутствия на сон. Но я обнаружила небольшую корреляцию между объёмом активности и процентом глубокого сна, который у меня был недавно. Для этого потребовался более сложный запрос
JOIN
для таблиц активности и сна. И мне нужно было выполнить DATE_SUB()
в операторе ON
из-за того, что Oura так возвращает данные:SELECT corr(deep / total, high + medium + low) FROM (
SELECT high, medium, low, a.summary_date
FROM `gcp-project.oura.activity` activity
JOIN (
SELECT deep, total, summary_date FROM `gcp-project.oura.sleep`
) sleep
ON activity.summary_date = date_sub(sleep.summary_date, interval 1 day)
)
И я получила 0,32. Значение указывает на то, что дни, когда я активнее, слегка коррелируют с ночами, когда сон глубже.
О программном обеспечении и предубеждениях
Помимо множества интересных показателей, Oura также даёт различные оценки, которые вычисляет на основе своих данных с помощью собственных алгоритмов. Каждый день вы получаете 100 баллов за свой сон, активность и готовность. Температура тела – это один из показателей, которые используются, чтобы рассчитать показатели сна и готовности. Через пару недель использования приложения я заметила довольно сильную обратную корреляцию между температурой тела и этими показателями. Проблема здесь в том, что у большинства женщин температура тела немного повышается раз в месяц, и это нормальное явление для женщины. Сообщения в приложении довольно ясно показывают, что повышенная температура тела является симптомом того, что что-то не так:
Господи, я проспала 9 часов!
Очевидно, что температура тела повышается, когда вы больны, и, может быть, довольно трудно отличить эти процессы друг от друга, но сообщения здесь – тонкий пример того, как гендерные предубеждения закрадываются в программное обеспечение. Предполагается, что мужчины – значение по умолчанию, а поведение женщин – отклонение от этого значения. Я очень надеюсь, что команда Oura исправит эту оплошность, изменив алгоритм с учётом пола и возраста либо просто изменив сообщения, чтобы прояснить, что повышенная температура тела – это не всегда плохо.
Тем не менее я нахожу представленные приложением необработанные данные полезными и, честно говоря, увлекательными, поэтому буду продолжать носить это кольцо!
Визуализация данных о сне в Data Studio
Вернёмся к интересной части: визуализируем некоторые данные, чтобы лучше понять корреляции, которые я обнаружила. BigQuery отлично интегрируется с Data Studio, которой я могу воспользоваться, чтобы создать интересные графики временных рядов с наложением различных показателей. Когда я создаю новый отчёт в Data Studio, мне нужно выбрать BigQuery в качестве источника данных, а затем выбрать Custom Query:
Когда я введу свой запрос, я смогу использовать любой из столбцов этого запроса в своих диаграммах. Поскольку я не собираюсь отображать значения CORR, запрос нужно немного изменить:
SELECT
start_hr_utc, temperature_deviation, rem / total as rem_pct, deep / total as deep_pct, light / total as light_pct, low + medium + high as total_activity, steps, inactive, hr_lowest, hr_average, activity.summary_date
FROM `gcp-project.oura.activity` activity
JOIN (
SELECT bedtime_start, extract (hour from bedtime_start) as start_hr_utc, temperature_deviation, rem, deep, light, summary_date, hr_lowest, hr_average FROM `gcp-project.oura.sleep`
) sleep
ON activity.summary_date = date_sub(sleep.summary_date, interval 1 day)
А вот моя диаграмма зависимости времени, когда начался отход ко сну, от процента быстрого сна:
За некоторыми исключениями, мой процент быстрого сна обычно увеличивается, когда я ложусь спать раньше. Как видно из следующего графика, частота пульса и фаза быстрого сна также имеют относительно сильную обратную связь:
Другой показатель, возвращаемый из API Oura, – bedtime_sleep_delta. Это разница в секундах между временем отхода ко сну нынешней и предыдущей ночью. Я вижу, что резкая смена времени отхода ко сну от ночи к ночи немного уменьшила мой процент глубокого сна:
Я надеюсь, что, продолжая собирать данные, я смогу выявить больше корреляций.
Заключение
Что я узнала, кроме навязчивого анализа данных о моём здоровье? Резюмирую:
- Повышенная температура тела обычно коррелирует с учащённым пульсом в состоянии покоя и частотой дыхания.
- Ранний отход ко сну почти всегда улучшает фазу быстрого сна.
- Ложиться спать в определённое время тоже хорошо.
- Тренировки хорошо влияют на фазу глубокого сна.
- Помните о предвзятости при создании технологий для разнообразной аудитории.
- Конечно, люди – не роботы, и я не могу ложиться спать в 9 вечера каждую ночь, но всё же считаю данные очень полезными.
Эти данные сложно использовать для машинного обучения, поскольку, даже если я соберу годовой отчет, в наборе данных будет только 365 строк. Однако я думаю, что у машинного обучения есть много возможностей для работы с данными о состоянии здоровья в целом. Хотите научиться использовать машинное обучение — приходите учиться, а промокод HABR, дающий 10 % дополнительно к скидке на баннере, вам в этом поможет.
- Курс по Machine Learning
- Курс «Математика и Machine Learning для Data Science»
- Профессия Data Scientist
- Профессия Data Analyst
Другие профессии и курсы
ПРОФЕССИИ
КУРСЫ
- Профессия Java-разработчик
- Профессия QA-инженер на JAVA
- Профессия Frontend-разработчик
- Профессия Этичный хакер
- Профессия C++ разработчик
- Профессия Разработчик игр на Unity
- Профессия Веб-разработчик
- Профессия iOS-разработчик с нуля
- Профессия Android-разработчик с нуля
КУРСЫ
- Курс по Data Engineering
- Курс «Python для веб-разработки»
- Курс «Алгоритмы и структуры данных»
- Курс по аналитике данных
- Курс по DevOps