信号处理--情绪分类数据集DEAP预处理(python版)

news2024/11/18 10:38:24

关于

DEAP数据集是一个常用的情绪分类公共数据,在日常研究中经常被使用到。如何合理地预处理DEAP数据集,对于后端任务的成功与否,非常重要。本文主要介绍DEAP数据集的预处理流程。

工具

 图片来源:DEAP: A Dataset for Emotion Analysis using Physiological and Audiovisual Signals

 DEAP数据集详细描述:https://www.eecs.qmul.ac.uk/mmv/datasets/deap/doc/tac_special_issue_2011.pdf

方法实现

加载.bdf文件+去除非脑电通道
	bdf_file_name = 's{:02d}.bdf'.format(subject_id)
	bdf_file_path = os.path.join(root_folder, bdf_file_name)
	
	print('Loading .bdf file {}'.format(bdf_file_path))
	raw = mne.io.read_raw_bdf(bdf_file_path, preload=True, verbose=False).load_data()
	ch_names = raw.ch_names
	eeg_channels = ch_names[:N_EEG_electrodes]
	non_eeg_channels = ch_names[N_EEG_electrodes:]
	stim_ch_name = ch_names[-1]
	stim_channels = [ stim_ch_name ]
设置脑电电极规范
raw_copy = raw.copy()
	raw_stim = raw_copy.pick_channels(stim_channels)
	raw.pick_channels(eeg_channels)
	print('Setting montage with BioSemi32 electrode locations')
	biosemi_montage = mne.channels.make_standard_montage(kind='biosemi32', head_size=0.095)
	raw.set_montage(biosemi_montage)
带通滤波器(4-45Hz),陷波滤波器(50Hz)
	print('Applying notch filter (50Hz) and bandpass filter (4-45Hz)')
	raw.notch_filter(np.arange(50, 251, 50), n_jobs=1, fir_design='firwin')
	raw.filter(4, 45, fir_design='firwin')
脑电通道相对于均值重标定
	# Average reference. This is normally added by default, but can also be added explicitly.
	print('Re-referencing all electrodes to the common average reference')
	raw.set_eeg_reference()
获取事件标签
print('Getting events from the status channel')
	events = mne.find_events(raw_stim, stim_channel=stim_ch_name, verbose=True)
	if subject_id<=23:
		# Subject 1-22 and Subjects 23-28 have 48 channels.
		# Subjects 29-32 have 49 channels.
		# For Subjects 1-22 and Subject 23, the stimuli channel has the name 'Status'
		# For Subjects 24-28, the stimuli channel has the name ''
		# For Subjects 29-32, the stimuli channels have the names '-0' and '-1'
		pass
	else:
		# The values of the stimuli channel have to be changed for Subjects 24-32
		# Trigger channel has a non-zero initial value of 1703680 (consider using initial_event=True to detect this event)
		events[:,2] -= 1703680 # subtracting initial value
		events[:,2] = events[:,2] % 65536 # getting modulo with 65536
	
	print('')
	event_IDs = np.unique(events[:,2])
	for event_id in event_IDs:
		col = events[:,2]
		print('Event ID {} : {:05}'.format(event_id, np.sum( 1.0*(col==event_id) ) ) )
获取事件对应信号
inds_new_trial = np.where(events[:,2] == 4)[0]
	events_new_trial = events[inds_new_trial,:]
	baseline = (0, 0)
	print('Epoching the data, into [-5sec, +60sec] epochs')
	epochs = mne.Epochs(raw, events_new_trial, event_id=4, tmin=-5.0, tmax=60.0, picks=eeg_channels, baseline=baseline, preload=True)
