# -*- coding: utf-8 -*-
#
# Authors: Swolf <swolfforever@gmail.com>
# Date: 2021/10/10
# License: MIT License
"""
Task Decomposition Component Analysis.
"""
from typing import Optional, List
import numpy as np
from scipy.linalg import qr
from scipy.stats import pearsonr
from numpy import ndarray
from sklearn.base import BaseEstimator, TransformerMixin, ClassifierMixin
from base import FilterBankSSVEP
"""
-*- coding: utf-8 -*-
DSP: Discriminal Spatial Patterns
Authors: Swolf <swolfforever@gmail.com>
Junyang Wang <2144755928@qq.com>
Last update date: 2022-8-11
License: MIT License
"""
from typing import Optional, List, Tuple
from itertools import combinations
import numpy as np
from scipy.linalg import eigh
from numpy import ndarray
from sklearn.base import BaseEstimator, TransformerMixin, ClassifierMixin
from base import robust_pattern
from base import FilterBankSSVEP
def xiang_dsp_kernel(
X: ndarray, y: ndarray
) -> Tuple[ndarray, ndarray, ndarray, ndarray]:
"""
DSP: Discriminal Spatial Patterns, only for two classes[1]
-Author: Swolf <swolfforever@gmail.com>
-Created on: 2021-1-07
-Update log:
Parameters
----------
X : ndarray
EEG data assuming removing mean, shape (n_trials, n_channels, n_samples)
y : ndarray
labels of EEG data, shape (n_trials, )
Returns
-------
W: ndarray
spatial filters, shape (n_channels, n_filters)
D: ndarray
eigenvalues in descending order
M: ndarray
template for all classes, shape (n_channel, n_samples)
A: ndarray
spatial patterns, shape (n_channels, n_filters)
Notes
-----
the implementation removes regularization on within-class scatter matrix Sw.
References
----------
[1] Liao, Xiang, et al. "Combining spatial filters for the classification of single-trial EEG in
a finger movement task." IEEE Transactions on Biomedical Engineering 54.5 (2007): 821-831.
"""
X, y = np.copy(X), np.copy(y)
labels = np.unique(y)
X = np.reshape(X, (-1, *X.shape[-2:]))
X = X - np.mean(X, axis=-1, keepdims=True)
# the number of each label
n_labels = np.array([np.sum(y == label) for label in labels])
# average template of all trials
M = np.mean(X, axis=0)
# class conditional template
Ms, Ss = zip(
*[
(
np.mean(X[y == label], axis=0),
np.sum(
np.matmul(X[y == label], np.swapaxes(X[y == label], -1, -2)), axis=0
),
)
for label in labels
]
)
Ms, Ss = np.stack(Ms), np.stack(Ss)
# within-class scatter matrix
Sw = np.sum(
Ss
- n_labels[:, np.newaxis, np.newaxis] * np.matmul(Ms, np.swapaxes(Ms, -1, -2)),
axis=0,
)
Ms = Ms - M
# between-class scatter matrix
Sb = np.sum(
n_labels[:, np.newaxis, np.newaxis] * np.matmul(Ms, np.swapaxes(Ms, -1, -2)),
axis=0,
)
D, W = eigh(Sb, Sw)
ix = np.argsort(D)[::-1] # in descending order
D, W = D[ix], W[:, ix]
A = robust_pattern(W, Sb, W.T @ Sb @ W)
return W, D, M, A
def xiang_dsp_feature(
W: ndarray, M: ndarray, X: ndarray, n_components: int = 1
) -> ndarray:
"""
Return DSP features in paper [1]
-Author: Swolf <swolfforever@gmail.com>
-Created on: 2021-1-07
-Update log:
Parameters
----------
W : ndarray
spatial filters from csp_kernel, shape (n_channels, n_filters)
M: ndarray
common template for all classes, shape (n_channel, n_samples)
X : ndarray
eeg test data, shape (n_trials, n_channels, n_samples)
n_components : int, optional
length of the spatial filters, first k components to use, by default 1
Returns
-------
features: ndarray
features, shape (n_trials, n_components, n_samples)
Raises
------
ValueError
n_components should less than half of the number of channels
Notes
-----
1. instead of meaning of filtered signals in paper [1]_., we directly return filtered signals.
References
----------
[1] Liao, Xiang, et al. "Combining spatial filters for the classification of single-trial EEG in
a finger movement task." IEEE Transactions on Biomedical Engineering 54.5 (2007): 821-831.
"""
W, M, X = np.copy(W), np.copy(M), np.copy(X)
max_components = W.shape[1]
if n_components > max_components:
raise ValueError("n_components should less than the number of channels")
X = np.reshape(X, (-1, *X.shape[-2:]))
X = X - np.mean(X, axis=-1, keepdims=True)
features = np.matmul(W[:, :n_components].T, X - M)
return features
class DSP(BaseEstimator, TransformerMixin, ClassifierMixin):
"""
DSP: Discriminal Spatial Patterns
-Author: Swolf <swolfforever@gmail.com>
-Created on: 2021-1-07
-Update log:
Parameters
----------
n_components : int
length of the spatial filter, first k components to use, by default 1
transform_method : str
method of template matching, by default ’corr‘ (pearson correlation coefficient)
classes_ : int
number of the EEG classes
"""
def __init__(self, n_components: int = 1, transform_method: str = "corr"):
self.n_components = n_components
self.transform_method = transform_method
def fit(self, X: ndarray, y: ndarray, Yf: Optional[ndarray] = None):
"""
import the train data to get a model
Parameters
----------
X : ndarray
train data, shape(n_trials, n_channels, n_samples)
y : ndarray
labels of train data, shape (n_trials, )
Yf : ndarray
optional parameter
Returns
-------
W_: ndarray
spatial filters, shape (n_channels, n_filters), in which n_channels = n_filters
D_: ndarray
eigenvalues in descending order, shape (n_filters, )
M_: ndarray
template for all classes, shape (n_channel, n_samples)
A_: ndarray
spatial patterns, shape (n_channels, n_filters)
templates_ : ndarray
templates of train data, shape (n_channels, n_filters, n_samples)
"""
X -= np.mean(X, axis=-1, keepdims=True)
self.classes_ = np.unique(y)
self.W_, self.D_, self.M_, self.A_ = xiang_dsp_kernel(X, y)
self.templates_ = np.stack(
[
np.mean(
xiang_dsp_feature(
self.W_, self.M_, X[y == label], n_components=self.W_.shape[1]
),
axis=0,
)
for label in self.classes_
]
)
return self
def transform(self, X: ndarray):
"""
import the test data to get features
Parameters
----------
X : ndarray
test data, shape(n_trials, n_channels, n_samples)
Returns
-------
feature : ndarray
features of test data, shape(n_trials, n_classes)
"""
n_components = self.n_components
X -= np.mean(X, axis=-1, keepdims=True)
features = xiang_dsp_feature(self.W_, self.M_, X, n_components=n_components)
if self.transform_method is None:
return features.reshape((features.shape[0], -1))
elif self.transform_method == "mean":
return np.mean(features, axis=-1)
elif self.transform_method == "corr":
return self._pearson_features(
features, self.templates_[:, :n_components, :]
)
else:
raise ValueError("non-supported transform method")
def _pearson_features(self, X: ndarray, templates: ndarray):
"""
pearson correlation coefficient
Parameters
----------
X : ndarray
features of test data after sp
没有合适的资源?快使用搜索试试~ 我知道了~
任务判别成分分析法(TDCA)\\(TDCA)main-python程序运行
共21个文件
py:11个
pyc:9个
loc:1个
需积分: 3 3 下载量 112 浏览量
2023-09-12
13:38:52
上传
评论
收藏 67KB RAR 举报
温馨提示
脑机接口(BCI)为大脑和外部设备之间提供了一个直接通信通道。基于稳态视觉诱发电位的脑机接口(SSVEPBCI)因其高信息传输率而受到越来越多的关注。任务相关成分分析法(TRCA)是一种最新的单独校准 SSVEPBCI 的方法。然而,在 TRCA 中,从每个刺激中学习到的空间滤波器可能是冗余的,时间信息没有得到充分利用。针对这一问题,本文提出了一种新方法,即任务判别成分分析法(TDCA),以进一步提高单独校准的 SSVEPBCI 的性能。通过两个公开的基准数据集对 TDCA 的性能进行了评估,结果表明 TDCA 的性能明显优于集合 TRCA 和其他竞争方法。测试 12 名受试者的离线和在线实验进一步验证了 TDCA 的有效性。本研究为设计经过视频校准的 SSVEPBCI 解码方法提供了新的视角,并为其在高速脑拼写应用中的实现提供了启示 ———————————————— 版权声明:本文为CSDN博主「紫钺-高山仰止」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_43158059/articl
资源推荐
资源详情
资源评论
收起资源包目录
fbtdca.rar (21个子文件)
fbtdca
main.py 2KB
utils
__init__.py 112B
download.py 5KB
performance.py 12KB
channels.py 2KB
io.py 3KB
64-channels.loc 2KB
__pycache__
download.cpython-39.pyc 4KB
__init__.cpython-39.pyc 332B
channels.cpython-39.pyc 2KB
io.cpython-39.pyc 3KB
tsinghua.py 17KB
ssvep.py 22KB
model_selection.py 14KB
__pycache__
ssvep.cpython-39.pyc 19KB
tdca.cpython-39.pyc 19KB
model_selection.cpython-39.pyc 11KB
tsinghua.cpython-39.pyc 13KB
base.cpython-39.pyc 18KB
base.py 20KB
tdca.py 22KB
共 21 条
- 1
资源评论
高山仰止景
- 粉丝: 1521
- 资源: 22
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- foldcraftlauncher_262944.apk
- 珍藏多年的基于matlab实现潮流计算程序源代码集合,包含多个潮流计算程序.rar
- 使用FPGA实现串-并型乘法器
- 基于matlab实现针对基于双曲线定位的DV-Hop算法中误差误差出一种基于加权双曲线定位的DV-Hop改进算法.rar
- 基于matlab实现由遗传算法开发的整数规划,车辆调度问题.rar
- 电视家7.0(对电视配置要求高).apk
- 免费计算机毕业设计-基于JavaEE的医院病历管理系统设计与实现(包含论文+源码)
- 手机端 我的世界融合植物大战僵尸版.apk
- 植物大战僵尸 · 戴夫的老年生活 手机版.apk
- Runcraft · 我的世界跑酷游戏 手机端.apk
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功