Beck_Moulton

健康に関して「データホーダー」ですか?Apple Healthのエクスポート、Oura Ringのログ、GarminのCSVの間で、私はほぼ1000万行のバイオメトリックデータを抱えていました。心拍変動(HRV)や安静時心拍数(RHR)の複数年にわたるトレンドをExcelで分析しようとすると、「アプリケーションが応答していません」の地獄への片道切符です。📉

このチュートリアルでは、Quantified Selfデータエンジニアリングの世界に飛び込みます。DuckDB—OLAPのスイスアーミーナイフ—とApache Supersetを活用して、超高速なローカルファーストのバイオメトリックダッシュボードを構築します。乱雑なJSON/CSVエクスポートを、モデリング用のdbtとコンピュート用のDuckDBを使用して高性能なインサイトに変える方法を探ります。個人利用のためのデータエンジニアリングをマスターする方法を探しているなら、これが究極の「公衆の面前で学ぶ」プロジェクトです!🚀


アーキテクチャ:生のエクスポートから実際のインサイトへ

SQLを一行も書く前に、データの流れを見てみましょう。私たちが望むのは、モジュール化され、高速で、完全にローカルマシン上に留まるシステムです(プライバシーファーストですよね?🥑)。

graph TD
    A[Raw Data: Apple Health / Oura / Garmin] -->|CSV/JSON| B(DuckDB Storage)
    B --> C{dbt Transformation}
    C -->|Cleaned Views| D[DuckDB Analytical Layer]
    D --> E[Apache Superset / Grafana]
    E -->|Visualization| F[Personal Biometric Dashboard]

    style B fill:#fff,stroke:#333,stroke-width:2px
    style D fill:#fbbf24,stroke:#333,stroke-width:2px

Enter fullscreen mode Exit fullscreen mode


前提条件 🛠️

このチュートリアルに従うには、以下の技術スタックを用意してください:

  • DuckDB: 超高速なインプロセス分析データベース。
  • dbt-duckdb: データモデリングと変換用。
  • Apache Superset: 「驚きの要素」のビジュアライゼーション用。
  • Python 3.10+: すべてを繋ぎ合わせるため。

ステップ1:DuckDBで「混沌」を取り込む

DuckDBが素晴らしいのは、取り込みステップなしでCSVとJSONファイルを直接クエリできることです。Apple Healthエクスポートから大量のheart_rate.csvがあるとしましょう。

従来のDBがデータを「ロード」するのを待つのではなく、即座にビューを作成できます:

-- Create a view directly from a multi-million row CSV
CREATE VIEW raw_heart_rate AS 
SELECT 
    creationDate::TIMESTAMP as timestamp,
    value::DOUBLE as bpm
FROM read_csv_auto('data/apple_health_export/heart_rate.csv');

-- Check the 7-day rolling average of RHR
SELECT 
    date_trunc('day', timestamp) AS day,
    avg(bpm) OVER (
        ORDER BY timestamp 
        RANGE BETWEEN INTERVAL '7 days' PRECEDING AND CURRENT ROW
    ) as rolling_rhr
FROM raw_heart_rate
LIMIT 10;

Enter fullscreen mode Exit fullscreen mode


ステップ2:dbt変換レイヤー

生のSQLも素晴らしいですが、dbt (data build tool)を使うことで、個人健康データを本番ウェアハウスと同じように扱うことができます。重複排除や「回復スコア」(HRV対睡眠の質)のような複雑なメトリクスの計算を扱います。

models/biometrics/stg_hrv.sql内:

-- Clean and deduplicate HRV readings
WITH base AS (
    SELECT 
        timestamp,
        value as hrv_ms,
        device_id
    FROM {{ source('raw_data', 'hrv_export') }}
)
SELECT 
    date_trunc('hour', timestamp) as hour_bucket,
    avg(hrv_ms) as avg_hrv,
    count(*) as sample_count
FROM base
GROUP BY 1

Enter fullscreen mode Exit fullscreen mode


ステップ3:Apache Supersetでの視覚化

ここからが楽しい部分です!Apache Supersetはduckdb_engine SQLAlchemy URIを使用してDuckDBに接続します。

  1. Supersetを起動する(Dockerが最も簡単な方法)。
  2. 新しいデータベースを追加する。
  3. 接続文字列: duckdb:///path/to/your/local_vault.duckdb

接続したら、RHRトレンド、睡眠サイクル、アクティビティ相関を表示する「健康コマンドセンター」を作成できます。📊


「クラウド」に勝る理由 ☁️

個人データの場合、プライバシーが最優先です。DuckDBを使用することで、データがノートパソコンから離れることはありません。このローカルファーストのアプローチに着想を与えた高性能データアーキテクチャに関する高度なデータパターンと、これらのパイプラインを本番環境にスケールする方法の詳細については、公式Wellallyブログをぜひご覧ください。


「プロ」セットアップ:大規模JSONの処理 💾

ネストされたJSON(Oura APIエクスポートなど)を扱う場合、DuckDBのJSON拡張機能は救世主となります。複雑な健康ペイロードをフラット化する方法は次のとおりです:

import duckdb

# Initialize DuckDB and load JSON extension
con = duckdb.connect('health_vault.db')
con.execute("INSTALL json; LOAD json;")

# Extracting nested sleep stages
query = """
SELECT 
    summary_date,
    json_extract_path(sleep_data, 'score')::INT as sleep_score,
    json_extract_path(sleep_data, 'levels.summary.rem.minutes')::INT as rem_min
FROM read_json_auto('data/oura_sleep_data.json')
"""

df = con.execute(query).df()
print(df.head())

Enter fullscreen mode Exit fullscreen mode


結論:データを取り戻す 🥑

個人用バイオメトリックダッシュボードの構築は、きれいなグラフだけではなく、OLAPワークフローの習得でもあります。DuckDBApache Supersetを使用することで、CSVの山をミリ秒単位で応答する高性能分析エンジンに変えました。

次のステップ:

  1. 健康データをエクスポートする(Apple Health、Garmin、またはGoogle Fit)。
  2. dbtを使用してモデル化し、カフェイン摂取と睡眠の質の相関関係を見つける。
  3. ダッシュボードのスクリーンショットをコメント欄で共有する!

この「公衆の面前で学ぶ」プロジェクトを楽しんでいただけたなら、データエンジニアリングの深掘り記事を今後も購読してください。最新のデータスタックの本番環境対応例については、wellally.tech/blogをご覧ください。

ハッキングを楽しんで!💻🔥