ICA去除伪迹
print('Fitting ICA to the epoched data, using {} ICA components'.format(N_ICA))
	ica = ICA(n_components=N_ICA, method='fastica', random_state=23)
	ica.fit(epochs)
	ICA_model_file = os.path.join(ICA_models_folder, 's{:02}_ICA_model.pkl'.format(subject_id))
	with open(ICA_model_file, 'wb') as pkl_file:
		pickle.dump(ica, pkl_file)
	# ica.plot_sources(epochs)
	print('Plotting ICA components')
	fig = ica.plot_components()
	cnt = 1
	for fig_x in fig:
		print(fig_x)
		fig_ICA_path = os.path.join(ICA_components_folder, 's{:02}_ICA_components_{}.png'.format(subject_id, cnt))
		fig_x.savefig(fig_ICA_path)
		cnt += 1
	# Inspect frontal channels to check artifact removal 
	# ica.plot_overlay(raw, picks=['Fp1'])
	# ica.plot_overlay(raw, picks=['Fp2'])
	# ica.plot_overlay(raw, picks=['AF3'])
	# ica.plot_overlay(raw, picks=['AF4'])
	N_excluded_channels = len(ica.exclude)
	print('Excluding {:02} ICA component(s): {}'.format(N_excluded_channels, ica.exclude))
	epochs_clean = ica.apply(epochs.copy())

	#############################

	print('Plotting PSD of epoched data')
	fig = epochs_clean.plot_psd(fmin=4, fmax=45, area_mode='range', average=False, picks=eeg_channels, spatial_colors=True)
	fig_PSD_path = os.path.join(PSD_folder, 's{:02}_PSD.png'.format(subject_id))
	fig.savefig(fig_PSD_path)

	print('Saving ICA epoched data as .pkl file')
	mneraw_pkl_path = os.path.join(mneraw_as_pkl_folder, 's{:02}.pkl'.format(subject_id))
	with open(mneraw_pkl_path, 'wb') as pkl_file:
		pickle.dump(epochs_clean, pkl_file)

	epochs_clean_copy = epochs_clean.copy()
数据降采样和保存
print('Downsampling epoched data to 128Hz')
	epochs_clean_downsampled = epochs_clean_copy.resample(sfreq=128.0)

	print('Plotting PSD of epoched downsampled data')
	fig = epochs_clean_downsampled.plot_psd(fmin=4, fmax=45, area_mode='range', average=False, picks=eeg_channels, spatial_colors=True)
	fig_PSD_path = os.path.join(PSD_folder, 's{:02}_PSD_downsampled.png'.format(subject_id))
	fig.savefig(fig_PSD_path)

	data = epochs_clean.get_data()
	data_downsampled = epochs_clean_downsampled.get_data()
	print('Original epoched data shape: {}'.format(data.shape))
	print('Downsampled epoched data shape: {}'.format(data_downsampled.shape))
	
	###########################################
	
	EEG_channels_table = pd.read_excel(DEAP_EEG_channels_xlsx_path)
	EEG_channels_geneva = EEG_channels_table['Channel_name_Geneva'].values
	channel_pick_indices = []
	print('\nPreparing EEG channel reordering to comply with the Geneva order')
	for (geneva_ch_index, geneva_ch_name) in zip(range(N_EEG_electrodes), EEG_channels_geneva):
		bdf_ch_index = eeg_channels.index(geneva_ch_name)
		channel_pick_indices.append(bdf_ch_index)
		print('Picking source (raw) channel #{:02} to fill target (npy) channel #{:02} | Electrode position: {}'.format(bdf_ch_index + 1, geneva_ch_index + 1, geneva_ch_name))

	ratings = pd.read_csv(ratings_csv_path)
	is_subject =  (ratings['Participant_id'] == subject_id)
	ratings_subj = ratings[is_subject]
	trial_pick_indices = []
	print('\nPreparing EEG trial reordering, from presentation order, to video (Experiment_id) order')
	for i in range(N_trials):
		exp_id = i+1
		is_exp = (ratings['Experiment_id'] == exp_id)
		trial_id = ratings_subj[is_exp]['Trial'].values[0]
		trial_pick_indices.append(trial_id - 1)
		print('Picking source (raw) trial #{:02} to fill target (npy) trial #{:02} | Experiment_id: {:02}'.format(trial_id, exp_id, exp_id))
	
	# Store clean and reordered data to numpy array
	epoch_duration = data_downsampled.shape[-1]
	data_npy = np.zeros((N_trials, N_EEG_electrodes, epoch_duration))
	print('\nStoring the final EEG data in a numpy array of shape {}'.format(data_npy.shape))
	for trial_source, trial_target in zip(trial_pick_indices, range(N_trials)):
		data_trial = data_downsampled[trial_source]
		data_trial_reordered_channels = data_trial[channel_pick_indices,:]
		data_npy[trial_target,:,:] = data_trial_reordered_channels.copy()
	print('Saving the final EEG data in a .npy file')
	np.save(npy_path, data_npy)
	
	print('Raw EEG has been filtered, common average referenced, epoched, artifact-rejected, downsampled, trial-reordered and channel-reordered.')
	print('Finished.')

