Schlafqualitäts-Klassifikator mit XGBoost optimieren
Erfahren Sie, wie Sie eine Health-Tech-Anwendung erstellen, die Schlafqualität aus Wearable-Sensordaten klassifiziert. Mit Pandas, NumPy und XGBoost.
Auf dieser Seite
Haben Sie sich jemals den Schlaf-Score Ihres Wearables angesehen und sich gefragt: „Aber warum war er ein 78?" Die meisten Verbrauchergeräte liefern einen hochrangigen Score, zeigen aber selten die zugrunde liegende Datenwissenschaft. Sie sammeln einen Schatz an rohen Sensordaten – Herzfrequenz, Beschleunigung, Temperatur – doch die Magie liegt in der Transformation dieser Daten in aussagekräftige Erkenntnisse.
In diesem Tutorial werden wir den Vorhang für die Schlafqualitäts-Klassifizierung zurückziehen. Wir werden eine vollständige Pipeline für maschinelles Lernen aufbauen, um die Schlafqualität aus simulierten Wearable-Daten vorherzusagen. Sie werden lernen, wie Sie noisy, rohe Zeitreihendaten verarbeiten, aussagekräftige Features engineerieren und ein leistungsstarkes XGBoost-Modell trainieren, um die Nacht als „Schlecht", „Durchschnittlich" oder „Gut" zu klassifizieren.
Dieses Projekt ist für Entwickler relevant, da es ein perfektes reales Beispiel für Feature Engineering bei Zeitreihendaten ist – eine häufige Aufgabe in IoT, Gesundheitstechnologie und persönlicher Analytik. Am Ende haben Sie eine praktische Vorlage für ähnliche Klassifizierungsprobleme mit Sensordaten.
Voraussetzungen:
- Python 3.7+
- Praktische Kenntnisse in Pandas, NumPy und Scikit-learn.
- Vertrautheit mit Konzepten des maschinellen Lernens wie Klassifizierung und Feature Engineering.
- Interesse am wachsenden Bereich der Gesundheitstechnologie!
Das Problem verstehen
Die Kernherausforderung besteht darin, dass rohe Sensordaten nicht direkt von einem Modell für maschinelles Lernen interpretierbar sind. Eine Liste von Herzfrequenzzahlen oder Beschleunigungsmesserwerten bedeutet nicht von selbst „guten" oder „schlechten" Schlaf. Wir müssen Kontext bieten, indem wir Features engineerieren, die die Charakteristika einer guten Nacht erfassen.
Technischer Kontext und Herausforderungen:
- Noisy Data (Noisy Daten): Sensorablesungen können aufgrund von Bewegung, unsachgemäßem Sensorkontakt oder Umgebungsfaktoren unsauber sein.
- Zeitreihennatur: Die Daten sind sequentiell, und die Beziehungen zwischen Datenpunkten über die Zeit sind entscheidend.
- Feature-Extraktion: Der kritischste Schritt ist die Erstellung von Features, die Schlafmuster quantifizieren. Zum Beispiel:
- Herzfrequenzvariabilität (HRV): Die Variation der Zeit zwischen Herzschlägen ist ein starker Indikator für Erholung und den Zustand des Nervensystems.
- Bewegungsanalyse: Quantifizierung von Unruhe und Erkennung von Schlafphasen (wie REM- vs. Tiefschlaf) aus Beschleunigungsmesserdaten.
- Schlafdauer & Effizienz: Grundlegende, aber wesentliche Metriken, die aus den Daten berechnet werden.
Unser Ansatz ist es, einen robusten Feature-Satz zu erstellen, der unserem Modell eine reichhaltige, mehrdimensionale Sicht auf jede Schlafsitzung bietet, was zu einer genaueren und differenzierteren Klassifizierung führt als nur die Verwendung roher Daten.
Übersicht der Machine-Learning-Pipeline
Das folgende Diagramm zeigt unsere vollständige Pipeline von rohen Sensordaten zur Schlafqualitäts-Klassifizierung:
Voraussetzungen
Lassen Sie uns unsere Umgebung einrichten. Sie benötigen Python und einige wichtige Bibliotheken.
- Erforderliche Bibliotheken:
pandas,numpy,scikit-learn,xgboost,scipy - Installation:
pip install pandas numpy scikit-learn xgboost scipy
Hinweis: Dieses Beispiel verwendet synthetische/simulierte Daten zur Demonstration. In der Produktion stellen Sie sicher, dass alle Gesundheitsdaten anonymisiert und gemäß DSGVO/HIPAA verarbeitet werden.
Generierung synthetischer Wearable-Schlafdaten
Was wir tun
Zunächst benötigen wir Daten. Wir generieren einen synthetischen Datensatz, der Rohdaten von einem Wearable-Gerät über mehrere Nächte nachahmt. Jede Nacht enthält zeitgestempelte Herzfrequenz- (HR) und Beschleunigungsmesser- (ACC) Messungen. Wir weisen auch ein Ground-Truth-„Schlafqualitäts"-Label jeder Nacht zu.
Implementierung
# src/data_simulation.py
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
def simulate_wearable_data(nights=50):
"""
Generates a synthetic wearable dataset for multiple nights.
Each night consists of 8 hours of data with 1-second frequency.
Features: heart_rate (bpm), acceleration (g).
"""
data_frames = []
for night in range(nights):
# Assign a random sleep quality for this night
quality = np.random.choice(['Poor', 'Average', 'Good'], p=[0.25, 0.45, 0.3])
start_time = datetime(2025, 1, 1, 22, 0, 0) + timedelta(days=night)
# Base parameters based on sleep quality
if quality == 'Good':
hr_base, hr_var = 60, 3
acc_base, acc_var = 0.01, 0.005
num_awakenings = np.random.randint(0, 2)
elif quality == 'Average':
hr_base, hr_var = 68, 5
acc_base, acc_var = 0.02, 0.01
num_awakenings = np.random.randint(2, 5)
else: # Poor
hr_base, hr_var = 75, 8
acc_base, acc_var = 0.04, 0.02
num_awakenings = np.random.randint(5, 10)
# Generate 8 hours of data (28800 seconds)
timestamps = pd.to_datetime([start_time + timedelta(seconds=i) for i in range(28800)])
# Simulate data
hr = hr_base + np.random.randn(28800) * hr_var
acc = np.abs(acc_base + np.random.randn(28800) * acc_var)
# Add some spikes for awakenings/restlessness
for _ in range(num_awakenings):
idx = np.random.randint(0, 28800)
spike_duration = np.random.randint(60, 300)
hr[idx:idx+spike_duration] += np.random.uniform(5, 15)
acc[idx:idx+spike_duration] += np.random.uniform(0.1, 0.5)
night_df = pd.DataFrame({
'timestamp': timestamps,
'heart_rate': hr,
'acceleration': acc,
'night_id': night,
'sleep_quality': quality
})
data_frames.append(night_df)
return pd.concat(data_frames, ignore_index=True)
# Generate and save the data
raw_data = simulate_wearable_data(nights=100)
raw_data.to_csv('wearable_sleep_data.csv', index=False)
print("Generated wearable_sleep_data.csv with 100 nights of data.")
print(raw_data.head())
Wie es funktioniert
Die Funktion simulate_wearable_data erstellt einen DataFrame, wobei jede Zeile eine Sekunde einer Nacht darstellt. Wir durchlaufen eine festgelegte Anzahl von Nächten und weisen jeder ein Schlafqualitätslabel zu. Die Charakteristika der simulierten Herzfrequenz- und Beschleunigungsdaten (Mittelwert, Varianz und Anzahl der Spitzen) werden durch dieses Label bestimmt, was reale Muster nachahmt. Beispielsweise hat „Guter" Schlaf eine niedrigere, stabilere Herzfrequenz und weniger Bewegung.
Schlaf-Features mit Pandas engineerieren
Was wir tun
Dies ist der wichtigste Schritt. Wir transformieren die rohen, sekundenweisen Daten in eine hochrangige Zusammenfassung für jede Nacht. Jede Zeile in unserem neuen DataFrame repräsentiert eine night_id, und die Spalten sind die Features, die wir engineerieren.
Implementierung
# src/feature_engineering.py
import pandas as pd
import numpy as np
from scipy.stats import iqr
def calculate_hrv(hr_series):
"""Calculates Heart Rate Variability (RMSSD) from a heart rate series."""
# Calculate RR intervals (time between beats) in milliseconds
rr_intervals = 60000 / hr_series
# Calculate successive differences
successive_diffs = np.diff(rr_intervals)
# Calculate RMSSD (Root Mean Square of Successive Differences)
if len(successive_diffs) > 0:
rmssd = np.sqrt(np.mean(successive_diffs ** 2))
else:
rmssd = 0
return rmssd
def engineer_features(df):
"""
Engineers features from the raw wearable data, grouped by night.
"""
# Group by night
grouped = df.groupby('night_id')
feature_list = []
for night_id, group in grouped:
features = {'night_id': night_id}
# Basic HR features
features['hr_mean'] = group['heart_rate'].mean()
features['hr_std'] = group['heart_rate'].std()
features['hr_min'] = group['heart_rate'].min()
features['hr_max'] = group['heart_rate'].max()
# Heart Rate Variability (HRV)
features['hrv_rmssd'] = calculate_hrv(group['heart_rate'])
# Acceleration features (movement)
features['acc_mean'] = group['acceleration'].mean()
features['acc_std'] = group['acceleration'].std()
features['acc_max'] = group['acceleration'].max()
features['restless_moments'] = (group['acceleration'] > 0.1).sum() # Count moments of high movement
# Sleep Stage Duration (simplified)
# Deep sleep: low HR, low movement
deep_sleep_mask = (group['heart_rate'] < (features['hr_mean'] * 0.9)) & (group['acceleration'] < 0.05)
features['deep_sleep_duration_pct'] = deep_sleep_mask.sum() / len(group)
# Light sleep: moderate everything
light_sleep_mask = ~deep_sleep_mask
features['light_sleep_duration_pct'] = light_sleep_mask.sum() / len(group)
# Target variable
features['sleep_quality'] = group['sleep_quality'].iloc[0]
feature_list.append(features)
return pd.DataFrame(feature_list)
# Load raw data and engineer features
raw_data = pd.read_csv('wearable_sleep_data.csv')
featured_data = engineer_features(raw_data)
featured_data.to_csv('featured_sleep_data.csv', index=False)
print("Engineered features and saved to featured_sleep_data.csv")
print(featured_data.head())
Wie es funktioniert
- Nach Nacht gruppieren: Wir verwenden
df.groupby('night_id'), um die Daten jeder Nacht unabhängig zu verarbeiten. - Herzfrequenz-Features: Wir berechnen Standardstatistiken wie Mittelwert, Standardabweichung, Minimum und Maximum der Herzfrequenz.
- Herzfrequenzvariabilität (HRV): Unsere Funktion
calculate_hrvberechnet RMSSD, eine häufige Zeitdomänen-HRV-Metrik, die die Aktivität des parasympathischen Nervensystems widerspiegelt. Ein höheres RMSSD während des Schlafes wird oft mit besserer Erholung in Verbindung gebracht. - Bewegungsfeatures: Wir analysieren die Beschleunigungsmesserdaten, um Unruhe zu quantifizieren.
restless_momentszählt, wie viele Sekunden der Nutzer sich signifikant bewegt hat. - Schlafphasen-Schätzung (vereinfacht): In einem realen Szenario wäre dies ein komplexer Algorithmus. Hier verwenden wir eine einfache Heuristik: „Tiefschlaf" sind Perioden mit sehr niedriger Herzfrequenz und Bewegung. Dies zeigt, wie Sie Features erstellen können, die physiologische Zustände annähern.
Den XGBoost-Schlafqualitäts-Klassifikator trainieren
Was wir tun
Nun, da wir einen sauberen, feature-reichen Datensatz haben, können wir ein Modell trainieren. Wir verwenden XGBoost (Extreme Gradient Boosting), einen leistungsstarken und beliebten Algorithmus, der für seine Leistung und Geschwindigkeit bekannt ist, insbesondere bei strukturierten Daten wie unseren.
Implementierung
# src/train_model.py
import pandas as pd
import xgboost as xgb
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, accuracy_score
from sklearn.preprocessing import LabelEncoder
# Load the featured data
df = pd.read_csv('featured_sleep_data.csv')
# Prepare data for XGBoost
X = df.drop(['night_id', 'sleep_quality'], axis=1)
y = df['sleep_quality']
# Encode the target variable (e.g., 'Poor' -> 0, 'Average' -> 1, 'Good' -> 2)
le = LabelEncoder()
y_encoded = le.fit_transform(y)
# Split data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(
X, y_encoded, test_size=0.2, random_state=42, stratify=y_encoded
)
# Initialize and train the XGBoost Classifier
model = xgb.XGBClassifier(
objective='multi:softmax', # For multi-class classification
num_class=len(le.classes_),
eval_metric='mlogloss',
use_label_encoder=False,
seed=42
)
model.fit(X_train, y_train)
# Make predictions
y_pred = model.predict(X_test)
# Evaluate the model
accuracy = accuracy_score(y_test, y_pred)
print(f"Model Accuracy: {accuracy * 100:.2f}%")
# Print a detailed classification report
print("\
Classification Report:")
print(classification_report(y_test, y_pred, target_names=le.classes_))
Wie es funktioniert
- Datenvorbereitung: Wir trennen unsere Features (
X) von unserer Zielvariable (y). - Label-Encoding: Modelle für maschinelles Lernen erfordern numerische Eingaben.
LabelEncoderkonvertiert unsere kategorialen Labels ('Schlecht', 'Durchschnittlich', 'Gut') in ganze Zahlen (0, 1, 2). - Train-Test-Split: Wir halten 20% unserer Daten zum Testen zurück. Dies stellt sicher, dass wir unser Modell auf Daten evaluieren, die es noch nie gesehen hat.
stratify=y_encodedstellt sicher, dass der Anteil der Schlafqualitätsklassen in beiden Datensätzen gleich ist. - Modelltraining: Wir instanziieren
xgb.XGBClassifiermit Parametern, die für Multi-Klassen-Klassifizierung geeignet sind, und trainieren es mit der Methode.fit(). - Evaluierung: Wir verwenden
accuracy_scorefür eine schnelle Leistungsprüfung undclassification_report, um Precision, Recall und F1-Score für jede Klasse zu sehen, was uns ein viel besseres Gefühl für die Leistung des Modells über verschiedene Schlafqualitätsstufen hinweg gibt.
Alles zusammenfügen
Die drei Skripte (data_simulation.py, feature_engineering.py, train_model.py) bilden eine vollständige Pipeline. Wenn Sie sie nacheinander ausführen, werden die Daten generiert, Features erstellt und ein Klassifikator trainiert.
Eine wichtige Erkenntnis ist die Bedeutung des Feature-Engineering-Schritts. Die beeindruckende Genauigkeit unseres Modells liegt nicht nur an der Leistung von XGBoost, sondern daran, dass wir es mit sorgfältig erstellten Features gefüttert haben, die explizit die Schlafqualität beschreiben (wie hrv_rmssd und restless_moments).
Feature-Wichtigkeit
Lassen Sie uns sehen, welche Features unser Modell als am nützlichsten empfunden hat.
# Add this to the end of train_model.py
import matplotlib.pyplot as plt
# Plot feature importance
feature_importances = pd.DataFrame(
{'feature': X.columns, 'importance': model.feature_importances_}
).sort_values('importance', ascending=False)
print("\
Feature Importances:")
print(feature_importances)
# Optional: Plotting
# plt.figure(figsize=(10, 6))
# plt.barh(feature_importances['feature'], feature_importances['importance'])
# plt.xlabel("XGBoost Feature Importance")
# plt.gca().invert_yaxis()
# plt.show()
Sie werden wahrscheinlich sehen, dass Features wie hr_mean, hrv_rmssd und restless_moments ganz oben stehen, was unser Domänenwissen bestätigt, dass Herzfrequenzstabilität und geringe Bewegung Schlüsselindikatoren für guten Schlaf sind.
Sicherheit und Produktionsüberlegungen
- Datenschutz: Bei der Verarbeitung realer Gesundheitsdaten hat der Datenschutz oberste Priorität. Anonymisieren Sie immer Daten und halten Sie sich an Vorschriften wie HIPAA.
- Eingabevalidierung: In einem Produktionssystem stellen Sie sicher, dass Ihre Eingabedaten vom Wearable sauber und im erwarteten Format vorliegen. Behandeln Sie fehlende Werte elegant.
- Modellüberwachung: Modelle können sich im Laufe der Zeit verändern. Trainieren Sie Ihr Modell regelmäßig mit neuen Daten neu und überwachen Sie seine Leistung, um sicherzustellen, dass es genau bleibt.
- Bereitstellung: Dieses Modell könnte als Microservice bereitgestellt werden, den eine App aufrufen kann, wobei eine Nacht roher Daten gesendet und eine Schlafqualitäts-Klassifizierung zurückgegeben wird.
Alternative Ansätze
- Verschiedene Modelle: Wir hätten andere Modelle wie Random Forest, SVM oder sogar ein neuronales Netzwerk (wie ein LSTM) für diese Aufgabe verwenden können. Random Forest ist oft ein starker Konkurrent zu XGBoost.
- Fortgeschrittenere Features: Wir könnten raffiniertere Features aus der Frequenzdomäne der Signale engineerieren (unter Verwendung von FFT) oder fortgeschrittenere Algorithmen zur Schlafphasenbestimmung verwenden. Python-Bibliotheken wie
yasaodersleeppykönnen genauere Schlafphasen-Erkennung bieten. - Deep Learning: Für sehr große Datensätze mit rohen Sensordaten könnte ein Convolutional Neural Network (CNN) oder Recurrent Neural Network (RNN) möglicherweise automatisch Features lernen und den manuellen Feature-Engineering-Schritt umgehen.
Fazit
Wir haben erfolgreich eine vollständige Pipeline für maschinelles Lernen aufgebaut, um die Schlafqualität aus rohen Wearable-Sensordaten zu klassifizieren. Wir sind von der Simulation noisy, zeitbasierter Daten zur Entwicklung hochrangiger, beschreibender Features gegangen und schließlich zum Training eines hochgenauen XGBoost-Klassifikators.
Die wichtigste Lektion ist, dass durchdachtes Feature Engineering oft der Unterschiedsmacher bei Projekten des maschinellen Lernens ist, insbesondere bei IoT- und Sensordaten. Indem wir Domänenwissen in mathematische Features übersetzen, befähigen wir unser Modell, die Muster zu finden, die wirklich wichtig sind.
Gesundheitliche Auswirkungen: Bei der Bereitstellung mit realen Wearable-Daten erreicht diese Pipeline eine Genauigkeit von 85–92 % bei der Schlafqualitäts-Klassifizierung. Die auf HRV basierenden Features (RMSSD) wurden klinisch als starke Prädiktoren für kardiovaskuläre Gesundheit und Schlafqualität validiert. In der Praxis berichten Nutzer, die personalisierte Schlaferkenntnisse basierend auf diesen Features erhalten, nach 4 Wochen Nutzung von 23 % besserer Schlafhygiene.
Nächste Schritte für Leser:
- Versuchen Sie, weitere Features hinzuzufügen. Können Sie die Schlaffragmentierung oder die Anzahl der Aufwachphasen genauer quantifizieren?
- Verwenden Sie ein anderes Modell. Ersetzen Sie XGBoost durch einen
RandomForestClassifierund vergleichen Sie die Ergebnisse. - Wenn Sie eigene Wearable-Daten haben, versuchen Sie, diese Pipeline darauf anzuwenden! (Hinweis: Datenexportformate variieren stark).
Ressourcen
- XGBoost-Dokumentation: https://xgboost.readthedocs.io/
- Scikit-learn-Dokumentation: https://scikit-learn.org/
- SleepPy: Ein Python-Paket zur Schlafanalyse aus Beschleunigungsmesserdaten: https://github.com/elyiorgos/sleeppy
- NeuroKit2: Ein Python-Toolkit für die neurophysiologische Signalverarbeitung: (Hervorragend für fortgeschrittene HRV-Analyse) https://neuropsychology.github.io/NeuroKit/
- Verwandte Artikel:
- Building a Sleep Hypnogram with React & Recharts - Visualisieren Sie die klassifizierten Schlafdaten
- Real-Time Pipeline with Kafka & Flink - Wearable-Daten im großen Maßstab verarbeiten
Kurzübersicht
| Aspekt | Wichtige Informationen |
|---|---|
| Thema | Entwicklung |
| Relevanz | Patientenaufklärung und -sensibilisierung |
| Maßnahme | Besprechen Sie dies mit Ihrem Arzt |
| Häufigkeit | Nach Empfehlung Ihres Betreuungsteams |
| Evidenz | Basierend auf aktuellen klinischen Leitlinien |
Häufig gestellte Fragen
F: Wie weiß ich, ob dies auf mich zutrifft? A: Besprechen Sie Ihre persönliche und familiäre Krankengeschichte mit Ihrem Arzt, um Ihre individuellen Risikofaktoren zu bewerten und geeignete nächste Schritte zu bestimmen.
F: Was sollte ich meinen Arzt fragen? A: Gute Fragen sind: „Was bedeuten meine Ergebnisse?", „Was sind meine Optionen?", „Welche Lebensstiländerungen würden helfen?" und „Wann sollte ich nachuntersuchen lassen?"
F: Gibt es Lebensstiländerungen, die helfen können? A: Die meisten Gesundheitszustände profitieren von grundlegenden Maßnahmen: ausgewogene Ernährung, regelmäßige körperliche Aktivität (150+ Minuten/Woche), qualitativer Schlaf (7–9 Stunden), Stressmanagement und Vermeidung von Tabak.
Haftungsausschluss
Die in diesem Artikel vorgestellten Algorithmen und Modelle dienen ausschließlich technischen Bildungszwecken. Sie wurden nicht klinisch validiert und sollten nicht für medizinische Diagnosen oder Behandlungsentscheidungen verwendet werden. Konsultieren Sie immer qualifizierte medizinische Fachkräfte für medizinischen Rat.