Chronotypen mit Python und Clustering entdecken
Erfahren Sie, wie K-Means und DBSCAN in Python Nutzer aus Schlafdaten in Chronotypen wie Nachteulen und Frühaufsteher segmentieren.
Auf dieser Seite
Sind Sie eine Nachteule, die nach Mitternacht aufblüht, oder eine Frühaufsteherin bzw. ein Frühaufsteher, die bzw. der im Morgengrauen am produktivsten ist? Diese natürlichen Neigungen werden als Chronotypen bezeichnet und beeinflussen unser Leben erheblich, von der Arbeitsleistung bis zur Gesundheit. Was wäre, wenn wir diese Muster automatisch aus Schlafdaten von Nutzerinnen und Nutzern erkennen könnten?
In diesem ausführlichen Beitrag gehen wir ein vollständiges Data-Science-Projekt durch, um Chronotypen von Nutzerinnen und Nutzern aus einem Datensatz mit Schlafzeiten zu ermitteln. Wir verwenden unüberwachte Clustering-Algorithmen, insbesondere K-Means und DBSCAN, um Nutzerinnen und Nutzer in aussagekräftige Gruppen wie „Frühaufsteher“, „Nachteulen“ und „Standardschläfer“ zu segmentieren.
Voraussetzungen: Sie sollten grundlegende Kenntnisse in Python und Vertrautheit mit der Datenbearbeitung mit Pandas mitbringen. Vorkenntnisse zu Konzepten des maschinellen Lernens sind hilfreich, aber nicht zwingend erforderlich. Sie benötigen Python 3 sowie die installierten Bibliotheken Pandas, Scikit-learn und Matplotlib.
Warum das für Entwicklerinnen und Entwickler wichtig ist: Das Verständnis des Nutzerverhaltens ist entscheidend, um personalisierte Erlebnisse zu schaffen. Bei Gesundheits- und Wellness-Apps kann die Segmentierung von Nutzerinnen und Nutzern nach Chronotyp maßgeschneiderte Empfehlungen für optimale Schlafpläne, Trainingszeiten und sogar Produktivitätstipps ermöglichen.
Hinweis: Dieses Beispiel verwendet synthetische bzw. simulierte Daten zur Demonstration. Stellen Sie in der Produktion sicher, dass alle Schlafdaten anonymisiert und im Einklang mit HIPAA/DSGVO verarbeitet werden.
Das Problem verstehen
Die manuelle Bestimmung von Chronotypen über Fragebögen kann subjektiv und zeitaufwendig sein. Unüberwachtes maschinelles Lernen bietet einen datengestützten Ansatz, um diese Muster aus passiv erhobenen Schlafdaten zu erkennen. Die größte Herausforderung besteht darin, rohe Schlafzeiten in aussagekräftige Merkmale umzuwandeln, die Clustering-Algorithmen wirksam nutzen können, um ähnliche Nutzerinnen und Nutzer zu gruppieren.
Wearable-Technologie und Gesundheits-Apps liefern heute große Mengen an Schlafdaten. Forschende und Unternehmen setzen zunehmend maschinelles Lernen ein, um diese Daten auf Erkenntnisse zu Schlafqualität und Schlafmustern zu analysieren. Statt uns auf selbstberichtete Angaben zu verlassen, verwenden wir objektive Daten zu den Schlafzeiten, um natürliche Nutzergruppen aufzudecken.
Architektur des Chronotyp-Clusterings
Das folgende Diagramm zeigt unsere Pipeline für unüberwachtes Lernen zur Erkennung von Nutzerchronotypen:
Voraussetzungen
Erforderliche Werkzeuge/Bibliotheken:
- Python 3.x
- Pandas
- Scikit-learn
- Matplotlib
- Seaborn
Hinweise zur Versionskompatibilität: Der Code in diesem Tutorial wurde mit Python 3.8, Pandas 1.3, Scikit-learn 1.0, Matplotlib 3.5 und Seaborn 0.11 geschrieben. Kleinere Versionsunterschiede sollten keine Probleme verursachen.
Führen Sie den folgenden Befehl in Ihrem Terminal aus, um die erforderlichen Bibliotheken zu installieren:
pip install pandas scikit-learn matplotlib seaborn
Schlafzeitdaten laden und vorverarbeiten
Was wir tun
Zuerst müssen wir unseren Datensatz laden und ihn für das Feature Engineering vorbereiten. Wir verwenden einen synthetischen Datensatz „Student Sleep Patterns“ von Kaggle, der sich für unsere Analyse eignet, da er Schlaf- und Aufwachzeiten an Werktagen und am Wochenende enthält. Wir bereinigen die Daten, behandeln Unstimmigkeiten und wandeln Zeitformate in eine besser nutzbare Form um.
Umsetzung
# src/data_preprocessing.py
import pandas as pd
# Load the dataset
try:
df = pd.read_csv('student_sleep_patterns.csv')
except FileNotFoundError:
print("Please download the dataset from: https://www.kaggle.com/datasets/ssooni/student-sleep-patterns-dataset")
exit()
# Display the first few rows and basic info
print("Original DataFrame head:")
print(df.head())
print("\
DataFrame Info:")
df.info()
# For this analysis, we are interested in the sleep timing columns
sleep_timing_df = df[['Student_ID', 'Weekday_Sleep_Start', 'Weekday_Sleep_End', 'Weekend_Sleep_Start', 'Weekend_Sleep_End']].copy()
print("\
Sleep Timing DataFrame head:")
print(sleep_timing_df.head())
So funktioniert es
Wir laden die CSV-Datei in ein Pandas-DataFrame. Die Funktion .head() zeigt uns die ersten Zeilen, um die Struktur zu verstehen, und .info() gibt einen Überblick über die Datentypen und die nicht fehlenden Werte. Anschließend erstellen wir ein neues DataFrame sleep_timing_df, das nur die für unsere Chronotyp-Analyse relevanten Spalten enthält.
Häufige Fallstricke
- Datei nicht gefunden: Stellen Sie sicher, dass sich die CSV-Datei im selben Verzeichnis wie Ihr Python-Skript befindet, oder geben Sie den korrekten Dateipfad an.
- Uneinheitliche Zeitformate: In realen Daten können Zeitformate unübersichtlich sein (z. B. „10:00 PM“, „22:00“, „10pm“). Unser Datensatz verwendet ein 24-Stunden-Gleitkommaformat, was die Verarbeitung vereinfacht. Bei anderen Formaten müssen Sie möglicherweise
pd.to_datetimeverwenden.
Schlafmerkmale für das Clustering erstellen
Was wir tun
Um Nutzerinnen und Nutzer nach Chronotyp zu clustern, müssen wir Merkmale erzeugen, die ihr Schlafverhalten abbilden. Zwei der wirksamsten Merkmale dafür sind:
- Schlafmittelpunkt: Der Mittelpunkt zwischen Zubettgehzeit und Aufwachzeit. Dies ist ein starker Indikator für den natürlichen Schlafrhythmus einer Person.
- Schlafdauer: Die insgesamt im Schlaf verbrachte Zeit.
Wir berechnen diese Werte sowohl für Werktage als auch für Wochenenden, um Verhaltensunterschiede zu erfassen.
Eingabe: DataFrame mit den Spalten Weekday_Sleep_Start, Weekday_Sleep_End, Weekend_Sleep_Start, Weekend_Sleep_End
Ausgabe: DataFrame mit den erzeugten Merkmalen Weekday_Midpoint, Weekday_Duration, Weekend_Midpoint, Weekend_Duration
Umsetzung
# src/feature_engineering.py
import numpy as np
def calculate_sleep_features(df):
"""Calculates midpoint of sleep and sleep duration."""
features_df = df.copy()
for period in ['Weekday', 'Weekend']:
start_col = f'{period}_Sleep_Start'
end_col = f'{period}_Sleep_End'
# Convert times to hours from midnight
start_time = features_df[start_col]
end_time = features_df[end_col]
# Handle overnight sleep
duration = np.where(end_time > start_time,
end_time - start_time,
(24 - start_time) + end_time)
midpoint = (start_time + duration / 2) % 24
features_df[f'{period}_Duration'] = duration
features_df[f'{period}_Midpoint'] = midpoint
return features_df
features_df = calculate_sleep_features(sleep_timing_df)
print("\
DataFrame with Engineered Features:")
print(features_df.head())
So funktioniert es
- Sowohl für „Weekday“ als auch für „Weekend“ berechnen wir die Schlafdauer. Wir müssen berücksichtigen, dass der Schlaf über Mitternacht hinausgehen kann. Ist
end_timekleiner alsstart_time, bedeutet das, dass die Person am nächsten Tag aufgewacht ist. In diesem Fall beträgt die Dauer(24 - start_time) + end_time. - Der
midpointdes Schlafs wird berechnet, indem die halbe Dauer zur Startzeit addiert wird. Wir verwenden den Modulo-Operator (% 24), damit der Mittelpunkt innerhalb einer 24-Stunden-Uhr bleibt.
Häufige Fallstricke
- Übernachtspannen ignorieren: Ein einfaches
end_time - start_timeergibt bei Schlaf über Nacht eine negative Dauer. Die Funktionnp.whereist eine saubere Möglichkeit, diese bedingte Logik zu behandeln.
Nutzerinnen und Nutzer mit dem K-Means-Algorithmus clustern
Was wir tun
K-Means ist ein beliebter Clustering-Algorithmus, der Datenpunkte in eine vordefinierte Anzahl von Clustern (k) gruppiert. Er ist ein guter Ausgangspunkt für die Erkennung von Chronotypen. Wir verwenden die „Elbow-Methode“, um die optimale Clusterzahl zu bestimmen, und passen anschließend das K-Means-Modell an unsere erzeugten Merkmale an.
Eingabe: Merkmalsmatrix X mit den Spalten [Weekday_Midpoint, Weekday_Duration, Weekend_Midpoint, Weekend_Duration]
Ausgabe: Clusterzuordnungen (0, 1, 2) für jede Nutzerin bzw. jeden Nutzer, die ihren Chronotyp darstellen
Umsetzung
# src/kmeans_clustering.py
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot as plt
import seaborn as sns
# Select features for clustering
X = features_df[['Weekday_Midpoint', 'Weekday_Duration', 'Weekend_Midpoint', 'Weekend_Duration']]
# Scale the features
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# Elbow method to find the optimal k
inertia = []
K = range(1, 11)
for k in K:
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
kmeans.fit(X_scaled)
inertia.append(kmeans.inertia_)
plt.figure(figsize=(8, 5))
plt.plot(K, inertia, 'bx-')
plt.xlabel('Number of clusters (k)')
plt.ylabel('Inertia')
plt.title('Elbow Method For Optimal k')
plt.show()
# Based on the elbow plot, let's choose k=3
k = 3
kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)
features_df['KMeans_Cluster'] = kmeans.fit_predict(X_scaled)
print("\
DataFrame with K-Means Clusters:")
print(features_df.head())
# Visualize the clusters
plt.figure(figsize=(10, 6))
sns.scatterplot(data=features_df, x='Weekday_Midpoint', y='Weekend_Midpoint', hue='KMeans_Cluster', palette='viridis', s=100)
plt.title('Chronotype Clusters (K-Means)')
plt.xlabel('Weekday Sleep Midpoint')
plt.ylabel('Weekend Sleep Midpoint')
plt.legend(title='Cluster')
plt.show()
So funktioniert es
- Merkmalsskalierung: Wir verwenden
StandardScaler, um unsere Merkmale zu normalisieren. Das ist bei distanzbasierten Algorithmen wie K-Means wichtig, da so verhindert wird, dass Merkmale mit größeren Skalen den Clustering-Prozess dominieren. - Elbow-Methode: Wir berechnen die Inertia (Summe der quadrierten Abstände der Stichproben zu ihrem nächstgelegenen Clusterzentrum) für verschiedene Werte von
k. Der „Ellenbogen“ in der Grafik, an dem die Abnahme der Inertia langsamer wird, deutet auf die optimale Clusterzahl hin. Bei diesen Daten liegt sie bei etwak=3. - Clustering und Visualisierung: Wir passen das K-Means-Modell mit
k=3an und schreiben die Clusterlabels in unser DataFrame zurück. Das Streudiagramm hilft uns, die resultierenden Cluster anhand der Schlafmittelpunkte an Werktagen und am Wochenende zu visualisieren.
Häufige Fallstricke
- Vergessen, Merkmale zu skalieren: Das kann zu verzerrten Clustern führen, wenn sich die Merkmalsskalen stark unterscheiden.
- Den Ellenbogen falsch deuten: Manchmal ist der Ellenbogen nicht sehr deutlich. In solchen Fällen müssen Sie möglicherweise andere Methoden wie den Silhouette-Score verwenden oder sich bei der Wahl von
kauf Fachwissen stützen.
Ausreißer mit DBSCAN-Clustering erkennen
Was wir tun
DBSCAN (Density-Based Spatial Clustering of Applications with Noise) ist ein weiterer leistungsfähiger Clustering-Algorithmus, der Cluster beliebiger Formen erkennen kann und zudem robust gegenüber Ausreißern ist. Im Gegensatz zu K-Means müssen wir die Clusterzahl nicht im Voraus festlegen. Das kann sehr nützlich sein, wenn wir nicht wissen, wie viele natürliche Gruppen in den Daten vorhanden sind.
Eingabe: Skalierte Merkmalsmatrix X_scaled
Ausgabe: Clusterzuordnungen, wobei -1 Rausch- bzw. Ausreißerpunkte kennzeichnet
Umsetzung
# src/dbscan_clustering.py
from sklearn.cluster import DBSCAN
# Using the same scaled features
dbscan = DBSCAN(eps=0.5, min_samples=5)
features_df['DBSCAN_Cluster'] = dbscan.fit_predict(X_scaled)
print("\
DataFrame with DBSCAN Clusters:")
print(features_df.head())
print("\
DBSCAN Cluster Counts:")
print(features_df['DBSCAN_Cluster'].value_counts())
# Visualize the clusters
plt.figure(figsize=(10, 6))
sns.scatterplot(data=features_df, x='Weekday_Midpoint', y='Weekend_Midpoint', hue='DBSCAN_Cluster', palette='viridis', s=100)
plt.title('Chronotype Clusters (DBSCAN)')
plt.xlabel('Weekday Sleep Midpoint')
plt.ylabel('Weekend Sleep Midpoint')
plt.legend(title='Cluster')
plt.show()
So funktioniert es
- DBSCAN-Parameter: DBSCAN hat zwei Hauptparameter:
eps(die maximale Entfernung zwischen zwei Stichproben, damit die eine als in der Nachbarschaft der anderen gilt) undmin_samples(die Anzahl der Stichproben in einer Nachbarschaft, damit ein Punkt als Kernpunkt gilt). Die Abstimmung dieser Parameter kann schwierig sein und etwas Experimentieren erfordern. - Rauscherkennung: DBSCAN kennzeichnet Rauschpunkte mit -1. Das ist ein wesentlicher Vorteil, da sich so Ausreißer isolieren lassen, die zu keinem Cluster gehören.
Häufige Fallstricke
- Parameterabstimmung: Die Leistung von DBSCAN reagiert empfindlich auf
epsundmin_samples. Schlechte Entscheidungen können dazu führen, dass alle Punkte in einem Cluster liegen oder alle Punkte als Rauschen gekennzeichnet werden. Möglicherweise müssen Sie mit verschiedenen Werten experimentieren, um aussagekräftige Ergebnisse zu erhalten.
Alles zusammenführen
Analysieren und interpretieren wir die gefundenen Cluster. Wir können unser DataFrame nach den Clusterlabels gruppieren und die Mittelwerte unserer Merkmale für jede Gruppe betrachten.
# src/analyze_clusters.py
# Analyze K-Means clusters
kmeans_summary = features_df.groupby('KMeans_Cluster')[['Weekday_Midpoint', 'Weekend_Midpoint', 'Weekday_Duration', 'Weekend_Duration']].mean()
print("\
K-Means Cluster Summary:")
print(kmeans_summary)
# Analyze DBSCAN clusters
dbscan_summary = features_df[features_df['DBSCAN_Cluster'] != -1].groupby('DBSCAN_Cluster')[['Weekday_Midpoint', 'Weekend_Midpoint', 'Weekday_Duration', 'Weekend_Duration']].mean()
print("\
DBSCAN Cluster Summary:")
print(dbscan_summary)
Die K-Means-Cluster interpretieren: Auf Grundlage der Ausgabe der K-Means-Zusammenfassung finden wir möglicherweise drei unterschiedliche Gruppen:
- Cluster 0: Frühaufsteher: Niedrige Mittelpunkte an Werktagen und am Wochenende (z. B. etwa 3–4 Uhr morgens), was darauf hindeutet, dass sie durchgängig früh zu Bett gehen und früh aufstehen.
- Cluster 1: Nachteulen: Hohe Mittelpunkte an Werktagen und am Wochenende (z. B. etwa 6–7 Uhr morgens), was eine Vorliebe für spätere Schlafzeiten anzeigt.
- Cluster 2: Standardschläfer: Mittelpunkte zwischen den beiden anderen Gruppen, die einen eher typischen Schlafrhythmus darstellen.
Alternative Ansätze
- Hierarchisches Clustering: Dieses Verfahren erzeugt einen Baum von Clustern und kann nützlich sein, um zu visualisieren, wie Gruppen ineinander verschachtelt sind. Es erfordert keine vordefinierte Clusterzahl, aber Sie müssen entscheiden, wo Sie den Baum „schneiden“.
- Gaussian Mixture Models (GMM): GMMs sind ein probabilistisches Modell, das davon ausgeht, dass die Datenpunkte aus einer Mischung einer endlichen Anzahl von Gauß-Verteilungen erzeugt werden. Das kann flexibler sein als K-Means, da Cluster möglich sind, die nicht kugelförmig sind.
Fazit
- Zusammenfassung der Ergebnisse: Wir haben erfolgreich eine durchgängige Pipeline aufgebaut, um Nutzerchronotypen aus Schlafzeitdaten zu erkennen. Wir haben die Daten bereinigt, aussagekräftige Merkmale erzeugt und zwei verschiedene unüberwachte Clustering-Algorithmen, K-Means und DBSCAN, angewendet, um Nutzerinnen und Nutzer in unterschiedliche Gruppen zu segmentieren.
- Nächste Schritte für Leserinnen und Leser: Versuchen Sie, diese Methodik auf einen anderen Verhaltensdatensatz anzuwenden. Sie könnten auch mit anderen Clustering-Algorithmen experimentieren oder zusätzliche Merkmale erzeugen, etwa den Unterschied zwischen Schlafmustern an Werktagen und am Wochenende (ein Indikator für „sozialen Jetlag“).
- Handlungsaufforderung: Probieren Sie den Code aus und sehen Sie, was Sie in Ihren eigenen Daten entdecken können! Teilen Sie Ihre Ergebnisse oder interessante Änderungen, die Sie vorgenommen haben, in den Kommentaren unten.
Quellen
- Offizielle Dokumentation:
- Weiterführende Literatur:
Kurzüberblick
| Aspekt | Wichtige Informationen |
|---|---|
| Thema | Data Science |
| Relevanz | Patientenaufklärung und Bewusstsein |
| Maßnahme | Besprechen Sie dies mit Ihrer Ärztin oder Ihrem Arzt |
| Häufigkeit | Wie von Ihrem Behandlungsteam empfohlen |
| Evidenz | Auf Grundlage aktueller klinischer Leitlinien |
Häufig gestellte Fragen
F: Woran erkenne ich, ob das auf mich zutrifft? A: Besprechen Sie Ihre persönliche und familiäre Krankengeschichte mit Ihrer Ärztin oder Ihrem Arzt, um Ihre individuellen Risikofaktoren zu beurteilen und geeignete nächste Schritte festzulegen.
F: Was sollte ich meine Ärztin oder meinen Arzt fragen? A: Gute Fragen sind: „Was bedeuten meine Ergebnisse?“, „Welche Möglichkeiten habe ich?“, „Welche Lebensstiländerungen würden helfen?“ und „Wann sollte ich zur Nachkontrolle kommen?“
F: Gibt es Lebensstiländerungen, die helfen können? A: Den meisten Erkrankungen kommen grundlegende Maßnahmen zugute: ausgewogene Ernährung, regelmäßige körperliche Aktivität (150+ Minuten/Woche), erholsamer Schlaf (7–9 Stunden), Stressbewältigung und Verzicht auf Tabak.
Medizinischer Haftungsausschluss
Dieser Artikel dient ausschließlich Bildungszwecken und stellt keine medizinische Beratung dar. Konsultieren Sie stets eine qualifizierte Ärztin oder einen qualifizierten Arzt, bevor Sie Entscheidungen über Ihre Gesundheit, Behandlung oder Versorgung treffen. Individuelle Umstände unterscheiden sich, und was für eine Person angemessen ist, muss für eine andere nicht angemessen sein.
Wenn Sie einen medizinischen Notfall erleben, rufen Sie sofort 911 (oder Ihre örtliche Notrufnummer) an.