Python-For-EEG基础代码讲解(1)

news/2024/10/30 13:35:02/

Python-For-EEG

我要演示脑电图信号的基本分析。

主题

1、基于时域分析,P300信号数据集

  1. Event-related potentials and 1-dimensional convolution(ERP,CNN)
  2. Long short-term memory(LSTM)

2、基于频域分析,DEAP和SSVEP数据集

  1. Spectral analysis and alpha asymmetry
  2. Canonical correlation analysis(CCA)

3、基于成分分析,运动想象数据集

  1. Event-related desynchronization(ERD)

数据集

所有数据集准备好

1. P300数据集
这是我个人的P300信号,我通过我的OpenBCI耳机在视觉上关注36个字母顺序的目标时获得的。当闪光灯在我所看的目标上闪烁时,在刺激开始后300ms会有一个信号上升。在数据集中,列是时间戳(128 samples per second), 16 channels of ‘Fp1’, ‘Fp2’, ‘F7’, ‘F3’, ‘F4’, ‘F8’, ‘C3’, ‘Cz’, ‘C4’, ‘T5’, ‘P3’, ‘P4’, ‘T6’, ‘POz’, ‘O1’, ‘O2’, 标记表示事件。标记格式将在笔记本中详细说明。

文件:p300-6trials-12rep-chaky.csv

2、DEAP和SSVEP数据集
ssvep数据集

在这里,我们记录了用户分别观看以6,10和15Hz闪烁的三个不同的圆圈。我们将使用滤波器组典型相关分析对信号进行分类。
文件:ssvep-10trials-3s-chaky-bigsquare.csv

DEAP 数据集

它基本上是一个数据集,关于参与者观看一些1分钟的情感视频,同时佩戴32个EEG通道。欲了解更多详情,请访问https://www.eecs.qmul.ac.uk/mmv/datasets/deap/

经过处理python版本DEAP数据

3、运动想象数据集

在这里,我们记录一个用户做想象中的左右运动。我们将探索与事件相关的去同步以解码类。

这里我们将演示处理脑电图信号的基本过程。为了简单起见,我们将处理一个相当简单的P300数据集。

我们还将访问事件相关电位和长短期记忆来解码信号。
注意:我们假设你对神经网络非常熟悉,所以我们将主要使用它,而不会有太多杂乱的解释。

导入基础包

import mne
from mne import create_info
from mne.io import RawArrayimport numpy as np
import pandas as pd
import torch
import torch.nn as nn
from torch.utils.data import TensorDataset, WeightedRandomSampler

cuda加速

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(device)

加载数据

df = pd.read_csv("../data/p300-6trials-12rep-chaky.csv")
df.head()
#we don't need timestamps for modeling
df = df.drop(["timestamps"], axis=1)
df.columns = ['P4', 'Pz', 'P3', 'PO4', 'POz', 'PO3', 'O2', 'O1', 'Marker']   #channels named according to how we plug our eeg device
df.head()

让我们看看这个标记是如何生成的。格式如下:

  • 0:不发生任何事情
    — 1:表示非目标闪烁
  • 2:闪光到目标
print(df['Marker'].unique())

基础背景

如果你对数据不了解,首先,你需要了解脑电图实验。

在类似脑电图的实验中,你通常有一个会话(session)。(a record)

您通常拥有的数据以(通道,样本)(channels, samples)的形式存在。

例如,如果你用16个通道记录脑电图,采样率为128赫兹,5秒长,那么你最终会得到一个(16,128 x 5)的会话,因为1秒将有128个样本,即根据定义。

我们记录的一个附加通道是“marker”。

“marker”是一种记录中的映射器,用于以后识别某些事情发生的时间。

具有3个EEG通道+标记的数据可能看起来像这样

[...[eeg_1, eeg_2, eeg_3, 0],[eeg_1, eeg_2, eeg_3, 0],[eeg_1, eeg_2, eeg_3, 0],[eeg_1, eeg_2, eeg_3, 1], <----- Some event1, like flashes or images happen here:[eeg_1, eeg_2, eeg_3, 0],[eeg_1, eeg_2, eeg_3, 0],[eeg_1, eeg_2, eeg_3, 0],[eeg_1, eeg_2, eeg_3, 0],[eeg_1, eeg_2, eeg_3, 0],[eeg_1, eeg_2, eeg_3, 2], <----- Some event2 again but another target happen here:[eeg_1, eeg_2, eeg_3, 0],[eeg_1, eeg_2, eeg_3, 0],[eeg_1, eeg_2, eeg_3, 0],...
]

