<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Oura Ring on kenji.blog</title><link>http://kenji.blog/tags/oura-ring/</link><description>Recent content in Oura Ring on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>ja</language><copyright>kenjinote</copyright><lastBuildDate>Sat, 12 Sep 2026 12:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/tags/oura-ring/index.xml" rel="self" type="application/rss+xml"/><item><title>スマートリング等で体調管理するエンジニアの日常（健康ハック）</title><link>http://kenji.blog/p/engineer-health-hacks-wearables/</link><pubDate>Sat, 12 Sep 2026 12:00:00 +0900</pubDate><guid>http://kenji.blog/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）を伴う過酷な知的労働です。常に変化する技術スタックのキャッチアップ、複雑な分散システムのバグハント、そして納期へのプレッシャー。これらを乗り越えるためには、単に「気合」や「根性」で乗り切るのではなく、システムをデバッグするように自らの身体というハードウェアをチューニングするアプローチ、すなわち「バイオハッキング（Biohacking）」が必要不可欠です。&lt;/p>
&lt;p>かつては「今日はなんとなく体調が良い・悪い」という主観的な感覚（ヒューリスティクス）に頼っていましたが、現代ではOura Ring、Apple Watch、Garminなどの高性能なウェアラブルデバイスの普及により、生体データを24時間365日、非侵襲で取得できるようになりました。本記事では、生体データ（HRV、RHR、睡眠アーキテクチャ）と生産性データ（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>指の動脈から直接データを取得するため、手首で計測するスマートウォッチと比較して、睡眠時の心拍数や心拍変動（HRV）、体表温の変化の計測精度が非常に高いのが特徴です。指には毛細血管が密集しており、光学式心拍センサー（PPG: Photoplethysmography）によるノイズの少ないデータ取得が可能です。また、REST APIが充実しており、OAuth2.0経由でJSON形式の生データを容易にエクスポートできるため、エンジニアにとって最もハッカブルなデバイスと言えます。&lt;/p>
&lt;h3 id="22-apple-watch-series--ultra">2.2 Apple Watch Series / Ultra
&lt;/h3>&lt;p>アクティビティ中のトラッキングや、血中酸素飽和度（SpO2）、心電図（ECG）の計測に優れています。日中の活動量や、マインドフルネスアプリ（呼吸アプリ）を通じたオンデマンドのHRV計測においては最強のデバイスです。ただし、データのエクスポートにはHealthKitを経由する必要があり、Pythonなどからの直接アクセスにはiOSアプリ（AutoSleepやHealthFitなど）を介したCSVエクスポートなど、ワンクッションが必要になります。&lt;/p>
&lt;h3 id="23-garmin-fenix--forerunner">2.3 Garmin (Fenix / Forerunner)
&lt;/h3>&lt;p>GPSトラッキングの精度に加えて、「Body Battery（ボディバッテリー）」と呼ばれる独自のエネルギー残量指標が優秀です。これはHRVとストレスレベルを基に算出されます。GarminはGarmin Connect APIを通じて取得可能ですが、法人向けAPIの壁があるため、個人開発者としてはオープンソースのライブラリを使用するか、有志によるスクレイピングツールを活用する必要があります。&lt;/p>
&lt;p>本記事では、睡眠と回復のトラッキングにおいて最高峰であり、APIからのデータ抽出が極めて容易な &lt;strong>Oura Ring&lt;/strong> のデータと、IDE（VS CodeやIntelliJなど）のプラグインとしてコーディング時間を計測する &lt;strong>WakaTime&lt;/strong> のデータを主軸に解説を進めます。&lt;/p>
&lt;h2 id="3-生体データの基礎理論hrvとrhrのデータサイエンス">3. 生体データの基礎理論：HRVとRHRのデータサイエンス
&lt;/h2>&lt;p>単に「睡眠時間が長いから良い」という単純な指標ではなく、データサイエンスの観点からは以下の2つの指標が「回復（Recovery）」のマスターメトリクスとなります。&lt;/p>
&lt;h3 id="31-hrv心拍変動heart-rate-variabilityと自律神経のモデリング">3.1 HRV（心拍変動：Heart Rate Variability）と自律神経のモデリング
&lt;/h3>&lt;p>心臓はメトロノームのように一定のリズムで打っているわけではありません。例えば心拍数が60bpmであっても、1拍1拍の間隔（R-R間隔）は「0.92秒」「1.05秒」「0.98秒」のように常に揺らいでいます。この揺らぎの大きさを数値化したものがHRV（心拍変動）です。&lt;/p>
&lt;p>HRVは自律神経系、すなわち「交感神経（アクセル）」と「副交感神経（ブレーキ）」のバランスを直接的に反映しています。ストレス状態、過労、あるいはアルコール摂取後などでは交感神経が優位になり、心臓の拍動は一定に近づきHRVは低下します。逆に十分にリラックスし回復している状態では、副交感神経（迷走神経）が優位になり、呼吸に合わせて心拍がダイナミックに変動するため、HRVは高くなります。&lt;/p>
&lt;p>HRVの計算には時間領域（Time-domain）と周波数領域（Frequency-domain）の2つのアプローチがありますが、時間領域分析において最も一般的に用いられ、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>エンジニアにとって、朝起きた時のHRV（RMSSD）が個人のベースライン（過去数週間の移動平均）よりも大きく低下している場合、「今日は認知的負荷の高いアーキテクチャ設計や、本番環境へのデプロイは避けて、テストコードの拡充やドキュメント作成に充てるべき日である」というデータドリブンな意思決定が可能になります。&lt;/p>
&lt;h3 id="32-安静時心拍数rhrresting-heart-rateと回復のシグナル">3.2 安静時心拍数（RHR：Resting Heart Rate）と回復のシグナル
&lt;/h3>&lt;p>RHRは、身体が完全にリラックスしている状態（通常は睡眠中）の1分間あたりの心拍数です。アルコール摂取後や、遅い時間の過食、あるいは病気（感染症など）の初期症状として、身体が体内の代謝や免疫反応にエネルギーを割いている時、RHRはベースラインよりも数bpm〜十数bpm上昇します。&lt;/p>
&lt;p>RHRが低いほど、心筋が一度の拍動で多くの血液を送り出せている（1回拍出量が多い）ことを意味し、有酸素運動能力の高さや疲労からの回復度合いを示します。理想的には、睡眠の最初の半分（前半）でRHRが最低値に達する「ハンモック型」のカーブを描くのが、最も質の高い回復ができている状態です。&lt;/p>
&lt;h2 id="4-睡眠アーキテクチャの詳細解析">4. 睡眠アーキテクチャの詳細解析
&lt;/h2>&lt;p>エンジニアの頭脳のパフォーマンスを決定づけるのは、睡眠の「量」だけでなく「質」、すなわち睡眠アーキテクチャ（Sleep Architecture）です。一晩の睡眠は通常、90〜110分のサイクルを4〜5回繰り返します。&lt;/p>
&lt;h3 id="41-nrem睡眠-ステージ12浅い睡眠--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〜2Hzの低周波）が現れる、物理的な肉体の回復のコアとなる時間帯です。成長ホルモンが大量に分泌され、細胞の修復が行われます。免疫系の強化にも不可欠であり、アスリートの筋疲労回復だけでなく、エンジニアの眼精疲労や首・肩の筋肉の修復にも直結します。深い睡眠は通常、睡眠の前半のサイクルに集中します。&lt;/p>
&lt;h3 id="43-rem睡眠rapid-eye-movement">4.3 REM睡眠（Rapid Eye Movement）
&lt;/h3>&lt;p>脳が覚醒時と同じくらい活発に動いている状態ですが、身体の筋肉は麻痺状態にあります。エンジニアにとって極めて重要なのがこのREM睡眠で、日中に学んだ新しいプログラミング言語の構文や、複雑なアルゴリズムの概念を脳内で整理し、長期記憶として定着（Memory Consolidation）させる役割を担います。神経可塑性（Neuroplasticity）を高め、創造的な問題解決能力（「シャワーを浴びている時に突然バグの解決策を閃く」ようなひらめき）もREM睡眠によって強化されます。REM睡眠は睡眠の後半（明け方）に長くなる傾向があります。&lt;/p>
&lt;p>つまり、「アラームで無理やり早く起きて睡眠時間を削る」ことは、記憶定着と創造性に関わるREM睡眠を局所的に大きく削ることを意味し、エンジニアとしてのパフォーマンスを著しく低下させる重大なバグに等しい行為です。&lt;/p>
&lt;h2 id="5-連続血糖測定cgmとスパイクの防御">5. 連続血糖測定（CGM）とスパイクの防御
&lt;/h2>&lt;p>近年、バイオハッカーの間で必須となっているのがCGM（Continuous Glucose Monitor：連続血糖測定器）の導入です。代表的なデバイスにFreeStyle LibreやDexcomがあります。
食事（特に炭水化物や糖分）を摂取すると、血中のグルコース濃度が急激に上昇（血糖値スパイク）し、その後インスリンの大量分泌によって急降下（クラッシュ）します。この「クラッシュ」のタイミングで、強烈な眠気（Brain Fog）や集中力の低下が引き起こされます。昼食後の「魔の午後2時」の眠気は、単なる体内時計の影響だけでなく、ラーメンや白米の過剰摂取による血糖値スパイクが原因である可能性が高いのです。&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$（振幅）を最小限に抑えることが重要です。具体的には、「野菜（食物繊維）を先に食べる」「精製された炭水化物を避ける」「食後に15分の軽い散歩をする（GLUT4トランスポーターを活性化させ、インスリン非依存的に血糖を筋肉に取り込む）」といったハックが有効です。&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 (Biometrics)&amp;#34;] --&amp;gt;|JSON via OAuth2| C[&amp;#34;Python Data Ingestion Pipeline&amp;#34;]
B[&amp;#34;WakaTime API (Code Time)&amp;#34;] --&amp;gt;|JSON via API Key| C
E[&amp;#34;SwitchBot API (Room Temp / CO2)&amp;#34;] --&amp;gt;|JSON via API Key| C
C --&amp;gt;|Extract &amp;amp; Transform| D[&amp;#34;Pandas DataFrame (Memory)&amp;#34;]
D --&amp;gt;|Load| F[&amp;#34;TimescaleDB / PostgreSQL&amp;#34;]
F --&amp;gt; G[&amp;#34;Jupyter Notebook (Ad-hoc Analysis)&amp;#34;]
F --&amp;gt; H[&amp;#34;Streamlit Web App (Daily Monitoring)&amp;#34;]
&lt;/pre>
&lt;p>このアーキテクチャにより、毎日自動で自身の体調（インプット）とコーディングパフォーマンス（アウトプット）の相関関係をモニタリングできるようになります。&lt;/p>
&lt;p>さらに、システム間でのシーケンスを詳細に見てみましょう。&lt;/p>
&lt;pre class="mermaid">
sequenceDiagram
participant U as &amp;#34;User (Engineer)&amp;#34;
participant W as &amp;#34;WakaTime Plugin (VS Code)&amp;#34;
participant O as &amp;#34;Oura Ring &amp;amp; API&amp;#34;
participant S as &amp;#34;Python ETL Batch&amp;#34;
participant DB as &amp;#34;TimescaleDB&amp;#34;
U-&amp;gt;&amp;gt;W: &amp;#34;Write code (Keyboard typing)&amp;#34;
W--&amp;gt;&amp;gt;W: &amp;#34;Log precise coding heartbeat&amp;#34;
U-&amp;gt;&amp;gt;O: &amp;#34;Sleep (Wear ring)&amp;#34;
O--&amp;gt;&amp;gt;O: &amp;#34;Record HRV, RHR, Temp &amp;amp; Sleep Stages&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;Clean and Merge Data (Pandas)&amp;#34;
S-&amp;gt;&amp;gt;DB: &amp;#34;INSERT INTO daily_metrics&amp;#34;
Note over S,DB: &amp;#34;Scheduled via Cron / Airflow&amp;#34;
&lt;/pre>
&lt;h2 id="7-pythonとpandasによるデータインジェスト">7. PythonとPandasによるデータインジェスト
&lt;/h2>&lt;p>実際にPythonスクリプトを用いて、Oura RingとWakaTimeのAPIからデータを取得し、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-データ前処理と特徴量エンジニアリング">8. データ前処理と特徴量エンジニアリング
&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>前処理したデータを元に、健康指標とコーディング生産性の関係を分析します。仮説として、「HRVが高い（自律神経が整い回復している）日ほど、集中力が持続しコーディング時間が長くなる、あるいはより複雑なタスクをこなせる」ということが考えられます。&lt;/p>
&lt;pre class="mermaid">
xychart-beta
title HRV vs Daily Coding Hours (Normalized)
x-axis [&amp;#34;Mon&amp;#34;, &amp;#34;Tue&amp;#34;, &amp;#34;Wed&amp;#34;, &amp;#34;Thu&amp;#34;, &amp;#34;Fri&amp;#34;, &amp;#34;Sat&amp;#34;, &amp;#34;Sun&amp;#34;]
y-axis &amp;#34;HRV &amp;amp; Coding Output&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>(注: 折れ線グラフが正規化されたHRVベースラインからの乖離、棒グラフがWakaTimeのコーディング時間を示します。十分な回復が得られている水曜日から金曜日にかけて、コーディングのアウトプットが最大化されている相関が見て取れます)&lt;/em>&lt;/p>
&lt;p>Pandasでの相関係数（ピアソンの積率相関係数 $r$）の算出と、SciPyを用いた統計的有意性（p値）の検定を行います。&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>多くの場合、&lt;code>average_hrv&lt;/code> や &lt;code>rem_sleep_duration&lt;/code> と &lt;code>coding_hours&lt;/code> の間に有意な正の相関（$p &lt; 0.05$）が観察されます。特に、前日のREM睡眠の長さが、当日の「エラー解決（デバッグ）にかかる時間」や「生産性」に強く影響を与えることが、多くのエンジニアの自己追跡（Quantified Self）コミュニティで報告されています。&lt;/p>
&lt;h2 id="10-サーカディアンリズムの数理モデルと認知ピークの最適化">10. サーカディアンリズムの数理モデルと認知ピークの最適化
&lt;/h2>&lt;p>人間には概日リズム（Circadian Rhythm）と呼ばれる約24時間周期の体内時計が備わっています。このリズムによって、体温、ホルモン分泌（朝方のコルチゾールスパイクや夜間のメラトニン分泌）、そして「認知能力」が変動します。&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>エンジニアリングにおいてこの式が意味するのは、「1日の中でパフォーマンス（覚醒度）がピークになる時間帯（$\phi$）は生物学的に決まっており、その時間帯に最も認知的負荷の高いタスク（難解なバグ修正、新しいアーキテクチャの設計）を割り当てるべきである」ということです。&lt;/p>
&lt;p>一般的な朝型（Morning Lark）クロノタイプの場合、起床後2〜4時間（例えば午前9時〜11時）に最初の認知ピークが訪れます。その後、午後2時頃に概日リズムの谷間（Post-lunch dip）が訪れ、夕方にもう一度小さなピークが来ます。自分のピークタイム（$\phi$）をウェアラブルデータの活動量や主観的集中度から特定し、Google Calendar等のスケジュールを「タイムブロッキング」して守ることが、最高の健康ハックです。ピークタイムに無意味なミーティングを入れることは、CPUの一番性能が良いコアをアイドルプロセスに割り当てるようなものです。&lt;/p>
&lt;h2 id="11-カフェインの薬物動態学と最適な摂取タイミング">11. カフェインの薬物動態学と最適な摂取タイミング
&lt;/h2>&lt;p>エンジニアとコーヒーは切っても切れない関係にありますが、カフェインの過剰摂取や遅い時間の摂取は、脳内のアデノシン受容体をブロックし、夜間の「深い睡眠（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>健康な成人の場合、個人の遺伝子（CYP1A2遺伝子）にもよりますが、カフェインの半減期 $t_{1/2}$ はおよそ &lt;strong>5〜6時間&lt;/strong> とされています。
例えば、午後3時にドリップコーヒーを1杯（カフェイン約150mg）飲んだとします（$C_0 = 150$）。半減期を5.5時間とすると、$k \approx 0.126$ となります。
就寝時間の午後11時（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{ mg} $$&lt;p>つまり、寝る時間になっても体内にまだ54mg（エスプレッソ1杯強）のカフェインが残留していることになり、これが睡眠アーキテクチャにダイレクトに悪影響を及ぼします。
この薬物動態モデルから導き出されるデータドリブンな結論は、&lt;strong>「質の高い睡眠を確保するためには、カフェイン摂取は起床後90分以降（コルチゾールスパイクが落ち着いた後）に開始し、遅くとも午後2時（就寝の9〜10時間前）には完全にカットオフすべきである」&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>サーカディアンリズムをリセットする最も強力な「ツァイトゲーバー（Zeitgeber：時間を知らせる手がかり）」は光です。朝、網膜の光受容細胞（ipRGC）に約100,000 Luxの太陽光が入ることでメラトニンの分泌が止まり、タイマーがリセットされます。逆に夜間はブルーライトを遮断し、メラトニン分泌を阻害しないことが必須です。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>SwitchBotハブやNetatmoのウェザーステーションのAPIをデータパイプラインに追加すると、室内の二酸化炭素（CO2）濃度と生産性に明確な負の相関が見られます。
ハーバード大学の研究などでも示されている通り、CO2濃度が1000ppmを超えると認知機能（特に戦略的意思決定能力）が有意に低下し始め、2000ppmを超えると深刻なパフォーマンス低下を引き起こします。冬場の締め切った部屋でのリモートワークは、知らず知らずのうちにパフォーマンスを下げています。&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>「睡眠時間を削って働く」ことは、技術的負債（Technical Debt）を無視して機能追加を強行することと同じです。短期的にはリリースに間に合うかもしれませんが、長期的には必ずシステムダウン（バーンアウトや深刻な健康被害、うつ病）を引き起こします。&lt;/p>
&lt;p>HRVをモニタリングし、RHRのトレンドをチェックし、睡眠アーキテクチャを最適化する。そして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>