Python中MNE库的事件相关特定频段分析(MEG数据)

2023-10-29

最近做运动想象分类的时候遇到一个问题就是分类结果始终不准,想从原始数据分析一下脑电数据,找了下MNE提供的examples。里面还真有一个按频带分析的例子,说实话打开这个例子最主要的原因是这个图看着比较牛。。。后面的主要内容就是分析这个例子的实现以及其中几个比较有意思的知识点。文章中提到的内容都打包到了上面的资料包中,如果只需要部分内容也可以在文章中单独下载。

先上代码吧,一行一行的看下来这里有几个知识点还是比较有意思的。

1、epochs.subtract_evoked()有什么作用?

2、epochs.apply_hilbert(envelope=True)有什么用?

3、GFP是什么?

4、bootstrap_confidence_interval有什么用?

# 导入必要的包
import os.path as op

import numpy as np
import matplotlib.pyplot as plt

import mne
from mne.datasets import somato
from mne.baseline import rescale
from mne.stats import bootstrap_confidence_interval

# 设置参数
data_path = somato.data_path()
subject = '01'
task = 'somato'
raw_fname = op.join(data_path, 'sub-{}'.format(subject), 'meg',
                    'sub-{}_task-{}_meg.fif'.format(subject, task))

# 设置4种不同波段的频率范围
iter_freqs = [
    ('Theta', 4, 7),
    ('Alpha', 8, 12),
    ('Beta', 13, 25),
    ('Gamma', 30, 45)
]

###############################################################################
# 创建每一个频段的时间功率谱

# 设置epoch的相关参数,这里分析event_id为1的事件,事件时间范围[-1, 3]
event_id, tmin, tmax = 1, -1., 3.
baseline = None

# 从源文件中读取事件信息
raw = mne.io.read_raw_fif(raw_fname)
events = mne.find_events(raw, stim_channel='STI 014')
# 初始化处理结果字典,frequency_map用于保存各个频段的处理结果
frequency_map = list()

for band, fmin, fmax in iter_freqs:
    # 加载原始数据
    raw = mne.io.read_raw_fif(raw_fname, preload=True)
    # 提取MEG数据,这里使用的是MEG的梯度数据,非EEG数据
    raw.pick_types(meg='grad', eog=True)

    # 设计带通滤波,这里l/h_trans_bandwidth是滤波器的设计参数,会影响滤波器的品质
    raw.filter(fmin, fmax, n_jobs=1, l_trans_bandwidth=1, h_trans_bandwidth=1)

    # 生成epoch格式的数据
    epochs = mne.Epochs(raw, events, event_id, tmin, tmax, baseline=baseline,
                        reject=dict(grad=4000e-13, eog=350e-6),
                        preload=True)
    # 去除evoked能量,保留induced部分
    epochs.subtract_evoked()

    # 构建Hilbert解析信号 (包络)
    epochs.apply_hilbert(envelope=True)
    # 保存对应频段的处理结果,epochs的均值代表该频段的(induced)处理结果
    frequency_map.append(((band, fmin, fmax), epochs.average()))
    del epochs
del raw

###############################################################################
# 计算GFP,采用bootstrap方法计算置信区间,与基线比较追踪每一个频段的空间域中事件的出现
# 可以看出主要的反应集中在 Alpha 和 Beta 频段.


# 计算置信GFP置信区间的辅助函数
def stat_fun(x):
    """Return sum of squares."""
    return np.sum(x ** 2, axis=0)


# 构建绘图的fig,由4行1列子图构成,共享x和y轴
fig, axes = plt.subplots(4, 1, figsize=(10, 7), sharex=True, sharey=True)
# 设置绘图颜色
colors = plt.get_cmap('winter_r')(np.linspace(0, 1, 4))
# 开始绘制不同频段对应的处理结果
for ((freq_name, fmin, fmax), average), color, ax in zip(
        frequency_map, colors, axes.ravel()[::-1]):
    # 扩展时间,实际上也就是为例扩展横轴,绘图后横轴会好看些,对于计算没有什么实际意义
    times = average.times * 1e3
    # 计算gfp,这里没有进行正则化处理
    gfp = np.sum(average.data ** 2, axis=0)
    # 重新缩放gfp曲线,根据rescale的源码缩放后是减去均值的
    gfp = mne.baseline.rescale(gfp, times, baseline=(None, 0))
    # 绘制gfp曲线
    ax.plot(times, gfp, label=freq_name, color=color, linewidth=2.5)
    # 绘制0值基线
    ax.axhline(0, linestyle='--', color='grey', linewidth=2)
    # 利用bootstrap计算置信区间
    ci_low, ci_up = bootstrap_confidence_interval(average.data, random_state=0, stat_fun=stat_fun)
    # 对置信区间进行缩放,这里主要的作用是对ci_low/up减去均值
    ci_low = rescale(ci_low, average.times, baseline=(None, 0))
    ci_up = rescale(ci_up, average.times, baseline=(None, 0))
    # 绘制gfp的置信区间
    ax.fill_between(times, gfp + ci_up, gfp - ci_low, color=color, alpha=0.3)
    # 添加网格
    ax.grid(True)
    # 设置y轴名称
    ax.set_ylabel('GFP')
    # 添加图的说明
    ax.annotate('%s (%d-%dHz)' % (freq_name, fmin, fmax),
                xy=(0.95, 0.8),
                horizontalalignment='right',
                xycoords='axes fraction')
    # 设置x轴的坐标范围,这里和上面扩展后的时间保持一致
    ax.set_xlim(-1000, 3000)
