OpenBMI运动想象--认知科学实践设计

news2024/11/25 14:58:12

目录

一、简要介绍

(一)材料与准备工具

数据集下载

工具箱下载

参考

(二)OpenBMI工具箱介绍

(三)数据集详细介绍

数据拆分

数据解读

二、预处理

(一)目标

(二)特征提取

代码

解释

三、分类器设计

(一)划分方式

第一种不跨被试

第二种不跨被试

跨被试

(二)分类器

不跨被试


一、简要介绍

(一)材料与准备工具

数据集下载

数据集是国外团队实验数据(建议用FTP或者迅雷下载,减少不必要的时间)

这个团队邀请了54位实验人员,做了两天实验,里面有多个范式,只用MI范式就可以了

这个数据的文件名是sess01_subj1_EEG_MI.mat的格式

里面的sess表示是第几天的数据(session1和session2),subj表示被试者(实验人员)

下载地址:GigaDB Dataset - DOI 10.5524/100542 - Supporting data for "EEG Dataset and OpenBMI Toolbox for Three BCI Paradigms: An Investigation into ...

工具箱下载

下载地址:http://openbmi.org

github:GitHub - PatternRecognition/OpenBMI: An open software package dedicated for the development of Brain-Computer Interfaces with various advanced pattern recognition algorithms

参考

这里给出其它作者的一篇博客,这个作者前面的东西非常详细,但是在分类器设计那里使用的是Matlab,不太适合所有人,但还是非常值得参考

参考链接:基于OpenBMI的运动想象分类_半個俗人的博客-CSDN博客_知乎openbmi

(二)OpenBMI工具箱介绍

这个工具箱是国外团队写的工具,使用的是Matlab,它相当于是一个集成的函数、类,使用的时候直接调用就可以了

比如这样,Load_MAT其实是它工具箱的函数

(三)数据集详细介绍

数据拆分

每一个文件,也就是单个session中的某一个subject,例如sess01_subj1_EEG_MI.mat,这个文件中其实包含了两个文件,通过Matlab读取的时候也能发现,一个是train,一个是test,但其实并不是真正意义上的训练集和测试集,train代表的是离线数据,test是在线数据(就是做实验的方式有些许区别),也就是这样理解

数据解读

读取数据后,得到这么一个struct数据(不管是train还是test),因为脑电信号是随时间变化的图像,以下为部分理解

X:输入,可知维度

t:取样时间,这里1X100,表示有100个取样点

fs:取样频率

