Электроэнцефалография (ЭЭГ) — это неинвазивный метод регистрации электрической активности мозга через электроды на поверхности головы. За последние годы ЭЭГ-данные перестали быть исключительно медицинской прерогативой и прочно вошли в мир data science. Сегодня их используют в нейромаркетинге для оценки реакций на рекламу, в когнитивных исследованиях для измерения внимания и памяти, в разработке Brain-Computer Interface (BCI) и даже в спортивной аналитике.
Популярность ЭЭГ объясняется несколькими факторами:
Доступность: относительно недорогие портативные устройства (Emotiv, Muse, OpenBCI)
Безопасность: полностью неинвазивная процедура
Скорость: данные в реальном времени с миллисекундным разрешением
Открытость: сотни публичных датасетов на Kaggle, PhysioNet и других платформах
В этой статье я покажу, как работать с реальными EEG-датасетами из Kaggle — от загрузки сырых данных до обучения классификатора на Python.
Типы EEG-датасетов: что и зачем измеряют
Все наборы данных можно условно разделить на четыре категории по типу исследуемой активности.
1. Эмоциональные состояния
Типичные датасеты: DEAP, Feeling Emotions
Что измеряют: реакцию на аудиовизуальные стимулы (музыкальные клипы, видео)
Метки: emotional valence (позитив/негатив), arousal (возбуждение), dominance (доминирование)
DEAP — один из самых цитируемых наборов данных. 32 участника смотрели 40 музыкальных клипов по одной минуте, после чего оценивали свои эмоции. Данные включают 32 канала ЭЭГ и дополнительные физиологические сигналы (GSR, EOG, EMG).
В научных статьях на основе таких датасетов строят гибридные LSTM+CNN модели, достигающие точности до 97% (Sensors, 2025; Electronics, 2022).
2. Когнитивная нагрузка
Типичные датасеты: EEGMAT (Arithmetic Task), Cognitive Load
Что измеряют: мозговую активность при решении задач разной сложности
Применение: оценка стресса, усталости, концентрации внимания
Например, в EEGMAT 36 участников решали задачи на вычитание чисел. Данные размечены по уровню сложности и качеству выполнения ("хорошо справился" / "плохо справился"). Такие наборы используют для создания адаптивных обучающих систем и интерфейсов.
3. Моторное воображение (Motor Imagery)
Типичные датасеты: EEGBCI, BCI Competition IV
Что измеряют: нейронные паттерны при воображении движений
Применение: BCI-интерфейсы, нейропротезирование, реабилитация
Классическая задача: участник воображает движение левой или правой руки, не совершая его физически. Система должна определить намерение по сигналам моторной коры. EEGBCI содержит записи 109 участников с 64 каналами — идеальная отправная точка для экспериментов с BCI.
4. Медицинская диагностика
Типичные датасеты: Bonn Epilepsy Dataset, CHB-MIT Scalp EEG Database
Что измеряют: патологическую активность (эпилептические приступы, нарушения сна)
Применение: автоматическая детекция приступов, предиктивные модели
Bonn Epilepsy Dataset — абсолютная классика. 5 категорий по 100 одноканальных сегментов длиной 23.6 секунды: здоровые испытуемые, межприступные периоды, приступы. На его основе создано большинство Kaggle-проектов по эпилепсии.
Топ-5 датасетов для старта
Для практического знакомства с ЭЭГ-анализом рекомендую начать с этих наборов:
Датасет |
Каналы |
Участники |
Задача |
Сложность |
|---|---|---|---|---|
Bonn Epilepsy |
1 |
- |
Детекция приступов |
⭐ |
Feeling Emotions |
14 |
3 |
Распознавание эмоций |
⭐⭐ |
EEGBCI |
64 |
109 |
Motor imagery |
⭐⭐⭐ |
DEAP |
32 |
32 |
Эмоции (мультимодальный) |
⭐⭐⭐⭐ |
CHB-MIT |
23 |
24 |
Предиктивная эпилептология |
⭐⭐⭐⭐⭐ |
Практика: pipeline обработки ЭЭГ на Python
Теперь разберём полный цикл работы с данными — от сырого сигнала до обученной модели.
Шаг 1: Загрузка данных
Для CSV-файлов всё тривиально:
import pandas as pd
df = pd.read_csv('eeg_data.csv')
print(df.head())
print(f"Размерность: {df.shape}")
Медицинские форматы (EDF, FIF) требуют специализированной библиотеки MNE-Python:
import mne
# Загрузка EDF-файла
raw = mne.io.read_raw_edf('subject1.edf', preload=True)
# Информация о записи
print(raw.info)
print(f"Частота дискретизации: {raw.info['sfreq']} Гц")
print(f"Каналы: {raw.info['ch_names']}")
print(f"Длительность: {raw.times[-1]:.2f} сек")
# Быстрая визуализация
raw.plot(duration=5, n_channels=10, scalings='auto')
Важно: всегда визуализируйте сырые данные перед обработкой. Это помогает выявить артефакты, шумы и сбои в записи.
Шаг 2: Предобработка и фильтрация
ЭЭГ содержит множество помех: сетевой шум (50/60 Гц), артефакты моргания, мышечная активность. Стандартная практика — полосовая фильтрация в диапазоне 1–40 Гц:
# Полосовой фильтр
raw.filter(l_freq=1.0, h_freq=40.0, fir_design='firwin')
# Режекторный фильтр для сетевой наводки (50 Гц)
raw.notch_filter(freqs=50.0)
# Сравнение до/после
raw_orig.plot(start=0, duration=5, title="До фильтрации")
raw.plot(start=0, duration=5, title="После фильтрации")
Для удаления артефактов моргания и движений используют Independent Component Analysis (ICA):
from mne.preprocessing import ICA
# Обучение ICA
ica = ICA(n_components=20, random_state=42)
ica.fit(raw)
# Автоопределение компонент-артефактов
ica.exclude = [0, 1] # индексы компонент, связанных с морганием
ica.plot_components()
# Применение к данным
raw_clean = ica.apply(raw.copy())
Шаг 3: Извлечение признаков
Классический подход — спектральный анализ. Разделяем сигнал на частотные диапазоны:
Дельта (0.5–4 Гц): глубокий сон
Тета (4–8 Гц): медитация, сонливость
Альфа (8–12 Гц): расслабленное бодрствование
Бета (12–30 Гц): активное мышление
Гамма (30–100 Гц): концентрация, обработка информации
import numpy as np
from scipy.signal import welch
def extract_band_power(raw, band_freq):
"""Вычисление мощности в заданном диапазоне"""
sfreq = raw.info['sfreq']
data, times = raw[:]
# Периодограмма Уэлча
freqs, psd = welch(data, sfreq, nperseg=int(sfreq * 2))
# Интегрирование по диапазону
idx = np.logical_and(freqs >= band_freq[0], freqs <= band_freq[1])
band_power = np.trapz(psd[:, idx], freqs[idx], axis=1)
return band_power
# Извлечение для всех диапазонов
bands = {
'delta': (0.5, 4),
'theta': (4, 8),
'alpha': (8, 12),
'beta': (12, 30),
'gamma': (30, 45)
}
features = {}
for band_name, band_range in bands.items():
features[band_name] = extract_band_power(raw, band_range)
# Сборка в DataFrame
features_df = pd.DataFrame(features)
print(features_df.head())
Альтернативы: Common Spatial Patterns (CSP) для motor imagery задач, статистические характеристики (дисперсия, асимметрия, эксцесс), wavelet-преобразования.
Шаг 4: Обучение модели
Начинаем с простого — Random Forest:
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import classification_report, confusion_matrix
# Подготовка данных
X = features_df.values
y = labels # массив меток классов
# Нормализация
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# Разбиение на train/test
X_train, X_test, y_train, y_test = train_test_split(
X_scaled, y, test_size=0.2, random_state=42, stratify=y
)
# Обучение
clf = RandomForestClassifier(n_estimators=100, max_depth=10, random_state=42)
clf.fit(X_train, y_train)
# Кросс-валидация
cv_scores = cross_val_score(clf, X_train, y_train, cv=5, scoring='accuracy')
print(f"Cross-validation accuracy: {cv_scores.mean():.3f} ± {cv_scores.std():.3f}")
# Оценка на тесте
y_pred = clf.predict(X_test)
print(f"Test accuracy: {clf.score(X_test, y_test):.3f}")
print("\nClassification Report:")
print(classification_report(y_test, y_pred))
Для более сложных задач можно использовать глубокие сети:
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
# Для LSTM нужен 3D тензор (samples, timesteps, features)
X_reshaped = X_train.reshape((X_train.shape[0], X_train.shape[1], 1))
model = Sequential([
LSTM(64, return_sequences=True, input_shape=(X_train.shape[1], 1)),
Dropout(0.3),
LSTM(32),
Dropout(0.3),
Dense(16, activation='relu'),
Dense(len(np.unique(y)), activation='softmax')
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
history = model.fit(X_reshaped, y_train, epochs=50, batch_size=32, validation_split=0.2, verbose=1)
Шаг 5: Визуализация результатов
Матрица ошибок показывает, какие классы модель путает:
import matplotlib.pyplot as plt
import seaborn as sns
# Матрица ошибок
cm = confusion_matrix(y_test, y_pred)
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
xticklabels=['Класс 0', 'Класс 1'],
yticklabels=['Класс 0', 'Класс 1'])
plt.title('Матрица ошибок классификации')
plt.ylabel('Истинные метки')
plt.xlabel('Предсказанные метки')
plt.tight_layout()
plt.show()
Важность признаков (для Random Forest):
importances = clf.feature_importances_
indices = np.argsort(importances)[::-1]
plt.figure(figsize=(10, 6))
plt.bar(range(len(importances)), importances[indices])
plt.xticks(range(len(importances)),
[list(bands.keys())[i] for i in indices],
rotation=45)
plt.title('Важность частотных диапазонов')
plt.ylabel('Feature Importance')
plt.tight_layout()
plt.show()
Best practices и типичные ошибки
✅ Рекомендации
Используйте MNE-Python — де-факто стандарт для ЭЭГ-анализа в Python
Всегда визуализируйте — графики выявляют проблемы, невидимые в числах
Начинайте с простого — Random Forest на спектральных признаках часто даёт 85–90% точности
Следите за балансом классов — используйте stratified split и метрики вроде F1-score
Сохраняйте промежуточные результаты — reproducibility критична в науке
❌ Типичные ошибки
Игнорирование артефактов — моргания и движения создают амплитуды в сотни раз больше реальной ЭЭГ
Неправильная фильтрация — слишком узкая полоса убивает полезный сигнал
Data leakage — использование будущих данных для предсказания прошлого (особенно при работе с временными рядами)
Переобучение — сложные модели на маленьких датасетах (используйте кросс-валидацию)
Куда двигаться дальше
После освоения базовых техник открывается несколько путей развития:
Участие в соревнованиях
Harmful Brain Activity Classification — классификация приступов
Grasp-and-Lift EEG Detection — детекция движений
Продвинутые техники
Common Spatial Patterns (CSP) для BCI
Transfer learning с предобученными сетями
Attention mechanisms для выделения значимых временных окон
Real-time processing для онлайн-приложений
Реальные приложения
Разработка BCI-интерфейсов для людей с ограниченными возможностями
Системы мониторинга внимания водителей
Адаптивные образовательные платформы
Нейромаркетинговые исследования
Заключение
Анализ ЭЭГ-данных — это увлекательное пересечение нейронауки, обработки сигналов и машинного обучения. Kaggle предоставляет отличную площадку для экспериментов: сотни датасетов, активное комьюнити и возможность сразу применить теорию на практике.
Даже простая модель на правильно подготовленных данных способна показывать впечатляющие результаты. Главное — понимать природу сигнала, тщательно проводить предобработку и не забывать про воспроизводимость результатов.
Мозговая активность — это тоже данные. А значит, её можно анализировать, визуализировать и превращать в умные интерфейсы. Экспериментируйте, пробуйте разные подходы — и у вас всё получится!
Полезные ресурсы
Статьи: Sensors (2025), Electronics (2022) — примеры гибридных DL-моделей для ЭЭГ
BCI Competition — архив соревнований по BCI
GitHub-репозитории:
Материал подготовлен на основе анализа публичных датасетов Kaggle и научных публикаций в области нейроинформатики.