Sleep Stage Classification (EEG)

Pream J
5 min readNov 3, 2023

--

Sleep is a fundamental and complex physiological process that plays a vital role in human life. Sleep significantly impacts physical well-being, and overall quality of life.

1 Introduction

Sleep state classification involves the categorization of various stages of sleep experienced by individuals during their rest. These sleep stages are predominantly classified into two main categories: Rapid Eye Movement (REM) and Non-Rapid Eye Movement (NREM) sleep. Each stage is associated with distinct physiological characteristics, brain activities, and varying depths of restfulness.

  • Wakefulness (W): This initial state encompasses the period when an individual is fully awake and alert. Brain activity during wakefulness shows high-frequency beta waves, often associated with conscious awareness and cognitive engagement.

Non-Rapid Eye Movement (NREM) Sleep:

  • Stage N1 (Light Sleep): As the body begins to transition from wakefulness to sleep, stage N1 sets in. This stage is characterized by slow eye movements and a decreased awareness of the external environment. Brainwaves slow down, marking the onset of sleep.
  • Stage N2 (True Sleep): N2 is a deeper state of sleep where the body continues to relax, and brain activity exhibits specific patterns like sleep spindles and K-complexes.
  • Stage N3 (Deep Sleep): Stage N3 is the deepest and most restorative phase. It is characterized by the presence of slow delta waves. Physical restoration, growth, and immune function are believed to occur predominantly during this phase.

Rapid Eye Movement (REM) Sleep:

  • REM Sleep: This stage is marked by rapid eye movements, vivid dreams, and heightened brain activity. It is associated with the consolidation of memories, emotional processing, and learning. Muscles are largely paralyzed during REM sleep, allowing the brain to disconnect from the body while remaining highly active.

Dataset

Dataset: Alvarez-Estevez, D., & Rijsman, R. (2022). Haaglanden Medisch Centrum sleep staging database (version 1.1). PhysioNet. https://doi.org/10.13026/t79q-fr32.

A collection of 151 whole-night polysomnographic (PSG) sleep recordings (85 Male, 66 Female, mean Age of 53.9 ± 15.4) collected during 2018 at the Haaglanden Medisch Centrum (HMC, The Netherlands) sleep center. Patient recordings were randomly selected and include a heterogeneous population which was referred for PSG examination on the context of different sleep disorders. The dataset contains electroencephalographic (EEG), electrooculographic (EOG), chin electromyographic (EMG), and electrocardiographic (ECG) activity, as well as event annotations corresponding to scoring of sleep patterns (hypnogram) performed by sleep technicians at HMC. The dataset was collected as part of a study evaluating the generalization performance of an automatic sleep scoring algorithm across multiple heterogeneous datasets.

Methods

1. Load data
Data is stored in the EDF format, and the MNE library is utilized for its reading and processing.

import mne
raw = mne.io.read_raw_edf('recordings/SN001.edf', preload=True)
print(raw.ch_names)
'''
['EEG F4-M1', 'EEG C4-M1', 'EEG O2-M1', 'EEG C3-M2', 'EMG chin', 'EOG E1-M2', 'EOG E2-M2', 'ECG']
'''

We will exclusively utilize EEG data, thereby excluding other non-essential data from our analysis or processing.

raw.drop_channels(['EMG chin', 'EOG E1-M2', 'EOG E2-M2', 'ECG'])
chan = raw.ch_names
print(chan)
'''
['EEG F4-M1', 'EEG C4-M1', 'EEG O2-M1', 'EEG C3-M2']
'''

Subsequently, we proceed to read the annotation file, extracting its contents and storing the acquired information in a Pandas Dataframe for further analysis and manipulation.

import pandas as pd
annotation = pd.read_csv("/content/drive/MyDrive/Sleeping/recordings/SN001_sleepscoring.txt", squeeze=True)
annotation = annotation.iloc[:, 4]
annotation
'''
0 Sleep stage W
1 Sleep stage W
2 Lights off
3 Sleep stage W
4 Sleep stage W
...
851 Sleep stage W
852 Sleep stage W
853 Sleep stage W
854 Sleep stage W
855 Lights on
'''

