Python-EEG工具库MNE中文教程(10)-信号空间投影SSP数学原理

更多技术,第一时间送达

projector(投影)和投影背景

projector(投影)(简称proj),也称为信号空间投影(SSP),定义了应用于空间上的EEG或MEG数据的线性操作。

可以将该操作看做是一个矩阵乘法,通过将数据投影到较低维度的子空间来降低数据的秩。

这种投影算子可以同时应用于数据和正向运算,用于源定位。注意,可以使用这样的投影算子来完成EEG平均参考。

它存储在info['projs']中的测量信息中。

下面就结合代码来解释投影原理

导入工具库

import osimport numpy as npimport matplotlib.pyplot as pltfrom mpl_toolkits.mplot3d import Axes3D # noqafrom scipy.linalg import svdimport mne
# 定义绘制3d图像def setup_3d_axes(): ax = plt.axes(projection='3d') ax.view_init(azim=-105, elev=20) ax.set_xlabel('x') ax.set_ylabel('y') ax.set_zlabel('z') ax.set_xlim(-1, 5) ax.set_ylim(-1, 5) ax.set_zlim(0, 5) return ax

什么是projector(投影)?

在最基本的术语中,投影是将一组点转换为另一组点的操作,在这些点上重复投影操作没有效果。

给一个简单的几何示例,请想象三维空间中的点(3,2,5)。

如果太阳在x,y平面正上方,则该点在x,y平面上的投影看起来很像该点投射的阴影:

ax = setup_3d_axes()
# 绘制向量(3, 2, 5)origin = np.zeros((3, 1))point = np.array([[3, 2, 5]]).Tvector = np.hstack([origin, point])ax.plot(*vector, color='k')ax.plot(*point, color='k', marker='o')
# 将向量投影到x,y平面上并将其绘制xy_projection_matrix = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 0]])projected_point = xy_projection_matrix @ pointprojected_vector = xy_projection_matrix @ vectorax.plot(*projected_vector, color='C0')ax.plot(*projected_point, color='C0', marker='o')
# 添加显示投影的虚线箭头arrow_coords = np.concatenate([point, projected_point - point]).flatten()ax.quiver3D(*arrow_coords, length=0.96, arrow_length_ratio=0.1, color='C1', linewidth=1, linestyle='dashed')

注意,使用矩阵乘法来计算点(3,2,5)平面的投影:

=

再次将投影应用于结果,只会再次返回结果:

=

从信息的角度来看,此投影采用了点x,y,z,并删除了有关该点在z方向上位置的信息。现在我们所知道的只是它在x,y平面上的位置。此外,将投影矩阵应用于x,y,z空间中的任何点,都会将其缩小为x,y平面上的对应点。术语是子空间:投影矩阵将原始空间中的点投影到比原始空间低维的子空间中。我们的子空间是x,y平面(而不是y,z平面)的原因是投影矩阵中特定值的直接结果。

示例:投影作为降噪

描述这种“信息丢失”或“投影到子空间”的另一种方式是,投影将测量的秩(或“自由度”)从三维降低到二维。如果您知道z方向上的测量分量只是由于您的测量方法而产生的噪声,而您所关心的只是x和y分量,那么将三维测量投影到x,y平面中就可以看作是一种降噪的形式。

当然,如果所有测量噪声都集中在z方向上,那确实是非常幸运的。您可以直接舍弃z分量,而不必费心构造投影矩阵或进行矩阵乘法。假设为了进行该测量,您必须在测量设备上触动触发器(pull a trigger on a measurement device),并且触动触发器的动作会使设备移动一点。如果您测量触发器的触动是如何影响测量设备的位置,则可以"校正"实际测量值,以“投射”触动触发器的效果。在这里,我们假设触发器的平均效果是将测量设备移动(3,−1,1):

trigger_effect = np.array([[3, -1, 1]]).T

计算正交平面

知道了这一点,我们可以计算一个与触发器作用正交的平面(利用一个穿过原点的平面在给定法向量(A,B,C)的情况下具有方程Ax+By+Cz=0),并将实际测量投影到该平面上。

# 计算与trigger_effect正交的平面x, y = np.meshgrid(np.linspace(-1, 5, 61), np.linspace(-1, 5, 61))A, B, C = trigger_effectz = (-A * x - B * y) / C# 切断z=0以下的平面(只是为了使绘图更精细)mask = np.where(z >= 0)x = x[mask]y = y[mask]z = z[mask]

使用SVD计算投影矩阵

使用奇异值分解(SVD)从trigger_effect向量计算投影矩阵;

放置好投影矩阵后,我们可以投影原始向量(3,2,5)以消除触发器的影响,然后对其进行绘制:

# 计算投影矩阵U, S, V = svd(trigger_effect, full_matrices=False)trigger_projection_matrix = np.eye(3) - U @ U.T
# 将向量投影到正交平面上projected_point = trigger_projection_matrix @ pointprojected_vector = trigger_projection_matrix @ vector
# 绘制trigger_effect及其正交平面ax = setup_3d_axes()ax.plot_trisurf(x, y, z, color='C2', shade=False, alpha=0.25)ax.quiver3D(*np.concatenate([origin, trigger_effect]).flatten(), arrow_length_ratio=0.1, color='C2', alpha=0.5)
# 绘制原始向量ax.plot(*vector, color='k')ax.plot(*point, color='k', marker='o')offset = np.full((3, 1), 0.1)ax.text(*(point + offset).flat, '({}, {}, {})'.format(*point.flat), color='k')
# 绘制投影向量ax.plot(*projected_vector, color='C0')ax.plot(*projected_point, color='C0', marker='o')offset = np.full((3, 1), -0.2)ax.text(*(projected_point + offset).flat, '({}, {}, {})'.format(*np.round(projected_point.flat, 2)), color='C0', horizontalalignment='right')
# 添加投影的虚线箭头arrow_coords = np.concatenate([point, projected_point - point]).flatten()ax.quiver3D(*arrow_coords, length=0.96, arrow_length_ratio=0.1, color='C1', linewidth=1, linestyle='dashed')