因此,我们感兴趣的是在事件显示一段时间后(可能在event1显示后3秒)检索所有样本,这个过程称为“epoching”。

数据转换为原始MNE对象

First we gonna use Python MNE as it provides many useful methods for achieving these tasks. So first, we gonna transform our pandas to mne type. Here is the function transforming df to raw mne.
首先,我们将使用Python MNE库,因为它为实现这些任务提供了许多有用的方法。首先,我们要把 pandas类型 数据 转换成 mne 类型。这是将df转换成raw的函数。

raw = df_to_raw(df)

以下是一些关于我的数据结构的简短总结:
https://mne.tools/stable/most_used_classes.html

  1. MNE.io.Raw
  • MNE.io.Raw 是你的整个session。在这个类中,您可以为整个session执行预处理,如’ filter '。
  1. MNE.Epochs
  • epoch是一个将整个session分割为较小窗口的方法。你可以按你喜欢的方式来epoching你的session。最常见的epoch是遵循marker/event通道

3.MNE.Evoked

  • Evoked是你从每个epochs得到的数据。你可以把epochs想象成 一系列的Evoked。

伪影移除

伪影是需要消除的噪音。频率受限伪影的两个例子是缓慢漂移和电源线噪声。下面我们将说明如何通过过滤来修复这些缺陷。

def df_to_raw(df):sfreq = 125  #our OpenBCI headset sampling ratech_names = list(df.columns)ch_types = ['eeg'] * (len(df.columns) - 1) + ['stim']ten_twenty_montage = mne.channels.make_standard_montage('standard_1020')df = df.T  #mne looks at the tranpose() formatdf[:-1] *= 1e-6  #convert from uVolts to Volts (mne assumes Volts data)info = create_info(ch_names=ch_names, ch_types=ch_types, sfreq=sfreq)raw = mne.io.RawArray(df, info)raw.set_montage(ten_twenty_montage)#try plotting the raw data of its power spectral densityraw.compute_psd().plot()return raw

电源噪声

电源噪声是由电网产生的噪声。它由50Hz(或60Hz,取决于你的地理位置)的尖峰组成。一些峰值也可能出现在谐波频率,即电力线频率的整数倍,例如100Hz, 150Hz,…(或120Hz, 180Hz,…)。

去除220V交流电50Hz电源噪声。我们还将去除它的谐波,即100Hz, 150Hz等。由于我们的信号是62.5Hz(根据奈奎斯特定理是125Hz / 2),我们不需要运行谐波,而只需截取50Hz信号。

raw.notch_filter(50) #250/2 based on Nyquist Theorem

设置从49 - 51赫兹的带阻滤波器

FIR滤波器参数

设计一种单通、零相位、无因果带阻滤波器
-有窗时域设计(firwin)方法
-汉明窗口0.0194通带纹波和53 dB阻带衰减
—下带边缘:49.38
-低转换带宽:0.50 Hz (- 6db截止频率:49.12 Hz)
—上通带边缘:50.62 Hz
—上转换带宽:0.50 Hz (- 6db截止频率:50.88 Hz)
-过滤器长度:825个样本(6.600秒)

#可以看到50Hz噪声被移除了, yay!
raw.compute_psd().plot()

漂移移除

低频漂移通常在1Hz以下。此外,由于P300,可以安全地假设没有有用的数据超过40Hz。

raw.filter(1, 40)
raw.compute_psd().plot();

过滤1个连续段的原始数据
设置从1 - 40赫兹的带通滤波器

FIR滤波器参数

设计一种单通、零相位、非因果带通滤波器
-有窗时域设计(firwin)方法
-汉明窗口0.0194通带纹波和53 dB阻带衰减
—下通带边缘:1.00
-低转换带宽:1.00 Hz (- 6db截止频率:0.50 Hz)
—上通带边缘:40.00 Hz
—转换带宽上限:10.00 Hz (- 6db截止频率:45.00 Hz)
-过滤器长度:413个样本(3.304秒)

Epoching

epoch是在事件发生时只提取相关脑电数据的过程。在这里,我们将在事件开始前-0.1秒提取到事件开始后0.6秒。这里我们选择0.6秒,因为我们知道P300发生在300毫秒左右,所以它是一个很好的中间值。