# 设置x轴的名称
axes.ravel()[-1].set_xlabel('Time [ms]')
# 绘图显示
plt.show()

 

1、epochs.subtract_evoked()有什么作用?

subtract是减法的意思,直译过来就是减去evoked,一脸懵逼,黑人问号???为什么要减去evoked啊。。。

查看一下说明文档更懵了:去除evoked,进行induced分析,可是这两单词都是引起的意思啊,好在有参考文献啊,大概看了下,涨知识了。原来脑电活动是有相位锁定和非相位锁定之分的。evoked为相位锁定的信号,induced为非相位锁定的信号,所以这里分析的是非相位锁定部分的脑电信号。

对应的参考文献《Mechanisms of evoked and induced responses in MEG/EEG》下载地址:

https://download.csdn.net/download/zhoudapeng01/12334169

对应文章摘要的截图,大概意思说的就是evoked,induced和on-going oscillations反映了不同的神经元处理过程和机制。详细的内容可以下载文章查看。

推荐一个比较不错的中文参考文献:

http://kns.cnki.net/kcms/detail/Detail.aspx?dbname=CAPJLAST&filename=XLXD20180627009&v=

 

2、epochs.apply_hilbert(envelope=True)有什么用?

Hilbert变换有什么用?从物理意义的角度来说,就是获取信号的包络信息,得到整体的信息。推荐几个链接:

https://blog.csdn.net/weixin_41608328/article/details/89322214

https://www.zhihu.com/question/30372795

http://bigsec.net/b52/scipydoc/frequency_process.html

 

3、GFP是什么?

GFP是global field power的简称,这又是什么鬼呢?参考文献《Automated model selection in covariance estimation and spatial whitening of MEG and EEG signals》的332页中给出了解释:

对应的资源链接:https://download.csdn.net/download/zhoudapeng01/12334442

公式中分母有个P,是为了做正则化处理的,而在实际代码中并没有,在方法介绍中有说明,这里没有正则化处理。

 

4、bootstrap_confidence_interval有什么用?

这个函数的作用就是为了准确地计算置信区间,详细的介绍在参考文献《Computer age statistical inference: Algorithms, evidence, and data science》中,CSDN上已经有了叫casi,传不上去了,可以去官网下载,就是有点慢。
 
 

 

配套的资料包中有搜集的相关资料,有些在博客中没有提到,但是也很不错的。

https://download.csdn.net/download/zhoudapeng01/12334513

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python中MNE库的事件相关特定频段分析(MEG数据) 的相关文章

