基于Python的脑电图(EEG)信号分析(1)

146 篇文章 0 订阅
5 篇文章 0 订阅

        在现代神经科学和生物医学工程领域,脑电图(EEG)信号分析是理解大脑活动和开发脑机接口的关键技术。本文将介绍如何使用Python、MNE和PyTorch进行EEG信号的分析。我们将深入探讨基于时间、频率和成分的分析方法,并通过实际代码展示如何处理和分析EEG数据。

背景

        脑电图(EEG)记录大脑电活动,广泛应用于研究认知功能、诊断神经疾病和开发脑机接口。EEG信号的分析通常包括时间域特征提取、频率域分析和成分分析。本文主要使用以下数据集进行演示:

  1. P300信号数据集:记录了用户在视觉刺激下的P300反应,是研究注意力和认知功能的常用数据。
  2. DEAP数据集:包含参与者观看情感视频时的EEG信号,用于情感分析研究。
  3. SSVEP数据集:记录了用户注视不同频率闪烁光源时的EEG信号,常用于脑机接口研究。
  4. Motor Imagery数据集:记录用户想象左手或右手运动时的EEG信号,用于运动意图检测。

代码实现

1. 数据加载与预处理

import mne
import numpy as np
import pandas as pd
import torch

# 读取P300数据集
df = pd.read_csv("../data/p300-6trials-12rep-chaky.csv")
df = df.drop(["timestamps"], axis=1)
df.columns = ['P4', 'Pz', 'P3', 'PO4', 'POz', 'PO3', 'O2', 'O1', 'Marker']

        在此步骤中,我们从CSV文件加载EEG数据并进行预处理,包括移除时间戳和重命名通道。

2. 转换为MNE Raw对象

def df_to_raw(df):
    sfreq = 125  # 采样率
    ch_names = list(df.columns)
    ch_types = ['eeg'] * (len(df.columns) - 1) + ['stim']
    info = mne.create_info(ch_names=ch_names, ch_types=ch_types, sfreq=sfreq)
    df = df.T  # 转置数据
    df[:-1] *= 1e-6  # 转换单位为伏特
    raw = mne.io.RawArray(df, info)
    return raw

raw = df_to_raw(df)

        我们使用MNE库将Pandas DataFrame转换为MNE Raw对象,以便后续处理。

3. 数据伪影去除与滤波

# 移除50Hz电源噪声
raw.notch_filter(50)
# 滤波去除低频漂移和高频噪声
raw.filter(1, 40)

        使用MNE工具去除EEG信号中的伪影和噪声,包括电源线噪声和低频漂移。

4. Epoching与特征提取

from mne import Epochs, find_events

event_id = {'Non-Target': 1, 'Target': 2}
epochs = Epochs(raw, events=find_events(raw), event_id=event_id, tmin=-0.1, tmax=0.6, preload=True)

# 获取数据和标签
X = epochs.get_data()
y = epochs.events[:, -1]

        在这一步中,我们对数据进行切片(epoching),提取事件相关的时间窗,并提取特征和标签。

5. 数据归一化与Tensor转换

from sklearn.preprocessing import MinMaxScaler
X = np.transpose(X, (0, 2, 1))
scalers = {i: MinMaxScaler(feature_range=(-1, 1)).fit(X[:, :, i]) for i in range(X.shape[2])}
X = np.array([scalers[i].transform(X[:, :, i]) for i in range(X.shape[2])]).transpose(1, 2, 0)

X = torch.FloatTensor(X)
y = torch.LongTensor(y) - 1  # 标签从0开始

        我们使用MinMaxScaler对数据进行归一化,并将其转换为PyTorch张量以用于神经网络训练。

6. 模型构建与训练

class EEGNet(nn.Module):
    def __init__(self, input_size=8, hidden_size=50, out_size=2):
        super(EEGNet, self).__init__()
        self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True)
        self.linear = nn.Linear(hidden_size, out_size)
    
    def forward(self, x):
        _, (h_n, _) = self.lstm(x)
        out = self.linear(h_n[-1])
        return out