图片来源: Blog - Ayan's Blog

代码获取

后台私信,请注明文章名称;

相关项目和代码问题,欢迎交流。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1550172.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

docker关闭全部运行容器命令是什么?

环境&#xff1a; docker v22.1 问题描述&#xff1a; docker关闭全部运行容器命令是什么&#xff1f; 解决方案&#xff1a; 要关闭所有正在运行的Docker容器&#xff0c;可以使用如下命令&#xff1a; docker stop $(docker ps -a -q)这条命令首先执行 docker ps -a -q…

WiFiSpoof for Mac wifi地址修改工具

WiFiSpoof for Mac&#xff0c;一款专为Mac用户打造的网络隐私守护神器&#xff0c;让您在畅游互联网的同时&#xff0c;轻松保护个人信息安全。 软件下载&#xff1a;WiFiSpoof for Mac下载 在这个信息爆炸的时代&#xff0c;网络安全问题日益凸显。WiFiSpoof通过伪装MAC地址&…

【QQ版】QQ群短剧机器人源码 全网短剧机器人插件

内容目录 一、详细介绍二、效果展示2.效果图展示 三、学习资料下载 一、详细介绍 QQ版本可以兼容两个框架&#xff08;HTQQ&#xff0c;MYQQ这两个的vip版也可以使用) 支持私聊与群聊&#xff0c;命令是 搜剧影视关键词 如果无法搜索到影视资源&#xff0c;请使用下方命令&…

网络链路层之(2)PPP协议

网络链路层之(2)PPP协议 Author: Once Day Date: 2024年3月27日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章可参考专栏: 通信网络技术_Once-Day的博客-CSDN…

[TS面试]keyof和typeof关键字作用?

keyof和typeof关键字作用? keyof 索引类型查询操作符, 获取索引类型属性名, 构成联合类型 typeof 获取一个变量或者对象的类型 let str:string ‘hello’ // typeof str >:string keyof typeof 获取 联合类型的key enum A{A, B, C }type unionType keyof typeof A; /…

JDK8的下载安装与环境变量配置教程

前言 官网下载&#xff1a;Java Archive Downloads - Java SE 8u211 and later 现在应该没人用32位的系统了吧&#xff0c;直接下载Windows x64 Installer jdk-8u391-windows-x64.exe 一、安装JDK 1. 打开jdk-8u391-windows-x64.exe 2. 直接下一步 3. 这个地方不要动他&…

python opencv稍基础初学

傅里叶变换 傅里叶变换f​​​​​傅里叶分析之掐死教程&#xff08;完整版&#xff09;更新于2014.06.06 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/19763358 相当nice 傅里叶变换的作用 高频&#xff1a;变化剧烈的灰度分量&#xff0c;例如边界 低频&#xff1a;变…

P8649 [蓝桥杯 2017 省 B] k 倍区间:做题笔记

目录 思路 代码思路 代码 推荐 P8649 [蓝桥杯 2017 省 B] k 倍区间 思路 额嗯&#xff0c;这道题我刚上来是想到了前缀和&#xff0c;但是还要判断每个子序列&#xff0c;我就两层for嵌套&#xff0c;暴力解了题。就是我知道暴力肯定过不了但是写不出来其他的[留下了苦…

[linux] AttributeError: module ‘transformer_engine‘ has no attribute ‘pytorch‘

[BUG] AttributeError: module transformer_engine has no attribute pytorch Issue #696 NVIDIA/Megatron-LM GitHub 其中这个答案并没有解决我的问题&#xff1a; import flash_attn_2_cuda as flash_attn_cuda Traceback (most recent call last): File "<stdi…

golang 在多线程中避免 CPU 指令重排

发布日期&#xff1a;2024-03-26 16:29:39 起因 golang 的发明初衷便是多线程&#xff0c;是一门专门用于多线程高并发的编程语言。其独创的 GMP 模型在多线程的开发上提供了很大的便利。 现代计算机基本上都是多核 CPU 的结构。CPU 在进行指令运行的时候&#xff0c;为了提高…