随机推荐

  • mybaits 代码自动生成

    https github com zhengjunbase codehelper generator GenDaoCode使用方法 主菜单Tools gt Codehelper gt GenDaoCode按键便可生成代码 方法一 点击Gen
  • 蓝桥杯模拟赛B组(大一报了直呼上当)

    这周蓝桥杯举行了模拟赛 需交费 交完后大家发现上当了 没想到这难度居然是小学生水平 这明显是在 咳嗽声 好 回归正题 今天博主给你们带来部分B组题题解 让你们重拾信心 继续进军省赛 目录 第一题 解析 实现 第二题 解析 第三题 解析 代码
  • Daily paper reading

    20180207 Nature Review Studying and modifying brain function with non invasive brain stimulation Brain derived neurotrop
  • ActiveMQ订阅模式持久化实现

    我的诉求是 建一个订阅通道 然后多个客户端监听 当某个客户端掉线后 再上线的时候可以收到它没有接收到的消息 本文主要参考了 使用Spring配置ActiveMQ的发布订阅模式 http nettm iteye com blog 182826
  • 【pytorch冻结网络参数:最全版】

    动机和意义 首先要搞清楚使用为什么要冻结某些层 以及那些层能够被冻结 冻结网络参数的一些动机 避免过拟合 当训练数据较少时 神经网络容易过拟合 即在训练集上表现很好 但在测试集上表现差 冻结一些参数可以减少网络的自由度 避免过拟合 加速训练
  • Java多线程 常见面试题

    1 什么是线程 线程是操作系统能够进行运算调度的最小单位 它被包含在进程之中 是进程中的实际运作单位 程序员可以通过它进行多处理器编程 你可以使用多线程对运算密集型任务提速 比如 如果一个线程完成一个任务要100毫秒 那么用十个线程完成该任
  • Unix系统 - 进程管理

    写在前面 注意 本章除了讲解进程管理 还包含网络编程Socket API的知识 这里写目录标题 一 进程 1 1基础知识 1 1 1进程ID 1 1 2查看进程 1 1 2 父子进程概念 1 1 3得到进程ID的函数 1 2 进程运行 1
  • SpringBoot教学资料6-SpringBoot登录注册功能实现(带简单前端)

    项目样式 SQL CREATE TABLE t user id int 11 NOT NULL AUTO INCREMENT username varchar 32 NOT NULL password varchar 32 NOT NULL
  • JavaScript 教程 (详细 全面)

    文章目录 JavaScript 是什么 JavaScript 简介 1 JavaScript 的历史 2 JavaScript 与 ECMAScript 的关系 3 如何运行 JavaScript 4 JavaScript 具有以下特点 N
  • 题目:根据当月利润,求应发放奖金总数

    题目描述 企业发放的奖金根据利润提成 利润低于或等于10万元时 奖金可提10 利润高于10万元 低于20万元时 低于10万元的部分按10 提成 高于10万元的部分 可提成7 5 20万到40万之间时 高于20万元的部分 可提成5 40万到6
  • 【Docker】Docker容器管理

    1 容器外部操作 1 通过实训平台进入到操作系统界面 在 后输入sudo docker run ubuntu 14 04 bin echo Hello world 命令 然后按Enter键 启动一个ubuntu容器 会输出 Hello Wo
  • 软件测试人员的职业发展路径和技术路线规划

    软件测试人员应该如何规划自己的职业发展路径 如何规划自己的技术路线 下面是我整理的两张图 大家可以参考这两张图 结合自已目前所处的技术水平阶段 自己的性格和特长 去提前定位个人的职业发展方向 规划下一步学习的内容 目录 一 技术路线图 准新
  • redis必杀命令:字符串(String)

    题记 Redis 字符串数据类型的相关命令用于管理 redis 字符串值 基本语法如下 redis 127 0 0 1 6379 gt COMMAND KEY NAME 字符串命令 序号 命令及描述 1 SET key value 设置指定
  • 贵金属白银行情走势图缘何强势?

    自从去年12月中以来 国际现货白银价格已经从底部抬升超过10 许多抓对行情节奏的投资者已经赚到了相当不俗的收益 但作为有专业素养的投资者 必须明白行情运行背后的逻辑 才能在日后的交易中再次占得先机 根据瑞士信贷2017全球财富报告 去年全球
  • VS code For win7 最后支持的一个版本是 1.70.3

    VS code For win7 最后支持的一个版本是 1 70 3 原本地址是 https update code visualstudio com 1 70 2 win32 x64 stable 实际地址 https az764295
  • 解决在Android studio的Button控件下background背景设置不起作用的问题

    Button控件默认的背景是深紫色的 想要修改背景色所以添加了background字段 但是又不起作用 其实是themes xml文件里的 style 标签 的 parent 属性设置不对
  • CentOS7设置IPv4&IPv6

    进入网卡目录 1 cd etc sysconfig network scripts 修改ONBOOT yes 2 vi ifcfg ens33 TYPE Ethernet PROXY METHOD none BROWSER ONLY no
  • 移动端异构运算技术 - GPU OpenCL 编程(基础篇)

    一 前言 随着移动端芯片性能的不断提升 在移动端上实时进行计算机图形学 深度学习模型推理等计算密集型任务不再是一个奢望 在移动端设备上 GPU 凭借其优秀的浮点运算性能 以及良好的 API 兼容性 成为移动端异构计算中非常重要的计算单元 现
  • angular API

    angular API bind bootstrap copy uppercase lowercase fromJson toJson element noop identity angular bind 返回一个调用self的函数fn s
  • Python中MNE库的事件相关特定频段分析(MEG数据)

    最近做运动想象分类的时候遇到一个问题就是分类结果始终不准 想从原始数据分析一下脑电数据 找了下MNE提供的examples 里面还真有一个按频带分析的例子 说实话打开这个例子最主要的原因是这个图看着比较牛 后面的主要内容就是分析这个例子的实