model = EEGNet().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)

        在此,我们定义了一个简单的LSTM模型,用于分类P300信号。然后,我们设置了损失函数和优化器。

7. 训练模型

for epoch in range(20):
    model.train()
    for X_batch, y_batch in train_loader:
        X_batch, y_batch = X_batch.to(device), y_batch.to(device)
        optimizer.zero_grad()
        output = model(X_batch)
        loss = criterion(output, y_batch)
        loss.backward()
        optimizer.step()
    print(f"Epoch {epoch + 1}, Loss: {loss.item()}")

        在训练过程中,我们迭代数据集,优化模型参数,记录损失值。

8. 模型评估

model.eval()
correct = 0
total = 0
with torch.no_grad():
    for X_batch, y_batch in test_loader:
        X_batch, y_batch = X_batch.to(device), y_batch.to(device)
        output = model(X_batch)
        _, predicted = torch.max(output.data, 1)
        total += y_batch.size(0)
        correct += (predicted == y_batch).sum().item()

print(f"Test Accuracy: {100 * correct / total}%")

结语

        在本文中,我们深入探讨了如何使用Python和深度学习技术进行EEG信号分析。我们涵盖了从数据预处理到模型训练和评估的完整流程,并展示了如何应用LSTM模型进行P300信号的分类。这些方法不仅为我们理解大脑活动提供了新的视角,也为脑机接口的开发和应用提供了坚实的基础。

        EEG信号分析是一项复杂且充满挑战的任务,需要多学科的知识和技术。在后续的研究和应用中,我们可以进一步探索更多的分析方法和模型,如频域分析、独立成分分析(ICA)等,以更全面地解读EEG信号中的信息。

        本篇文章为EEG信号分析奠定了基础,后续的研究和开发工作将继续在此基础上探索更高级的分析技术和应用场景。我们期待这些研究成果能在医学诊断、神经科学研究等领域发挥重要作用,为相关领域带来更多创新和突破。

如果你觉得这篇博文对你有帮助,请点赞、收藏、关注我,并且可以打赏支持我!

欢迎关注我的后续博文,我将分享更多关于人工智能、自然语言处理和计算机视觉的精彩内容。

谢谢大家的支持!

Python中进行脑电信号特征提取可以使用一些常见的信号处理和机器学习库。以下是一个基本的脑电信号特征提取的示例: 1. 导入所需的库: ```python import numpy as np from scipy.signal import butter, filtfilt from scipy.stats import entropy from sklearn.decomposition import PCA ``` 2. 定义一个函数来滤波脑电信号: ```python def filter_signal(signal, low_freq, high_freq, fs): nyquist = 0.5 * fs low = low_freq / nyquist high = high_freq / nyquist b, a = butter(4, [low, high], btype='band') filtered_signal = filtfilt(b, a, signal) return filtered_signal ``` 3. 定义一个函数来提取脑电信号的频谱特征: ```python def extract_spectrum_features(signal, fs): window_size = int(fs) overlap = int(fs / 2) spectrum = np.abs(np.fft.fft(signal)) spectrum = spectrum[:int(len(signal)/2)] return spectrum ``` 4. 定义一个函数来提取脑电信号的时域特征: ```python def extract_time_domain_features(signal): mean = np.mean(signal) variance = np.var(signal) std_deviation = np.std(signal) entropy_value = entropy(signal) return mean, variance, std_deviation, entropy_value ``` 5. 定义一个函数来提取脑电信号的空域特征(使用主成分分析): ```python def extract_spatial_features(signal): pca = PCA(n_components=3) spatial_features = pca.fit_transform(signal) return spatial_features ``` 这些只是一些常见的特征提取方法示例,你可以根据你的需要进一步扩展和优化这些方法。注意,脑电信号特征提取是一个复杂的任务,需要基于领域知识和实际数据进行调整和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会飞的Anthony

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值