<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Wearables on kenji.blog</title><link>http://kenji.blog/ru/tags/wearables/</link><description>Recent content in Wearables on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>ru</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 12 Sep 2026 12:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/ru/tags/wearables/index.xml" rel="self" type="application/rss+xml"/><item><title>Будни инженера, управляющего своим здоровьем с помощью смарт-колец (Лайфхаки для здоровья)</title><link>http://kenji.blog/ru/p/engineer-health-hacks-wearables/</link><pubDate>Sat, 12 Sep 2026 12:00:00 +0900</pubDate><guid>http://kenji.blog/ru/p/engineer-health-hacks-wearables/</guid><description>&lt;img src="http://kenji.blog/p/engineer-health-hacks-wearables/img/eyecatch.jpg" alt="Featured image of post Будни инженера, управляющего своим здоровьем с помощью смарт-колец (Лайфхаки для здоровья)" />&lt;h2 id="1-введение-на-стыке-программной-инженерии-и-биохакинга">1. Введение: На стыке программной инженерии и биохакинга
&lt;/h2>&lt;p>Современная программная инженерия — это изнурительный интеллектуальный труд, связанный с экстремальными когнитивными нагрузками и длительным сидячим образом жизни (Sedentary Lifestyle). Постоянное изучение меняющихся технологических стеков, поиск багов в сложных распределенных системах и давление дедлайнов. Чтобы преодолеть всё это, недостаточно просто полагаться на &amp;ldquo;силу воли&amp;rdquo; или &amp;ldquo;упорство&amp;rdquo;. Необходим подход, при котором вы настраиваете свое тело как аппаратное обеспечение, подобно отладке системы — то есть &amp;ldquo;биохакинг&amp;rdquo; (Biohacking).&lt;/p>
&lt;p>В прошлом мы полагались на субъективные ощущения (эвристику) вроде &amp;ldquo;сегодня я чувствую себя хорошо или плохо&amp;rdquo;, но сегодня, благодаря распространению высокопроизводительных носимых устройств, таких как Oura Ring, Apple Watch и Garmin, мы можем неинвазивно получать биометрические данные 24 часа в сутки, 365 дней в году. В этой статье объясняется, как получать биометрические данные (ВСР, ЧСС покоя, архитектура сна) и данные о производительности (метрики кодирования с помощью WakaTime и т.д.) через API, и проводить корреляционный анализ с использованием подходов науки о данных с помощью Python и Pandas. Мы также очень подробно разберем научно обоснованные лайфхаки для здоровья инженеров, такие как математические модели циркадных ритмов и оптимальное время приема кофе на основе периода полувыведения кофеина.&lt;/p>
&lt;h2 id="2-то-что-нельзя-измерить-нельзя-контролировать-оборудование-для-получения-биометрических-данных">2. То, что нельзя измерить, нельзя контролировать: Оборудование для получения биометрических данных
&lt;/h2>&lt;p>Каждый сенсор (носимое устройство) для получения биометрических данных имеет свои сильные стороны. Первым шагом в управлении здоровьем на основе данных является выбор оптимального устройства в соответствии с вашими целями.&lt;/p>
&lt;h3 id="21-oura-ring-generation-3--4">2.1 Oura Ring (Generation 3 / 4)
&lt;/h3>&lt;p>Поскольку данные собираются непосредственно с артерий пальца, оно отличается очень высокой точностью измерения частоты сердечных сокращений во время сна, вариабельности сердечного ритма (ВСР) и изменения температуры поверхности тела по сравнению с умными часами на запястье. На пальцах густая сеть капилляров, что позволяет оптическому датчику пульса (PPG: фотоплетизмография) получать данные с низким уровнем шума. Кроме того, устройство обладает богатым REST API, позволяющим легко экспортировать необработанные данные в формате JSON через OAuth2.0, что делает его самым удобным для &amp;ldquo;хакинга&amp;rdquo; устройством для инженеров.&lt;/p>
&lt;h3 id="22-apple-watch-series--ultra">2.2 Apple Watch Series / Ultra
&lt;/h3>&lt;p>Отлично подходит для отслеживания активности, измерения насыщения крови кислородом (SpO2) и электрокардиограммы (ЭКГ). Это лучшее устройство для отслеживания уровня активности в течение дня и измерения ВСР по требованию через приложения для осознанности (приложение &amp;ldquo;Дыхание&amp;rdquo;). Однако экспорт данных требует использования HealthKit, и для прямого доступа из Python и т.д. потребуется промежуточный шаг, например, экспорт в CSV через приложения iOS (такие как AutoSleep или HealthFit).&lt;/p>
&lt;h3 id="23-garmin-fenix--forerunner">2.3 Garmin (Fenix / Forerunner)
&lt;/h3>&lt;p>Помимо точности GPS-трекинга, уникальный показатель остатка энергии под названием &amp;ldquo;Body Battery&amp;rdquo; является превосходным. Он рассчитывается на основе ВСР и уровня стресса. Данные Garmin можно получить через API Garmin Connect, но поскольку существует барьер в виде корпоративного API, индивидуальным разработчикам необходимо использовать библиотеки с открытым исходным кодом или инструменты для парсинга, созданные энтузиастами.&lt;/p>
&lt;p>В этой статье основное внимание будет уделено данным с &lt;strong>Oura Ring&lt;/strong>, которое является вершиной в отслеживании сна и восстановления, и из которого чрезвычайно легко извлекать данные через API, а также данным с &lt;strong>WakaTime&lt;/strong>, который измеряет время кодирования в качестве плагина для IDE (таких как VS Code и IntelliJ).&lt;/p>
&lt;h2 id="3-базовая-теория-биометрических-данных-наука-о-данных-вср-и-чсс-покоя">3. Базовая теория биометрических данных: Наука о данных ВСР и ЧСС покоя
&lt;/h2>&lt;p>С точки зрения науки о данных &amp;ldquo;восстановление&amp;rdquo; (Recovery) определяется не просто таким показателем, как &amp;ldquo;долго спал — значит хорошо&amp;rdquo;, а двумя следующими главными метриками.&lt;/p>
&lt;h3 id="31-вср-вариабельность-сердечного-ритма-heart-rate-variability-и-моделирование-вегетативной-нервной-системы">3.1 ВСР (Вариабельность сердечного ритма: Heart Rate Variability) и моделирование вегетативной нервной системы
&lt;/h3>&lt;p>Сердце не бьется в постоянном ритме, как метроном. Например, даже если частота сердечных сокращений составляет 60 ударов в минуту, интервал между каждым ударом (интервал R-R) всегда колеблется, например, &amp;ldquo;0,92 секунды&amp;rdquo;, &amp;ldquo;1,05 секунды&amp;rdquo;, &amp;ldquo;0,98 секунды&amp;rdquo;. Количественное выражение величины этого колебания — это ВСР (вариабельность сердечного ритма).&lt;/p>
&lt;p>ВСР напрямую отражает баланс вегетативной нервной системы, то есть &amp;ldquo;симпатической нервной системы (газ)&amp;rdquo; и &amp;ldquo;парасимпатической нервной системы (тормоз)&amp;rdquo;. В состоянии стресса, переутомления или после употребления алкоголя симпатическая нервная система доминирует, биение сердца становится более равномерным, а ВСР снижается. Наоборот, в состоянии полного расслабления и восстановления доминирует парасимпатическая (блуждающий нерв) нервная система, пульс динамически колеблется в такт дыханию, и ВСР повышается.&lt;/p>
&lt;p>Существуют два подхода к расчету ВСР: во временной области (Time-domain) и в частотной области (Frequency-domain). Наиболее часто используемым в анализе во временной области и применяемым в Oura Ring и Apple Watch является &lt;strong>RMSSD (Root Mean Square of Successive Differences)&lt;/strong>. Это среднеквадратичное значение разности между последовательными межкардиоинтервалами (RR-интервалами).&lt;/p>
&lt;p>Строго математически это выражается следующим образом:&lt;/p>
$$ RMSSD = \sqrt{\frac{1}{N-1} \sum_{i=1}^{N-1} (RR_{i+1} - RR_i)^2} $$&lt;p>Где,&lt;/p>
&lt;ul>
&lt;li>$N$ — общее количество измеренных сердечных сокращений&lt;/li>
&lt;li>$RR_i$ — $i$-й RR-интервал (в миллисекундах)&lt;/li>
&lt;/ul>
&lt;p>Для инженера, если ВСР (RMSSD) при пробуждении утром значительно ниже индивидуального базового уровня (скользящее среднее за последние несколько недель), это позволяет принять решение на основе данных: &amp;ldquo;Сегодня следует избегать проектирования архитектуры с высокой когнитивной нагрузкой или деплоя в продакшен, а вместо этого посвятить день расширению тестового покрытия или написанию документации&amp;rdquo;.&lt;/p>
&lt;h3 id="32-частота-сердечных-сокращений-в-покое-чсс-покоя---rhr-resting-heart-rate-и-сигналы-восстановления">3.2 Частота сердечных сокращений в покое (ЧСС покоя - RHR: Resting Heart Rate) и сигналы восстановления
&lt;/h3>&lt;p>RHR (ЧСС покоя) — это количество ударов сердца в минуту, когда тело полностью расслаблено (обычно во время сна). После употребления алкоголя, переедания в позднее время или в качестве раннего симптома болезни (например, инфекции), когда организм тратит энергию на внутренний метаболизм или иммунную реакцию, RHR поднимается на несколько или даже более десяти ударов в минуту выше базового уровня.&lt;/p>
&lt;p>Чем ниже RHR, тем больше крови сердечная мышца может перекачать за один удар (высокий ударный объем), что указывает на высокую аэробную способность и степень восстановления после усталости. В идеале кривая RHR должна иметь форму &amp;ldquo;гамака&amp;rdquo;, достигая наименьшего значения в первой половине сна, что свидетельствует о наиболее качественном восстановлении.&lt;/p>
&lt;h2 id="4-детальный-анализ-архитектуры-сна">4. Детальный анализ архитектуры сна
&lt;/h2>&lt;p>Производительность мозга инженера определяется не только &amp;ldquo;количеством&amp;rdquo; сна, но и его &amp;ldquo;качеством&amp;rdquo;, то есть архитектурой сна (Sleep Architecture). Ночной сон обычно состоит из 4-5 циклов по 90-110 минут.&lt;/p>
&lt;h3 id="41-nrem-сон-стадии-1-2-легкий-сон--light-sleep">4.1 NREM-сон Стадии 1-2 (Легкий сон / Light Sleep)
&lt;/h3>&lt;p>Это подготовительная стадия, когда мозговые волны постепенно замедляются, и тело начинает расслабляться. Составляет около 50% всего сна. Хотя вклад в когнитивное восстановление невелик, это важный мост для перехода к следующей стадии глубокого сна.&lt;/p>
&lt;h3 id="42-nrem-сон-стадия-3-глубокий-сон--deep-sleep--slow-wave-sleep-sws">4.2 NREM-сон Стадия 3 (Глубокий сон / Deep Sleep / Slow Wave Sleep: SWS)
&lt;/h3>&lt;p>В мозговых волнах появляются дельта-волны (низкие частоты 0,5-2 Гц), это основное время для физического восстановления тела. Секретируется большое количество гормона роста, и происходит восстановление клеток. Это также необходимо для укрепления иммунной системы, и напрямую связано не только с восстановлением мышечной усталости у спортсменов, но и со снятием зрительного напряжения и восстановлением мышц шеи и плеч у инженеров. Глубокий сон обычно концентрируется в циклах первой половины сна.&lt;/p>
&lt;h3 id="43-rem-сон-быстрый-сон--rapid-eye-movement">4.3 REM-сон (Быстрый сон / Rapid Eye Movement)
&lt;/h3>&lt;p>Мозг так же активен, как и во время бодрствования, но мышцы тела парализованы. Для инженеров этот REM-сон чрезвычайно важен; он играет роль в систематизации в мозгу синтаксиса новых языков программирования или сложных концепций алгоритмов, изученных в течение дня, и их закреплении в долговременной памяти (Memory Consolidation). Нейропластичность (Neuroplasticity) повышается, и способность к творческому решению проблем (&amp;ldquo;внезапно придумал, как исправить баг, принимая душ&amp;rdquo;) также усиливается благодаря REM-сну. REM-сон имеет тенденцию удлиняться во второй половине сна (ближе к утру).&lt;/p>
&lt;p>Другими словами, &amp;ldquo;сокращение времени сна путем принудительного раннего пробуждения по будильнику&amp;rdquo; означает локальное и значительное сокращение REM-сна, связанного с закреплением памяти и креативностью, что равносильно критическому багу, который существенно снижает вашу производительность как инженера.&lt;/p>
&lt;h2 id="5-непрерывный-мониторинг-уровня-глюкозы-cgm-и-защита-от-спайков">5. Непрерывный мониторинг уровня глюкозы (CGM) и защита от спайков
&lt;/h2>&lt;p>В последние годы внедрение CGM (Continuous Glucose Monitor: устройство для непрерывного мониторинга уровня глюкозы) стало обязательным среди биохакеров. Типичными устройствами являются FreeStyle Libre и Dexcom.
При употреблении пищи (особенно углеводов и сахара) концентрация глюкозы в крови резко возрастает (спайк уровня сахара в крови), а затем резко падает (краш) из-за массовой секреции инсулина. Во время этого &amp;ldquo;краша&amp;rdquo; возникает сильная сонливость (Brain Fog) и снижение концентрации. Сонливость &amp;ldquo;проклятых 2 часов дня&amp;rdquo; после обеда, скорее всего, вызвана не только биологическими часами, но и скачком уровня сахара в крови из-за чрезмерного потребления рамена или белого риса.&lt;/p>
&lt;p>Кривую реакции уровня глюкозы в крови $G(t)$ можно приблизительно выразить с помощью следующей модели затухающих колебаний как разницу между скоростью всасывания потребленных углеводов и клиренсом под действием инсулина:&lt;/p>
$$ G(t) = G_{base} + \Delta G \cdot e^{-\alpha t} \sin(\beta t) $$&lt;p>Где,&lt;/p>
&lt;ul>
&lt;li>$G_{base}$: Уровень глюкозы натощак (базовый уровень)&lt;/li>
&lt;li>$\Delta G$: Амплитуда повышения уровня глюкозы после еды&lt;/li>
&lt;li>$\alpha$: Коэффициент затухания, основанный на чувствительности к инсулину и скорости метаболизма&lt;/li>
&lt;li>$\beta$: Частотная составляющая колебаний&lt;/li>
&lt;li>$t$: Время, прошедшее после еды&lt;/li>
&lt;/ul>
&lt;p>Чтобы поддерживать производительность инженера, важно минимизировать $\Delta G$ (амплитуду). В частности, эффективны такие лайфхаки, как &amp;ldquo;сначала есть овощи (клетчатку)&amp;rdquo;, &amp;ldquo;избегать рафинированных углеводов&amp;rdquo; и &amp;ldquo;совершать 15-минутную легкую прогулку после еды (активирует транспортер GLUT4 и поглощает глюкозу в мышцы независимо от инсулина)&amp;rdquo;.&lt;/p>
&lt;h2 id="6-проектирование-архитектуры-построение-локального-конвейера-данных">6. Проектирование архитектуры: Построение локального конвейера данных
&lt;/h2>&lt;p>Построим локальный конвейер данных для интегрированного анализа биометрических данных и данных о производительности.
Следующая диаграмма Mermaid (блок-схема) показывает процесс от получения данных из API до их визуализации на дашборде.&lt;/p>
&lt;pre class="mermaid">
flowchart TD
A[&amp;#34;Oura Ring API (Биометрия)&amp;#34;] --&amp;gt;|JSON через OAuth2| C[&amp;#34;Конвейер приема данных на Python&amp;#34;]
B[&amp;#34;WakaTime API (Время кодирования)&amp;#34;] --&amp;gt;|JSON через API Ключ| C
E[&amp;#34;SwitchBot API (Температура комнаты / CO2)&amp;#34;] --&amp;gt;|JSON через API Ключ| C
C --&amp;gt;|Извлечение и Трансформация| D[&amp;#34;Pandas DataFrame (Память)&amp;#34;]
D --&amp;gt;|Загрузка| F[&amp;#34;TimescaleDB / PostgreSQL&amp;#34;]
F --&amp;gt; G[&amp;#34;Jupyter Notebook (Ad-hoc Анализ)&amp;#34;]
F --&amp;gt; H[&amp;#34;Веб-приложение Streamlit (Ежедневный мониторинг)&amp;#34;]
&lt;/pre>
&lt;p>Благодаря этой архитектуре мы сможем автоматически ежедневно отслеживать корреляцию между нашим физическим состоянием (ввод) и производительностью кодирования (вывод).&lt;/p>
&lt;p>Давайте рассмотрим последовательность взаимодействия между системами более подробно.&lt;/p>
&lt;pre class="mermaid">
sequenceDiagram
participant U as &amp;#34;Пользователь (Инженер)&amp;#34;
participant W as &amp;#34;Плагин WakaTime (VS Code)&amp;#34;
participant O as &amp;#34;Oura Ring и API&amp;#34;
participant S as &amp;#34;Python ETL Пакет&amp;#34;
participant DB as &amp;#34;TimescaleDB&amp;#34;
U-&amp;gt;&amp;gt;W: &amp;#34;Пишет код (Набор на клавиатуре)&amp;#34;
W--&amp;gt;&amp;gt;W: &amp;#34;Логирует точный ритм кодирования&amp;#34;
U-&amp;gt;&amp;gt;O: &amp;#34;Спит (Носит кольцо)&amp;#34;
O--&amp;gt;&amp;gt;O: &amp;#34;Записывает ВСР, ЧСС покоя, Темп. и Фазы сна&amp;#34;
S-&amp;gt;&amp;gt;W: &amp;#34;GET /api/v1/users/current/summaries&amp;#34;
S-&amp;gt;&amp;gt;O: &amp;#34;GET /v2/usercollection/sleep&amp;#34;
S-&amp;gt;&amp;gt;S: &amp;#34;Очистка и слияние данных (Pandas)&amp;#34;
S-&amp;gt;&amp;gt;DB: &amp;#34;INSERT INTO daily_metrics&amp;#34;
Note over S,DB: &amp;#34;Запланировано через Cron / Airflow&amp;#34;
&lt;/pre>
&lt;h2 id="7-прием-данных-с-помощью-python-и-pandas">7. Прием данных с помощью Python и Pandas
&lt;/h2>&lt;p>Давайте посмотрим, как использовать скрипт Python для фактического получения данных из API Oura Ring и WakaTime и их интеграции в виде Pandas DataFrame. Мы создадим надежный код, который выдержит практическое применение.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;span class="lnt">61
&lt;/span>&lt;span class="lnt">62
&lt;/span>&lt;span class="lnt">63
&lt;/span>&lt;span class="lnt">64
&lt;/span>&lt;span class="lnt">65
&lt;/span>&lt;span class="lnt">66
&lt;/span>&lt;span class="lnt">67
&lt;/span>&lt;span class="lnt">68
&lt;/span>&lt;span class="lnt">69
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">requests&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">pandas&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">pd&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">datetime&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">datetime&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">timedelta&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">os&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Environment Variables&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">OURA_TOKEN&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">os&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">getenv&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;OURA_ACCESS_TOKEN&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">WAKATIME_API_KEY&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">os&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">getenv&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;WAKATIME_API_KEY&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">fetch_oura_sleep_data&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">start_date&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">str&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">end_date&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">str&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">-&amp;gt;&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Fetch daily sleep summary from Oura Ring API v2.&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">url&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;https://api.ouraring.com/v2/usercollection/sleep&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">params&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;start_date&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">start_date&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;end_date&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">end_date&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">headers&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;Authorization&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Bearer &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">OURA_TOKEN&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">requests&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">headers&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">headers&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">params&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">params&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">response&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">raise_for_status&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="c1"># Raise exception for 4xx/5xx errors&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">data&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">response&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">json&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;data&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">[])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="n">data&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">json_normalize&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Extract deeply nested values or select essential columns&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">df&lt;/span>&lt;span class="p">[[&lt;/span>&lt;span class="s1">&amp;#39;day&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;score&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;time_in_bed&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;total_sleep_duration&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;average_hrv&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;lowest_heart_rate&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;deep_sleep_duration&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;rem_sleep_duration&amp;#39;&lt;/span>&lt;span class="p">]]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Convert dates to datetime objects and set as index&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;day&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">to_datetime&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;day&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">set_index&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;day&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">inplace&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">df&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">fetch_wakatime_data&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">start_date&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">str&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">end_date&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="nb">str&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">-&amp;gt;&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Fetch coding duration summaries from WakaTime API.&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">url&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;https://wakatime.com/api/v1/users/current/summaries&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">params&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;start&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">start_date&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;end&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">end_date&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;api_key&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">WAKATIME_API_KEY&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">requests&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">params&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">params&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">response&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">raise_for_status&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">data&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">response&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">json&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;data&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">[])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">records&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">day_data&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">data&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">date_str&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">day_data&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;range&amp;#39;&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="s1">&amp;#39;date&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Extract total seconds spent coding&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">total_seconds&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">day_data&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;grand_total&amp;#39;&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="s1">&amp;#39;total_seconds&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">records&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s1">&amp;#39;day&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">date_str&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;coding_hours&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">total_seconds&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="mf">3600.0&lt;/span>&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">records&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="n">df&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">empty&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;day&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">to_datetime&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;day&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">set_index&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;day&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">inplace&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">df&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s2">&amp;#34;__main__&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Fetch data for the last 60 days&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">end&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">datetime&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">now&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">strftime&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;%Y-%m-&lt;/span>&lt;span class="si">%d&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">start&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">datetime&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">now&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">timedelta&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">days&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">60&lt;/span>&lt;span class="p">))&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">strftime&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;%Y-%m-&lt;/span>&lt;span class="si">%d&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">oura_df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">fetch_oura_sleep_data&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">start&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">end&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">waka_df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">fetch_wakatime_data&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">start&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">end&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Merge datasets on &amp;#39;day&amp;#39; index using inner join&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">merged_df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">merge&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">oura_df&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">waka_df&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">left_index&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">right_index&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">how&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;inner&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Save raw data to CSV/DB&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">merged_df&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">to_csv&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;health_productivity_raw.csv&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Ingested &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="nb">len&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">merged_df&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> days of data.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="8-предобработка-данных-и-разработка-признаков-feature-engineering">8. Предобработка данных и разработка признаков (Feature Engineering)
&lt;/h2>&lt;p>Опасно использовать полученные необработанные данные напрямую для анализа. Необходимо обработать пропущенные значения (Missing Values) из-за забытой зарядки устройств и сгенерировать новые значимые показатели (разработка признаков: Feature Engineering).&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">engineer_features&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">df&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">-&amp;gt;&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Apply feature engineering and cleaning to the merged dataframe.&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">df&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">copy&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 1. Handle missing values (e.g., forward fill)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">fillna&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">method&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;ffill&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">inplace&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 2. Calculate Sleep Efficiency&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Formula: (Total Sleep Time / Time in Bed) * 100&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;sleep_efficiency_pct&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;total_sleep_duration&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;time_in_bed&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="mi">100&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 3. Calculate Sleep Stage Ratios&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;rem_ratio&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;rem_sleep_duration&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;total_sleep_duration&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;deep_ratio&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;deep_sleep_duration&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;total_sleep_duration&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 4. Calculate 7-day Moving Averages (Rolling Mean) to smooth out daily noise&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;hrv_7d_ma&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;average_hrv&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">rolling&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">window&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">7&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">mean&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;rhr_7d_ma&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;lowest_heart_rate&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">rolling&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">window&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">7&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">mean&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 5. Calculate daily deviation from baseline&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;hrv_deviation&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;average_hrv&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;hrv_7d_ma&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 6. Normalize targets for Machine Learning (Optional)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">from&lt;/span> &lt;span class="nn">sklearn.preprocessing&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">MinMaxScaler&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">scaler&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">MinMaxScaler&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df&lt;/span>&lt;span class="p">[[&lt;/span>&lt;span class="s1">&amp;#39;hrv_scaled&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;coding_scaled&amp;#39;&lt;/span>&lt;span class="p">]]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">scaler&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">fit_transform&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">df&lt;/span>&lt;span class="p">[[&lt;/span>&lt;span class="s1">&amp;#39;average_hrv&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;coding_hours&amp;#39;&lt;/span>&lt;span class="p">]])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Drop rows with NaN generated by rolling window&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">dropna&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">inplace&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">df&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">processed_df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">engineer_features&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">merged_df&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="9-корреляционный-анализ-пересечение-производительности-и-показателей-здоровья">9. Корреляционный анализ: Пересечение производительности и показателей здоровья
&lt;/h2>&lt;p>На основе предварительно обработанных данных мы проанализируем взаимосвязь между показателями здоровья и производительностью кодирования. Гипотеза заключается в том, что &amp;ldquo;в дни с высокой ВСР (когда вегетативная нервная система сбалансирована и восстановлена), концентрация сохраняется дольше, время кодирования увеличивается, или можно выполнять более сложные задачи&amp;rdquo;.&lt;/p>
&lt;pre class="mermaid">
xychart-beta
title ВСР против Часов кодирования в день (Нормализовано)
x-axis [&amp;#34;Пн&amp;#34;, &amp;#34;Вт&amp;#34;, &amp;#34;Ср&amp;#34;, &amp;#34;Чт&amp;#34;, &amp;#34;Пт&amp;#34;, &amp;#34;Сб&amp;#34;, &amp;#34;Вс&amp;#34;]
y-axis &amp;#34;ВСР и Вывод кодирования&amp;#34; 10 --&amp;gt; 100
line [45, 52, 65, 75, 70, 58, 48]
bar [35, 42, 58, 65, 60, 20, 15]
&lt;/pre>
&lt;p>&lt;em>(Примечание: Линейный график показывает отклонение от нормализованного базового уровня ВСР, а гистограмма показывает время кодирования WakaTime. Можно увидеть корреляцию, при которой вывод кодирования максимизируется со среды по пятницу, когда достигается достаточное восстановление)&lt;/em>&lt;/p>
&lt;p>Мы рассчитаем коэффициент корреляции (коэффициент корреляции Пирсона $r$) с помощью Pandas и проверим статистическую значимость (p-значение) с помощью SciPy.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">scipy.stats&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">stats&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Select numerical columns for correlation matrix&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">cols_of_interest&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;average_hrv&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;score&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;deep_sleep_duration&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;rem_sleep_duration&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;coding_hours&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">correlation_matrix&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">processed_df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="n">cols_of_interest&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">corr&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Correlation with Coding Hours:&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">correlation_matrix&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;coding_hours&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sort_values&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">ascending&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">False&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Calculate Pearson correlation coefficient and p-value for REM sleep and Coding Hours&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">r&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">p_value&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">stats&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">pearsonr&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">processed_df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;rem_sleep_duration&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="n">processed_df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;coding_hours&amp;#39;&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;REM Sleep vs Coding Hours: r = &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">r&lt;/span>&lt;span class="si">:&lt;/span>&lt;span class="s2">.3f&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">, p-value = &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">p_value&lt;/span>&lt;span class="si">:&lt;/span>&lt;span class="s2">.4f&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Во многих случаях наблюдается значимая положительная корреляция ($p &lt; 0.05$) между &lt;code>average_hrv&lt;/code> или &lt;code>rem_sleep_duration&lt;/code> и &lt;code>coding_hours&lt;/code>. В частности, в сообществе инженеров, занимающихся &amp;ldquo;количественным измерением себя&amp;rdquo; (Quantified Self), часто сообщается, что продолжительность REM-сна в предыдущую ночь сильно влияет на &amp;ldquo;время, необходимое для устранения ошибок (отладки)&amp;rdquo; и &amp;ldquo;производительность&amp;rdquo; в текущий день.&lt;/p>
&lt;h2 id="10-математическая-модель-циркадных-ритмов-и-оптимизация-когнитивных-пиков">10. Математическая модель циркадных ритмов и оптимизация когнитивных пиков
&lt;/h2>&lt;p>У людей есть биологические часы с циклом около 24 часов, называемые циркадным ритмом (Circadian Rhythm). В зависимости от этого ритма колеблются температура тела, секреция гормонов (утренний спайк кортизола и ночная секреция мелатонина) и &amp;ldquo;когнитивные способности&amp;rdquo;.&lt;/p>
&lt;p>Колебания циркадного ритма часто аппроксимируются с помощью математической модели, использующей косинусоиду (модель Cosinor), и изменения биометрических показателей можно сформулировать следующим образом:&lt;/p>
$$ y(t) = M + A \cos\left(\frac{2\pi}{24}(t - \phi)\right) + e(t) $$&lt;ul>
&lt;li>$y(t)$: Биометрический показатель в момент времени $t$ (например, температура кора тела или уровень бдительности)&lt;/li>
&lt;li>$M$: MESOR (Midline Estimating Statistic of Rhythm) - центральное значение ритма (средний уровень)&lt;/li>
&lt;li>$A$: Амплитуда (Amplitude) - величина колебаний&lt;/li>
&lt;li>$\phi$: Акрофаза (Acrophase) - фаза (время) пика&lt;/li>
&lt;li>$e(t)$: Член ошибки из-за факторов окружающей среды и т.д.&lt;/li>
&lt;/ul>
&lt;p>В контексте инженерии эта формула означает, что &amp;ldquo;время суток ($\phi$), когда производительность (уровень бдительности) достигает пика, биологически детерминировано, и в это время следует назначать задачи с наибольшей когнитивной нагрузкой (исправление сложных багов, проектирование новой архитектуры)&amp;rdquo;.&lt;/p>
&lt;p>В случае типичного утреннего хронотипа (Morning Lark) первый когнитивный пик наступает через 2-4 часа после пробуждения (например, с 9:00 до 11:00). Затем, около 14:00, наступает спад циркадного ритма (Post-lunch dip), и еще один небольшой пик приходится на вечер. Выявление вашего пикового времени ($\phi$) по уровню активности из данных носимых устройств и субъективному уровню концентрации, а затем защита этого времени с помощью &amp;ldquo;блокировки времени&amp;rdquo; в Google Календаре и т.д. — это лучший лайфхак для здоровья. Назначать бессмысленные встречи на пиковое время — все равно что выделять самое производительное ядро процессора для процесса ожидания.&lt;/p>
&lt;h2 id="11-фармакокинетика-кофеина-и-оптимальное-время-приема">11. Фармакокинетика кофеина и оптимальное время приема
&lt;/h2>&lt;p>Инженеры и кофе неразделимы, но чрезмерное употребление кофеина или употребление в позднее время блокирует аденозиновые рецепторы в мозге и разрушает &amp;ldquo;глубокий сон&amp;rdquo; (Deep Sleep) ночью. Субъективно вам может казаться, что вы спите хорошо, но посмотрев на данные Oura Ring, вы можете увидеть, что ваш пульс не падает, а доля глубокого сна резко снижается.&lt;/p>
&lt;p>Выведение кофеина из организма подчиняется кинетике первого порядка (First-order kinetics). Другими словами, концентрация в крови снижается экспоненциально.&lt;/p>
$$ C(t) = C_0 e^{-k t} $$&lt;p>Где,&lt;/p>
&lt;ul>
&lt;li>$C(t)$: Концентрация кофеина в крови по прошествии времени $t$&lt;/li>
&lt;li>$C_0$: Начальная концентрация (максимальная концентрация сразу после приема)&lt;/li>
&lt;li>$k$: Константа скорости элиминации (выведения)&lt;/li>
&lt;li>$t$: Время, прошедшее с момента приема (в часах)&lt;/li>
&lt;/ul>
&lt;p>Константа скорости элиминации $k$ выражается через период полувыведения кофеина ($t_{1/2}$) следующим образом:&lt;/p>
$$ k = \frac{\ln(2)}{t_{1/2}} $$&lt;p>Для здорового взрослого человека период полувыведения кофеина $t_{1/2}$ составляет около &lt;strong>5-6 часов&lt;/strong>, хотя это зависит от индивидуальной генетики (ген CYP1A2).
Например, предположим, что вы выпили 1 чашку капельного кофе (около 150 мг кофеина) в 15:00 ($C_0 = 150$). Если период полувыведения составляет 5,5 часов, то $k \approx 0.126$.
Рассчитав концентрацию остаточного кофеина в организме ко времени отхода ко сну в 23:00 (через 8 часов):&lt;/p>
$$ C(8) = 150 \times e^{-0.126 \times 8} = 150 \times e^{-1.008} \approx 150 \times 0.365 = 54.75 \text{ мг} $$&lt;p>Другими словами, ко времени сна в организме все еще остается 54 мг кофеина (немного больше, чем в 1 чашке эспрессо), что напрямую негативно влияет на архитектуру сна.
Вывод на основе данных, полученный из этой фармакокинетической модели, заключается в том, что &lt;strong>&amp;ldquo;для обеспечения качественного сна прием кофеина следует начинать через 90 минут после пробуждения (после того как уляжется спайк кортизола), и полностью прекращать не позднее 14:00 (за 9-10 часов до сна)&amp;rdquo;&lt;/strong>.&lt;/p>
&lt;h2 id="12-взлом-переменных-среды-lux-температура-co2">12. Взлом переменных среды (Lux, Температура, CO2)
&lt;/h2>&lt;p>Важно оптимизировать не только внутреннюю систему собственного тела, но и внешние переменные среды (Environment Variables).&lt;/p>
&lt;h3 id="121-программирование-световой-среды-lux">12.1 Программирование световой среды (Lux)
&lt;/h3>&lt;p>Самый мощный &amp;ldquo;Zeitgeber (синхронизатор: сигнал, указывающий время)&amp;rdquo; для сброса циркадных ритмов — это свет. Утром, когда около 100 000 люкс солнечного света попадает на фоторецепторные клетки сетчатки (ipRGC), секреция мелатонина прекращается, и таймер сбрасывается. И наоборот, ночью необходимо блокировать синий свет, чтобы не препятствовать секреции мелатонина. Эффективно не только снижать цветовую температуру дисплея с помощью такого программного обеспечения, как f.lux, но и управлять умным освещением (например, Philips Hue) через API, написав скрипт, который автоматически снижает освещенность и цветовую температуру в комнате после захода солнца.&lt;/p>
&lt;h3 id="122-контроль-температуры-в-спальне-и-латентность-сна-sleep-latency">12.2 Контроль температуры в спальне и латентность сна (Sleep Latency)
&lt;/h3>&lt;p>Люди засыпают при снижении температуры кора тела (Core Body Temperature). Поддерживая в спальне прохладную температуру 18-19 градусов и ложась в постель точно в момент резкого падения температуры кора тела, которая была временно повышена теплой ванной за 90 минут до сна, можно кардинально сократить латентность сна (Sleep Latency: время от момента укладывания в постель до засыпания) и максимизировать глубокий сон.&lt;/p>
&lt;h3 id="123-концентрация-co2-и-снижение-когнитивных-функций">12.3 Концентрация CO2 и снижение когнитивных функций
&lt;/h3>&lt;p>Если вы добавите API концентратора SwitchBot или метеостанции Netatmo в свой конвейер данных, вы увидите четкую отрицательную корреляцию между концентрацией углекислого газа (CO2) в помещении и производительностью.
Как показывают исследования Гарвардского университета и другие, когда концентрация CO2 превышает 1000 ppm, когнитивные функции (особенно способность принимать стратегические решения) начинают значительно снижаться, а превышение 2000 ppm вызывает серьезное падение производительности. Удаленная работа в закрытом помещении зимой незаметно снижает вашу производительность.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Pseudo-code for intelligent room ventilation using Home Assistant / SwitchBot API&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">requests&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">check_and_ventilate&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Get current CO2 level from Netatmo/SwitchBot API&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">co2_ppm&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">get_sensor_data&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;co2_sensor_id&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">co2_ppm&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="mi">1000&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Warning: CO2 level high (&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">co2_ppm&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> ppm). Cognitive decline risk.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Trigger smart plug to turn on ventilation fan&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">turn_on_smart_plug&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;ventilation_fan_id&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Send notification to Slack/Discord&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">send_notification&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Вентилятор включен. Уровень CO2 высокий.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">elif&lt;/span> &lt;span class="n">co2_ppm&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="mi">600&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">turn_off_smart_plug&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;ventilation_fan_id&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Регулярно выполняя такой скрипт с помощью Cron, вы создадите автономную систему контроля среды, которая всегда поддерживает оптимальную концентрацию кислорода.&lt;/p>
&lt;h2 id="13-заключение-cicd-системы-человеческого-тела">13. Заключение: CI/CD системы человеческого тела
&lt;/h2>&lt;p>Попробуйте рассматривать собственное тело как единую сложную распределенную систему. Носимые устройства (Oura Ring) — это экспортеры метрик для мониторинга (Prometheus), скрипты Python/Pandas — это конвейер анализа логов (Logstash/Fluentd), а ежедневные изменения физического состояния и производительности — это здоровье системы, отображаемое на дашборде (Grafana/Streamlit).&lt;/p>
&lt;p>&amp;ldquo;Работа в ущерб времени сна&amp;rdquo; — это то же самое, что и форсированное добавление функций, игнорируя технический долг (Technical Debt). В краткосрочной перспективе вы можете успеть к релизу, но в долгосрочной перспективе это обязательно приведет к сбою системы (выгоранию, серьезным проблемам со здоровьем, депрессии).&lt;/p>
&lt;p>Мониторинг ВСР, проверка трендов ЧСС покоя, оптимизация архитектуры сна. И ежедневная тонкая настройка &amp;ldquo;гиперпараметров&amp;rdquo;, таких как питание, упражнения, сон и окружающая среда, с одновременным анализом корреляции с данными о производительности WakaTime. Это не что иное, как процесс &lt;strong>CI/CD (непрерывная интеграция и непрерывная доставка)&lt;/strong> для человеческого тела.&lt;/p>
&lt;p>Давайте использовать науку о данных и API для инжиниринга такого состояния здоровья, которое позволит вам достичь максимальной производительности. Ведь качество кода, который вы пишете, напрямую зависит от здоровья вашей собственной биологической системы.&lt;/p>
&lt;hr>
&lt;p>&lt;em>Отказ от ответственности (Disclaimer): Эта статья суммирует личные эксперименты автора и подходы науки о данных, и не содержит медицинских советов. Если у вас наблюдается постоянное плохое самочувствие или нарушения сна, пожалуйста, проконсультируйтесь со специализированным медицинским учреждением.&lt;/em>&lt;/p></description></item></channel></rss>