from mne import Epochs, find_eventsdef getEpochs(raw, event_id, tmin, tmax, picks):#epochingevents = find_events(raw)epochs = Epochs(raw, events=events, event_id=event_id, tmin=tmin, tmax=tmax, baseline=None, preload=True,verbose=False, picks=picks)  #8 channelsprint('sample drop %: ', (1 - len(epochs.events)/len(events)) * 100)return epochs#this one requires expertise to specify the right tmin, tmax
event_id = {'Non-Target': 1, 'Target' : 2}
tmin = -0.1
tmax = 0.6
eeg_channels = mne.pick_types(raw.info, eeg=True)
picks= eeg_channels
epochs = getEpochs(raw, event_id, tmin, tmax, picks)   

今天先到这,下一集继续讲!好的话给个赞,所有资料在这里


http://www.ppmy.cn/news/203622.html

相关文章

苹果上网本报价_比iPhone还便宜,这是你能买到最香的苹果笔记本!?

熟悉苹果的差友们和果粉应该都知道&#xff0c;前阵子&#xff0c;苹果在官网上架了新款 MacBook Air。 只是它的关注度没有隔壁新款 iPad Pro 来的大&#xff0c;很多人都把注意力放在了首次加入激光雷达并且支持触控板的平板上。 连苹果自己都在官网说了&#xff1a;“ 你的下…

​iPhone 14 Pro 全系降价 700 元;Gmail 之父:有了 ChatGPT,搜索引擎活不过两年了|极客头条

「极客头条」—— 技术人员的新闻圈&#xff01; CSDN 的读者朋友们早上好哇&#xff0c;「极客头条」来啦&#xff0c;快来看今天都有哪些值得我们技术人关注的重要新闻吧。 整理 | 梦依丹 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 一分钟速览新闻点&…

如何以最低廉的价格(249元!!)组装一台Mac黑苹果主机,垃圾佬极限装机!!

废话不多说&#xff0c;先上图&#xff01;&#xff01; 配置单&#xff1a; 主板&#xff1a;清华同方G41&#xff08;支持ddr3&#xff09;cpu(Q8300)60元&#xff08;那个淘宝店买主板送cpu&#xff0c;哪个店铺我忘了&#xff0c;买了一年多了&#xff09; 散热器&#x…

李彦宏给创新员工发放2000万奖金;iPhone 14系列新机涨价后,电池维修费也涨至748元|极客头条

「极客头条」—— 技术人员的新闻圈&#xff01; CSDN 的读者朋友们早上好哇&#xff0c;「极客头条」来啦&#xff0c;快来看今天都有哪些值得我们技术人关注的重要新闻吧。 整理 | 梦依丹 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 一分钟速览新闻点&…

苹果WWDC或推8GB版iPhone5s和低价iMac

腾讯科技讯 5月29日消息&#xff0c;苹果全球开发大会&#xff08;WWDC&#xff09;日益临近。日前&#xff0c;在预测苹果新产品方面享有全球盛誉的凯基证券大牌分析师郭明池&#xff0c;预测苹果将在大会上发布一款价格更便宜的电脑一体机&#xff0c;以及存储容量8GB的更便宜…

fjnu 1725 分苹果

Description 有苹果若干,按以下方法分给五个大人和一位小孩. 先由第一人将苹果均分为5堆,多余的一个给小孩,自己取其中的一堆.第二人 又将剩下的苹果均分为5堆,多余一个给小孩,自己取其中的一堆.第三、四、五人 同样均分&#xff0c;多余一个给小孩&#xff0c;每人各取其中一堆…

MacBook Pro(13 英寸,2011 年末)A1278 满血复活记(安装Catalina和Windows11双系统)

朋友看到我疫情在家时折腾那台2015 iMAC&#xff0c;就拿来一台苹果笔记本电脑&#xff0c;说是无法开机&#xff0c;找修电脑的也搞不好&#xff0c;让我给看看。正好五一疫情期间&#xff0c;哪儿也不让去&#xff0c;闲着无聊&#xff0c;活动活动大脑&#xff0c;预防老年痴…

骁龙8gen2和苹果A15哪个好 骁龙8gen2和A15对比

骁龙8gen2相当于苹果a几&#xff1f; 答&#xff1a;骁龙8gen2大概相当于苹果a15。 因为现在骁龙8gen1仅相当于苹果a13。 据悉骁龙8gen2跑分还会突破120万&#xff0c;直接成为安卓天花板&#xff0c;因此肯定可以对标苹果最新芯片。 我用的手机就是活动时8折抢购的太划算了机会…