AI-обработка данных носимых устройств
Носимые устройства генерируют непрерывный поток физиологических и двигательных данных. Сырые акселерометрические данные, интервалы RR, температура кожи — всё это требует специализированной обработки до того, как станет пригодным для клинических или потребительских выводов.
Типы носимых устройств и их данные
Потребительские:
- Apple Watch, Samsung Galaxy Watch: PPG (ЧСС), акселерометр, гироскоп, SpO₂, ЭКГ (1-канальная)
- Whoop, Oura Ring: HRV, температура кожи, SpO₂, стадии сна
- Fitbit: шаги, ЧСС, SpO₂, сон
Медицинские:
- Holter мониторы (Preventice, iRhythm Zio): многодневная 2-канальная ЭКГ
- CGM (Continuous Glucose Monitor, Dexterity, Abbott LibreLink): глюкоза каждые 5 минут
- Biosig-ID: биомеханическая аутентификация
Спортивные:
- Garmin HRM-Pro, Polar H10: R-R интервалы (точные HRV данные)
- Catapult Sports, STATSports: GPS + IMU с частотой 100 Гц
Обработка сигнала
PPG (Photoplethysmography) → ЧСС:
from scipy.signal import butter, filtfilt, find_peaks
import numpy as np
def ppg_to_hr(ppg_signal, sampling_rate=25):
"""
PPG сигнал: зелёный диод → пульсовая волна
1. Полосовой фильтр (0.5-4 Hz = 30-240 BPM)
2. Поиск пиков
3. Вычисление ЧСС
"""
# Butterworth bandpass filter
nyq = sampling_rate / 2
low, high = 0.5 / nyq, 4.0 / nyq
b, a = butter(4, [low, high], btype='band')
filtered = filtfilt(b, a, ppg_signal)
# Поиск систолических пиков
peaks, _ = find_peaks(filtered, distance=sampling_rate * 0.4)
# ЧСС из средних R-R интервалов
rr_intervals_sec = np.diff(peaks) / sampling_rate
hr_bpm = 60 / np.mean(rr_intervals_sec)
return hr_bpm, rr_intervals_sec
Очистка от артефактов движения (Motion Artifact Removal): PPG искажается при движении. Методы:
- Акселерометр для идентификации и вычитания артефакта (TROIKA, JOSS алгоритмы)
- Adaptive filter: акселерометр как reference signal
HRV из R-R интервалов:
def compute_hrv_metrics(rr_intervals_ms):
"""
Временные метрики HRV
"""
rr = np.array(rr_intervals_ms)
return {
'rmssd': np.sqrt(np.mean(np.diff(rr)**2)), # вегетативный баланс
'sdnn': np.std(rr), # общая вариабельность
'pnn50': np.mean(np.abs(np.diff(rr)) > 50), # % пар с разницей >50мс
'mean_rr': np.mean(rr),
'mean_hr': 60000 / np.mean(rr)
}
Классификация активности
IMU → Activity Recognition:
def extract_imu_features(accel_xyz, gyro_xyz, window_sec=5, sampling_rate=100):
"""
Окно 5 секунд → набор статистических фич
"""
window_samples = window_sec * sampling_rate
features = {}
for axis in ['x', 'y', 'z']:
acc = accel_xyz[axis][-window_samples:]
features.update({
f'acc_{axis}_mean': np.mean(acc),
f'acc_{axis}_std': np.std(acc),
f'acc_{axis}_p95': np.percentile(acc, 95),
f'acc_{axis}_energy': np.sum(acc**2) / window_samples
})
# Magnitude
magnitude = np.sqrt(sum(accel_xyz[a]**2 for a in ['x', 'y', 'z']))
features['sma'] = np.sum(np.abs(magnitude)) / window_samples # Signal Magnitude Area
features['zero_crossing_rate'] = np.mean(np.diff(np.sign(magnitude)) != 0)
# FFT features
fft = np.abs(np.fft.rfft(magnitude[-window_samples:]))
freqs = np.fft.rfftfreq(window_samples, 1/sampling_rate)
features['dominant_freq'] = freqs[np.argmax(fft)]
features['spectral_entropy'] = -np.sum(fft/fft.sum() * np.log(fft/fft.sum() + 1e-8))
return features
# Классификатор активности: покой, ходьба, бег, езда на велосипеде, подъём по лестнице
activity_model = RandomForestClassifier(n_estimators=200)
Анализ сна
Sleep Stage Classification: Коммерческие алгоритмы (GGIR, ActiSleep) используют акселерометр + ЧСС. Медицинский стандарт — PSG (полисомнография). Accuracy consumer devices vs. PSG: ~75-80% agreement.
def classify_sleep_stages(hr_ts, accel_ts, time_ts):
"""
4-классовая классификация: Wake / Light / Deep / REM
Фичи: движение (из акселерометра) + ЧСС + HRV RMSSD
"""
features = []
for i in range(0, len(time_ts), 30): # эпохи по 30 секунд (стандарт PSG)
epoch_hr = hr_ts[i:i+30]
epoch_acc = accel_ts[i:i+30]
features.append({
'hr_mean': np.mean(epoch_hr),
'hr_std': np.std(epoch_hr),
'rmssd': compute_rmssd(epoch_hr),
'movement': np.mean(np.abs(epoch_acc)),
'time_in_sleep': i / 3600 # часы от начала сна
})
stages = sleep_stage_model.predict(features)
return stages
Непрерывный мониторинг глюкозы
CGM Pattern Analysis:
def analyze_glucose_patterns(cgm_readings, timestamps):
"""
Метрики гликемического контроля: TIR, GMI, CV%
"""
glucose = np.array(cgm_readings)
return {
'time_in_range': np.mean((glucose >= 70) & (glucose <= 180)), # TIR 70-180 mg/dL
'time_below': np.mean(glucose < 70), # гипогликемия
'time_above': np.mean(glucose > 180), # гипергликемия
'cv_pct': np.std(glucose) / np.mean(glucose) * 100, # вариабельность
'gmi': 3.31 + 0.02392 * np.mean(glucose), # glucose management indicator (HbA1c proxy)
'meal_spikes': detect_meal_spikes(glucose, timestamps)
}
ML-прогноз гипогликемии: 30-60 минутный прогноз снижения ниже 70 mg/dL → предупреждение. LSTM на окне CGM данных + данные о приёме пищи/инсулина.
Конфиденциальность и HIPAA/GDPR
Обработка данных:
- Медицинские носимые: данные = PHI (Protected Health Information) по HIPAA
- На стороне edge: обработка сырых сигналов, передача только агрегатов
- Differential privacy: добавление шума при агрегировании популяционных данных
Анонимизация: Псевдонимизация + k-анонимность при публикации когортных данных для исследований.
Сроки: PPG обработка + IMU activity classification + sleep staging + базовый дашборд — 4-5 недель. CGM анализ, HRV-мониторинг, медицинские метрики, API для носимых устройств — 2-3 месяца.