与以前一样,投影矩阵会将x,y,z空间中的任何点映射到该平面上,并且一旦某个点投影到该平面上,再次应用投影将不会产生任何效果。因此,很明显,尽管投影点在所有三个x、y和z方向上都有所不同,但是投影点集只有两个有效尺寸(即,它们被约束在一个平面上)。

EEG或MEG信号的投影几乎以相同的方式工作:点x,y,z对应于单个时间点上每个传感器的值,并且投影矩阵根据信号的哪些方面(比如,什么样的噪声)。唯一真正的区别是, 在实际案例中,要处理一系列N维“点”的时间序列(每次采样一个点),而不是单个三维点(x,y,z),其中N通常是几十个或几百个(取决于实验中EEG/MEG系统有多少个传感器)。

由于投影是矩阵运算,因此即使在具有数百个维度和数万个时间点的信号上也可以非常快速地完成投影。

(0)

相关推荐

  • 使用支持向量机SVM进行分类

    SVM, 全称为support vector machines,  翻译过来就是支持向量机.该算法最常见的应用场景就是解决二分类问题,当然也可以用于回归和异常值检测. 首先来理解下什么叫做支持向量,以 ...

  • Open3d 学习计划—11(使用NumPy)

    Open3D是一个开源库,支持快速开发和处理3D数据.Open3D在c++和Python中公开了一组精心选择的数据结构和算法.后端是高度优化的,并且是为并行化而设置的. 本系列学习计划有Blue同学作 ...

  • (2条消息) 基于OpenCV使用OpenPose进行多个人体姿态估计

    目录 1.网络的体系结构 2.下载模型的权重文件 3. 第一步:生成图片对应的输出 3.1 读取神经网络 3.2 读取图像并生成输入blob 3.3 向前通过网络 3.4 样本输出 4. 第二步:关键 ...

  • 基于Opencv的图像单应性转换实战

    重磅干货,第一时间送达 同形转换 我们所常见的都是以这样的方式来处理图像:检测斑点,分割感兴趣的对象等.我们如何将它们从一种形式转换为另一种形式来处理这些图像呢?通过单应矩阵快速转换图像可以实现这个需 ...

  • 什么是单应性矩阵?

    重磅干货,第一时间送达 你们是否知道人工智能正在改变体育产业?AI助教在比赛前和比赛中能帮助教练增强战略决策,通过使用高速相机和可穿戴传感器,人工智能现在可以测量场上每个球员的运动和位置.但是,AI如 ...

  • 基于OpenCV的图像翻转和镜像

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本期,我们将解释如何在Python中实现图像的镜像或翻转.大家只需 ...

  • 线性代数之正交投影

    我们在初中就应该学过投影,那么什么是投影呢?形象点说,就是将你需要投影的东西上的每一点向你要投影的平面作垂线,垂线与平面的交点的集合就是你的投影.注意这里我们的投影是向量的投影,几何的投影(并不一定是 ...

  • 在OpenCV中使用单应性进行姿势估计

    重磅干货,第一时间送达 什么是单应性 单应性是一种平面关系,可将点从一个平面转换为另一个平面.它是3乘3的矩阵,转换3维向量表示平面上的2D点.这些向量称为同构坐标,下面将进行讨论.下图说明了这种关系 ...

  • DL之HNN:基于HNN(subplot)将凌乱数字矩阵图像(模拟手写数字图片)实现转为最相近的阿拉伯数字

    DL:基于HNN将凌乱数字矩阵图像(模拟手写数字图片)实现转为最相近的阿拉伯数字 输出结果 代码设计 #DL:基于HNN将凌乱数字矩阵图像(模拟手写数字图片)实现转为最相近的阿拉伯数字 import ...

  • 将视频里物体移动轨迹绘制到2D平面图中

    小白导读 数据挖掘是一个非常重要的技术.在近些年,数据挖掘为整个社会创造了巨大的财富.但是通过视频信息实现数据挖掘一直是一个比较艰难的过程.本文介绍的将视频中的信息转成平面信息非常有利于进一步的数据挖 ...

  • 使用 OpenCV 将卷积实现为图像过滤器

    卷积简介 卷积是计算机视觉 (CV) 中的一个流行术语.在讨论如何实现 CV 任务时,经常会提到卷积神经网络.因此,任何 CV 追求者都必须完全理解"卷积"一词. 卷积是几个图像处 ...

  • 如何使用OpenCV实现图像均衡???

    重磅干货,第一时间送达 我们已经练习了很多图像处理--操作图像(精确地说是图像矩阵).为此,我们探索了图像的均衡方法,以便在一定程度上增强对比度,以使被处理的图像看起来比原始图像更好,这种技术称为直方 ...

  • 基于OpenCV的位姿估计

    重磅干货,第一时间送达 今天我们的目标是找出我们相对于球场上的位置,从而了解我们在比赛中的全局位置. 01.什么是单应性 单应性是一种平面关系,可将点从一个平面转换为另一个平面.它是一个3乘3的矩阵, ...