y_dec:y标签,1表示左,2是右。(这里也知道是一个二分类问题了

y_logic:y标签的逻辑值

y_class:y标签的类

class:类别

chan:通道数,1X62表示是62个通道

time_interval:采样持续时间,这里是4000ms

这个时候,我们能知道特征和标签,之后会经常提到trial(这个概念对后续数据划分设计很重),实际上对应就是y标签的数量,这里实际上是进行了100次间歇性实验,所以有100个结果,那么,一个train或者test对应就是100个trial

二、预处理

(一)目标

看到x的维度非常奇怪,脑电信号有很多通道,自然是非常奇怪。我们要使用一些算法,把某些频率的信号进行增强,然后提取出其中重要的特征,然后作为处理后的输入。

常见的算法有CSP,FCSP等等,这些东西都已经集成在工具箱内,你需要看懂那些函数的输入和输出是什么,然后就可以对x进行滤波操作

(二)特征提取

代码

这里给出我预处理使用的代码,实际上这个代码是从工具箱提供者的论文中搬过来的,所以,有时间一定要去看看原作者的论文,其实他们写的一些东西也非常详细的,你也可以看到分类的准确率,可以与自己的做对比

另外,原作者在后面其实加上了LDA分类器,这个是Matlab实现的,所以就一起写进去了,loss是损失,也就是可以说是错误率

%读取数据集
[CNT_tr,CNT_te] = Load_MAT('./sess02_subj04_EEG_MI.mat');
%训练集预处理
CNT_tr = prep_selectChannels(CNT_tr,{'Index',1:20});%划分电极1到20
CNT_tr = prep_filter(CNT_tr,{'frequency',[8,30]});%划分频率8到30赫兹
SMT_tr = prep_segmentation(CNT_tr,{'interval',[1000,3500]});%数据分段,10ms分一段,为250X20X100(trials)
%得到SMT下一步数据
%测试集预处理
CNT_te = prep_selectChannels(CNT_te,{'Index',1:20});
CNT_te = prep_filter(CNT_te,{'frequency',[8,30]});
SMT_te = prep_segmentation(CNT_te,{'interval',[1000,3500]});
%CSP训练
[CSP_tr,CSP_W] = func_csp(SMT_tr,{'nPatterns',[2]});%csp空间滤波,得到滤波后的训练集、滤波参数,滤波评分
FT_tr=func_featureExtraction(CSP_tr,{'feature','logvar'});%对滤波后的训练集进行特征提取
CF_PARAW=func_train(FT_tr,{'classifier','LDA'});%训练LDA模型,得到分类器参数
%CSP测试
CSP_te = func_projection(SMT_te,CSP_W);%csp空间再滤波,得到滤波后的测试集
FT_te = func_featureExtraction(CSP_te,{'feature','logvar'});%对滤波后的测试集特征提取
cf_out = func_predict(FT_te,CF_PARAW);%输入分类器参数和滤波后的测试集特征,得到结果
loss = eval_calLoss(FT_te.y_dec,cf_out);%将测试集结果和滤波特征结果进行比对

解释

然后你会发现在Matlab左侧出现了一堆变量

Matlab会存储你的每一行代码运行结果,这点我觉得比较可以的,然后,FT变量就是提取出来的特征变量(就是feature的缩写),比如FT_te

进入这个变量,你会发现某些变量变化了,比如x,现在变成了4X100大小,也就是说,CSP滤波提取出了4个特征。

你需要做的就是把这里的x和y_dec作为数据的特征和标签导出来

这里给出我的导出代码,这个也是Matlab代码

FT_tr_x = FT_tr.x;
FT_tr_y = FT_tr.y_dec;
save('E:\learning\data\train\sess02_subj04_FT_tr_x.mat',"FT_tr_x")
save('E:\learning\data\train\sess02_subj04_FT_tr_y.mat',"FT_tr_y")

新建变量存储特征结构体中的x和y,然后用save函数导出(这里只是sess01_subj1_EEG_MI.mat,根据你需要多少trial,以及你的设计方式提取足够的特征数据)

三、分类器设计

(一)划分方式

假如我们把所有的数据集都已经提取过,然后我们需要对数据进行拼接和划分,确定哪些是模型的训练集和测试集,这里数据量仅仅使用前10个subj

这里介绍一下概念,不跨被试的意思就是,仅仅对单个被试者的数据进行建模和预测,不把其它的被试者数据拼接。跨被试的意思就是,将你手上被试者的数据拼接在一起,进行建模和预测

第一种不跨被试

10个分类器,把每个subj的train和test拼接在一起(也就是200个trial),作为不跨被试的数据集,然后对数据集进行交叉验证,至于是几折,则依据情况确定(这个概念不懂的自己去查)

第二种不跨被试

10个分类器,把每个subj的train和test拼接在一起(200个trial),然后以session01作为训练集,session02作为测试集

跨被试

1个分类器,把每个subj的train和test拼接在一起(200个trial),然后9个subj拼接在一起作为训练集,剩余一个作为测试集(其实是留一验证法)

(二)分类器

不跨被试

import pandas
from scipy.io import loadmat
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn import svm
import pandas as pd
def preprocess(data):
    for i in data.keys():
        if i == "FT_tr_x":
            data = data["FT_tr_x"]
        elif i == "FT_tr_y":
            data = data["FT_tr_y"]
        elif i == "FT_te_x":
            data = data["FT_te_x"]
        elif i == "FT_te_y":
            data = data["FT_te_y"]
        else:
            continue
    data = pd.DataFrame(data)
    data = data.T
    return data
x1_train = loadmat("E:\\learning\\data\\train\\sess01_subj01_FT_tr_x.mat")
x1_train = preprocess(x1_train)
x2_train = loadmat("E:\\learning\\data\\test\\sess01_subj01_FT_te_x.mat")
x2_train = preprocess(x2_train)
x_train = pd.concat([x1_train,x2_train])

y1_train = loadmat("E:\\learning\\data\\train\\sess01_subj01_FT_tr_y.mat")
y1_train = preprocess(y1_train)
y2_train = loadmat("E:\\learning\\data\\test\\sess01_subj01_FT_te_y.mat")
y2_train = preprocess(y2_train)
y_train = pd.concat([y1_train,y2_train])

KF = KFold(n_splits=10,random_state=3,shuffle=True)
model = svm.SVC(C=10,kernel='linear',probability=True)
score_accuracy1 = cross_val_score(model,x_train,pd.DataFrame(y_train).values.ravel(),cv=KF,scoring='accuracy',n_jobs=-1)
print(f"SVM准确率:{score_accuracy1.mean()}")

log = LogisticRegression(max_iter=1000)
score_accuracy2 = cross_val_score(log,x_train,pd.DataFrame(y_train).values.ravel(),cv=KF,scoring='accuracy',n_jobs=-1)
print(f"LOG准确率:{score_accuracy2.mean()}")

这里仅仅给出不跨被试的python代码,跨被试的代码太多,平台撰写的时候崩了,不放这里

里面可以看到文件读取操作,这个是绝对路径,如果想让代码正常运行,建议新建一样路径下的文件夹,然后把特征数据这些也放到对应的位置,或者就自己改地址,改到自己电脑中放的位置

我对原特征矩阵进行了转置,因为正常来说列表示特征,行表示样本量,4X100的x就变成了100X4

里面的SVM和Logistic是sklearn中的模型,没有仔细调参,只设置了惩罚系数、最大收敛值、核函数这些,实际上一个模型变量很多(这里建议熟悉机器学习的自己建模,毕竟你已经的到特征和标签了)

这里给出一个sklearn机器学习库的参考博客:【Sklearn】【API详解】【SVM】sklearn.svm.SVC参数详解(一)_拾夕er的博客-CSDN博客_sklearn.svm.svc

最后给出我的源代码链接:

链接:百度网盘 请输入提取码

提取码:2023

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

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

相关文章

Linux安装和入门

文章目录1、课程介绍2、为什么需要Linux3、Linux简介3.1、什么事Linux3.2、Linux优点3.3、常见的Linux系统3.4、小结4、虚拟机安装4.1、引入4.2、常见的虚拟机软件4.3、安装vmware4.4、vmware常用操作4.4.1、全局配置虚拟机(Linux系统)存储位置4.4.2、虚拟机操作5、CentOS安装5…

Python中的消息框对话框tkinter.messagebox

介绍:使用:选择消息框的模式:提示消息框:【返回”ok”】消息警告框【返回”ok”】:错误消息框【返回”ok”】:对话框:询问确认对话框【返回值:yes/no】确认/取消对话框【返回值:True/False】是/…

【Java集合】Set接口及系列子类HashSet等

文章目录Set接口> Set 接口和常用方法> Set接口实现类 - HashSetHashSet 底层机制(HashMap)> Set接口实现类 - LinkedHashSetSet接口 Set 接口介绍: 无序(添加和取出的顺序不一致),没有索引&…

交叉开发环境搭建

ubuntu网络环境搭建 配置网络环境有很多种方法,可以用命令行也可以用图形化界面。ip可以是静态的也可以是动态的。当然要是用SSH访问的话要配置成静态的,但是用校园网的话,又要是动态的,这里就不详细说了。 我们配置ubuntu是为了能…

Java学习路线图(2023版,视频已更新)

PS:注意收藏,此套路线图会不定期更新!点这里跳转:2023年Java程序员学习路线图入门: Java SE基础 → Java Web(含数据库H5jsvue)中级: Maven → Git → SSM框架 → MybatisPlus → Spring Boot→ 《传智健康》项目实战 …

北大硕士LeetCode算法专题课-基础算法查找

算法专题系列: 北大硕士LeetCode算法专题课---算法复杂度介绍_骨灰级收藏家的博客-CSDN博客 北大硕士LeetCode算法专题课-基础算法之排序_骨灰级收藏家的博客-CSDN博客 查找算法 查找算法也可以叫搜索算法。 查找算法就是从一个有序数列中找出一个特定的数&am…

66.物体检测算法:区域卷积神经网络(R-CNN)系列

1. R-CNN ps:在计算机视觉中,深度学习之前,分类器用的是SVM 2. 兴趣区域(RoI)池化层 目的是为了让每个锚框都可以变成一个自己想要的形状。 3. Fast RCNN 具体步骤如下: 对整张图片用CNN抽特征&#xff…

IT服务管理(ITSM)是什么?ITSM工具哪个好用

什么是IT服务管理(ITSM) IT 服务管理 (ITSM) 包含一组策略和实践,这些策略和实践可用于为最终用户实施、交付和管理 IT 服务,以满足最终用户的既定需求和企业的既定目标。 在此定义中,最终用户可以包含员工、客户或业…

一网打尽链表的经典OJ题!链表必考笔试题第一弹

目录 0.前言 1. 移除链表元素 2. 反转链表 2.1 方法一(遍历反转链接关系) 2.2 方法二(节点头插构造新链表) 3.链表的中间节点 4. 链表中倒数第k个节点 5. 总结 0.前言 本文所有代码都已传入gitee,可自取 3链表OJ题p1 onlookerzy123456qwq/data_structu…

使用Electron创建桌面程序,从创建到打包

在桌面程序中,使用C#语言可以创建winform和WPF程序,他们2个在Windows中都非常的优秀,还有就是使用QT开发桌面,可以跨平台开发,这三种都是比较“正规”的,而Electron是使用框架开发桌面程序的,还…

JDBC核心技术_第9章:Apache-DBUtils实现CRUD操作

目录9.1 Apache-DBUtils简介9.2 主要API的使用9.2.1 DbUtils9.2.2 QueryRunner类9.2.3 ResultSetHandler接口及实现类9.1 Apache-DBUtils简介 commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低&#xff0…

硬件设备上也能安全运行小程序

当前,在百度、支付宝、今日头条等各大巨头都把持小程序技术尚未开放的情况下,市面上可商用的小程序技术选择面非常狭窄。与此同时,企业仍希望实现 “一次开发,多端运行”,从而真正达到降本增效。今天为大家分享一下&am…

【c++复习梳理】--基础入门语法

目录 1.函数重载 1.1 函数重载概念 1.2C支持函数重载的原理--名字修饰(name Mangling) 2.引用 2.1 引用概念 2.2 引用特性 2.3 常引用 2.4 使用场景 2.4.1 做参数 2.4.2 做返回值 2.5 传值、传引用效率比较 2.5.1 传值、传引用效率比较--做参数返回 2.5.2 值和引用…

Linux--进程地址空间在线程方面的补充--页表的操作模式 0109

上一篇有关地址空间的博客 (入门自用)--Linux--程序地址空间--程序的创建--0907-0913_Gosolo!的博客-CSDN博客 很久之前写的,最近会完善。 1. 进程地址空间在线程方面的补充 线程由于资源都是从主进程直接拿来的,所以他们的pcb结构体中的地址…

如何让 Shell 提示符更酷炫

使用远程终端时,默认的命令行提示符格式已经能满足大部分用户需求了,但有时我们希望提示符看起来更直观、优雅、酷炫、美观,可以从中直接得到我们想要的信息,而且清晰分明。本文就详细讲解一下如何让 Shell 提示符更酷炫&#xff…

13_9、Java的IO流之NIO.2中Path、Paths、Files类的使用

一、引入1、Java NIO (New IO,Non-Blocking IO)是从Java 1.4版本开始引入的一套新的IO API,可以替代标准的Java IO API。NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的(IO是面向流的)、基于通道的…

cinder对接nfs后端存储

1.部署配置流程 1.安装nfs服务端 可以新增一个节点,或直接使用计算节点,因为存储节点上已经有lvm了这里直接使用计算节点来安装 yum install nfs-utils -y2.修改配置 vi /etc/exports # 要共享的目录 允许的网络1(操做权限) 允许的网络2(操做权限) …

Mybatis源码分析(八)MapperMethod的Select分析

目录一 Select1.1 参数的对应解析convertArgsToSqlCommandParam1.2 ID获取对应的MappedStatement1.3 MappedStatement交给执行器执行1.4 根据参数获取BoundSql1.5 SqlNode节点的解析1.5.1 MixedSqlNode1.5.2 IfSqlNode1.5.3 StaticTextSqlNode1.5.4 TextSqlNode1.6 执行器执行查…

Delete `␍`eslint(prettier/prettier) 错误的解决方案

Delete ‘␍’ eslint(prettier/prettier) 错误的解决方案 问题背景 在Windows笔记本上新拉完代码,在执行pre-commit时,出现如下错误: Delete ␍eslint(prettier/prettier)下面是几种个人尝试过的解决方案: 解决方案 一、Crtl…

【自学Python】Python bytes转string

Python bytes转string Python string转bytes教程 在 Python 中,bytes 类型和 字符串 的所有操作、使用和内置方法也都基本一致。因此,我们也可以实现将 bytes 类型转换成 string 类型。 Python bytes转string方法 Python bytes 转 string 方法主要有…