Burnout을 미리 감지하기: HRV 이상 탐지기를 Isolation Forest로 구축 🚀
Source: Dev.to
혹시 “휴식”을 했음에도 불구하고 트럭에 치인 듯한 기분으로 깨어본 적이 있나요? 아니면 헬스장에서 PR을 깨고 나서 24시간 만에 감기로 몸이 안 좋아진 적이 있나요? 우리 몸은 증상이 나타나기 훨씬 전에 이미 위험 신호를 보내고 있습니다. 그 중 가장 강력한 신호 중 하나가 Heart Rate Variability (HRV) 입니다.
이번 튜토리얼에서는 HRV anomaly detection, Isolation Forest, 그리고 Python을 활용해 예측 건강 파이프라인을 구축합니다. 비지도 학습을 이용해 초기 과훈련이나 감염이 다가오고 있음을 나타내는 “이상치” 일자를 식별할 수 있습니다. wearable data analysis와 scikit‑learn을 마스터하고 싶다면 바로 여기입니다. 🥑
과학: 왜 HRV인가?
HRV는 각 심장 박동 사이의 시간 간격 변화를 측정합니다. 높은 HRV는 일반적으로 회복된 신경계 상태를 나타내며, 갑작스러운 감소(또는 비정상적으로 높은 급증)는 종종 신체적 “붕괴”가 일어나기 전에 나타납니다. 표준 임계값만으로는 충분하지 않은데, 사람마다 “정상”이 다르기 때문입니다. 여기서 Isolation Forest가 빛을 발합니다—라벨이 된 데이터가 없어도 몸이 “이상하게” 작동할 때를 감지할 수 있습니다.
아키텍처 🏗️
graph TD
A[Wearable Device / Apple Health] -->|Export| B(InfluxDB)
B --> C{Python Analytics Engine}
C --> D[Scikit‑learn: Isolation Forest]
D -->|Identify Outliers| E[Grafana Dashboard]
E -->|Alert| F[User: Take a Rest Day!]
style D fill:#f9f,stroke:#333,stroke-width:2px
사전 요구 사항
- Python 3.9+
- scikit‑learn (머신러닝 마법을 위해)
- InfluxDB (시간 시계열 웨어러블 데이터를 위해 최적화됨)
- Grafana (대시보드를 위해)
Step 1: InfluxDB에서 데이터 가져오기 📥
import pandas as pd
from influxdb_client import InfluxDBClient
# Setup connection
token = "YOUR_INFLUX_TOKEN"
org = "YourOrg"
bucket = "HealthData"
client = InfluxDBClient(url="http://localhost:8086", token=token, org=org)
def fetch_hrv_data():
query = f'''
from(bucket: "{bucket}")
|> range(start: -30d)
|> filter(fn: (r) => r["_measurement"] == "heart_rate_variability")
|> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
'''
df = client.query_api().query_data_frame(query)
return df
# Assume df has columns: ['_time', 'hrv_ms', 'sleep_duration_hr']
df = fetch_hrv_data()
단계 2: Isolation Forest로 이상 감지 🌲
from sklearn.ensemble import IsolationForest
import numpy as np
def detect_overtraining(df):
# Focus on HRV and Sleep Duration as primary features
features = df[['hrv_ms', 'sleep_duration_hr']]
# contamination=0.05 → expect ~5 % of days to be anomalous
model = IsolationForest(
n_estimators=100,
contamination=0.05,
random_state=42
)
# 1 = normal, -1 = anomaly
df['anomaly_score'] = model.fit_predict(features)
# Return potential red flags
return df[df['anomaly_score'] == -1]
anomalies = detect_overtraining(df)
print(f"Detected {len(anomalies)} days where your body was under significant stress!")
“공식적인” 확장 방법 💡
이 스크립트는 개인 프로젝트를 시작하기에 훌륭하지만, 프로덕션 수준의 건강 모니터링 시스템은 누락된 데이터, 센서 노이즈, 베이스라인 드리프트를 처리해야 합니다. 바이오메트릭 데이터 처리에 대한 고급 아키텍처 패턴 및 보다 프로덕션에 적합한 예시를 보려면 WellAlly Official Blog 를 참조하세요.
단계 3: Grafana에서 시각화 📊
Python 스크립트가 이상을 감지하면, InfluxDB에 “플래그”를 다시 기록합니다. Grafana에서는 Time Series 패널을 만들고 State Timeline을 사용하여 빨간 구역을 강조 표시할 수 있습니다.
Pro‑tip: 가벼운 편차에는 노란색을, “즉시 훈련 중지” 신호에는 빨간색을 사용하세요.
-- Example Flux query for Grafana
from(bucket: "HealthData")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "hrv_anomalies")
|> yield(name: "anomalies")
결론: 데이터 > 직관 🧘♂️
버너웃을 느낄 때쯤이면 HRV가 며칠 동안 하향 추세를 보였을 가능성이 높습니다. scikit‑learn의 Isolation Forest를 사용하면 반응적인 회복에서 능동적인 건강 관리로 전환할 수 있습니다.
우리가 만든 것 요약
- InfluxDB에 연결하여 시계열 데이터를 가져왔습니다.
- 건강 이상치를 찾기 위해 비지도 ML 모델을 구현했습니다.
- 결과를 시각화하여 감염·과훈련을 약 24시간 일찍 포착했습니다.
어떤 데이터를 추적하고 계신가요? Oura, Whoop, Apple Watch…? 댓글로 알려주시고, 이상 탐지를 위한 최고의 특징에 대해 이야기해요! 👇