基于大语言模型的云故障根因分析|顶会EuroSys24论文

*马明华 微软主管研究员 2021年CCF国际AIOps挑战赛程序委员会主席&#xff08;第四届&#xff09; 2021年博士毕业于清华大学&#xff0c;2020年在佐治亚理工学院做访问学者。主要研究方向是智能运维&#xff08;AIOps&#xff09;、软件可靠性。近年来在ICSE、FSE、ATC、EuroS…

【系统架构师】-第13章-层次式架构设计

层次式体系结构设计是将系统组成一个层次结构&#xff0c;每一层 为上层服务 &#xff0c;并作为下层客户。 在一些层次系统中&#xff0c;除了一些精心挑选的输出函数外&#xff0c; 内部的层接口只对相邻的层可见 。 连接件通过决定层间如何交互的协议来定义&#xff0c;拓扑…

免费SSL证书和付费SSL证书的区别点

背景&#xff1a; 在了解免费SSL证书和付费SSL证书的区别之前&#xff0c;先带大家了解一下SSL证书的概念和作用。 SSL证书的概念&#xff1a; SSL证书就是基于http超文本传输协议的延伸&#xff0c;在http访问的基础上增加了一个文本传输加密的协议&#xff0c;由于http是明…

让手机平板成为AI开发利器:AidLux

想ssh登录自己的手机吗&#xff1f; 想在手机上自由的安装lynx、python、vscode、jupyter甚至飞桨PaddlePaddle、Tensorflow、Pytorch和昇思Mindspore吗&#xff1f; 那么看这里....装上AidLux&#xff0c;以上全都有&#xff01; AidLux是一个综合的AI开发平台&#xff0c;…

Java 学习和实践笔记(49):用javabean和一维数组的方式来存储表格数据

还是存储下面这个表格的数据&#xff0c;但使用另一种方法来做。 用javabean和一维数组的方法来做&#xff0c;示例代码如下&#xff1a; /*先创建一个类&#xff0c;其实就是创建好一个只有各属性列的空表格*/ class Employees {private int id;private String name;private …

python学习12:python中的字符串格式化-数字精度控制

python中的字符串格式化-数字精度控制 1.使用辅助符号"m.n"来进行数据的宽度和精度的控制 m,控制宽度&#xff0c;要求是数字&#xff08;一般是很少使用的&#xff09;&#xff0c;设置的宽度小于数字自身&#xff0c;不生效 n,控制小数点精度&#xff0c;要求是数…

瑞_23种设计模式_观察者模式

文章目录 1 观察者模式&#xff08;Observer Pattern&#xff09;1.1 介绍1.2 概述1.3 观察者模式的结构1.4 观察者模式的优缺点1.5 观察者模式的使用场景 2 案例一2.1 需求2.2 代码实现 3 案例二3.1 需求3.2 代码实现 4 JDK中提供的观察者模式实现 ★4.1 Observable类4.2 Obse…

CCF-CSP真题202206-2《寻宝!大冒险!》

题目背景 暑假要到了。可惜由于种种原因&#xff0c;小 P 原本的出游计划取消。失望的小 P 只能留在西西艾弗岛上度过一个略显单调的假期……直到…… 某天&#xff0c;小 P 获得了一张神秘的藏宝图。 问题描述 西西艾弗岛上种有 n 棵树&#xff0c;这些树的具体位置记录在…

芝麻云节点服务器:零知识加密与跨用户兼得

海量大数据是指数据量特别大、数据类别非常大的数据集&#xff0c;而这样的数据集无法使用传统的数据库工具进行捕获、管理和处理。 数据量太大&#xff0c;没有地方存放。 服务器硬盘能存储多少数据肯定无法满足如此大量的数据存储需求。 因此&#xff0c;分布式存储系统应运而…

libVLC 动态视频壁纸

在 Windows 上&#xff0c;你可能需要使用 Windows API 来设置壁纸&#xff0c;而在 Linux 上&#xff0c;你可能需要使用某种桌面环境特有的方法。在 macOS 上&#xff0c;这一功能可能受到限制。 效果图如下所示&#xff1a; 以下是一个简单的示例&#xff0c;说明了如何在 …