2. Sleep Staging

We employ YASA (Yet Another Spindle Algorithm) , a library package, to assist in the processes related to the EEG data analysis and manipulation.

import yasa
yasa.plot_hypnogram(annotation);
yasa.sleep_statistics(hypno2, sf_hyp=1/30) #sf_hyp is recorded every 30 sec -> 30 Hz
'''
{'TIB': 428.0,
'SPT': 418.0,
'WASO': 66.5,
'TST': 351.5,
'N1': 54.5,
'N2': 215.0,
'N3': 11.5,
'REM': 70.5,
'NREM': 281.0,
'SOL': 4.5,
'Lat_N1': 4.5,
'Lat_N2': 8.5,
'Lat_N3': 53.0,
'Lat_REM': 78.0,
'%N1': 15.5049786628734,
'%N2': 61.16642958748222,
'%N3': 3.271692745376956,
'%REM': 20.056899004267425,
'%NREM': 79.94310099573258,
'SE': 82.12616822429906,
'SME': 84.0909090909091}
'''

Calculate the sleep stages transition matrix

counts, probs = yasa.transition_matrix(hypno2)
probs.round(3)
'''

To Stage 0 1 2 3 4
From Stage
0 0.013 0.901 0.086 0.000 0.000 0.000
1 0.000 0.083 0.670 0.220 0.000 0.028
2 0.000 0.005 0.042 0.923 0.019 0.012
3 0.000 0.000 0.000 0.348 0.652 0.000
4 0.000 0.014 0.035 0.007 0.000 0.943
'''

EEG power in specific frequency bands

Spectral analysis quantifies the power (or amplitude) of the EEG signal in different frequency bands.

delta (0.5–4 Hz), theta (4–8 Hz), alpha (8–12 Hz), beta (12–30 Hz), and gamma (30–~100 Hz).

yasa.bandpower(raw)
'''
Delta Theta Alpha Sigma Beta Gamma TotalAbsPow FreqRes Relative
Chan
EEG F4-M1 0.753016 0.115520 0.067026 0.029862 0.030099 0.004476 141.649727 0.25 True
EEG C4-M1 0.678864 0.148338 0.089762 0.040867 0.037117 0.005051 91.792231 0.25 True
EEG O2-M1 0.716019 0.125976 0.072915 0.038143 0.039978 0.006970 82.225965 0.25 True
EEG C3-M2 0.698738 0.140163 0.083912 0.037986 0.034138 0.005063 87.296400 0.25 True
'''

We used yasa.SleepStaging, pre-trained classifiers from YASA.

Vallat, R., & Walker, M. P. (2021). An open-source, high-performance tool for automated sleep staging. Elife, 10. doi: https://doi.org/10.7554/eLife.70092

def predict(eeg_name):
sls = yasa.SleepStaging(raw, eeg_name=eeg_name)
hypno_pred = sls.predict()
hypno_pred = yasa.hypno_str_to_int(hypno_pred)
return hypno_pred
# ['EEG F4-M1', 'EEG C4-M1', 'EEG O2-M1', 'EEG C3-M2']
hypno_pred_F4_M1 = predict('EEG F4-M1')
yasa.plot_hypnogram(hypno_pred_F4_M1);
print(f"The accuracy is {100 * accuracy_score(hypno2, hypno_pred):.3f}%")
confustion_matrics = metrics.multilabel_confusion_matrix(hypno2, hypno_pred)
classification_report = metrics.classification_report(hypno2, hypno_pred)
classification_report

It has been determined that the highest channel in accuracy is EEG C3-M2, exhibiting an accuracy rate of 79.649%.

“Lastly, I would like to say thank you to Brain Code Camp and the exceptional TAs in Group B. Without their unwavering support, dedication, and expertise, this project wouldn’t have been possible. Their commitment and guidance have been instrumental in its success. Thank you.”

--

--

Pream J

Hi there! I'm a high school student who interested in programming.