Электроэнцефалография (ЭЭГ) — это неинвазивный метод регистрации электрической активности мозга через электроды на поверхности головы. За последние годы ЭЭГ-данные перестали быть исключительно медицинской прерогативой и прочно вошли в мир 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 и научных публикаций в области нейроинформатики.
