首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在三维空间中分别绘制由sklearn.decomposition.PCA导出的主分量图

在三维空间中分别绘制由sklearn.decomposition.PCA导出的主分量图
EN

Stack Overflow用户
提问于 2020-04-06 14:16:57
回答 1查看 361关注 0票数 1

在我的项目中,我使用三维核磁共振数据,其中第四个维度代表不同的主题(我使用包尼尔温 )。我正在使用sklearn.decomposition.PCA从我的数据中提取给定数量的主成分。现在,我想在大脑图像上分别绘制这些成分,也就是说,我想用我提取的成分(在本例中是2)以不同的颜色显示一个大脑图像。

下面是使用OASIS数据集的示例代码,可以通过尼尔温API下载

  1. 使用nilearn.input_data.NiftiMasker掩蔽,它将我的4维数据转换成2维数组(n_subjects X n_voxels)。
  2. StandardScaler规范数据矩阵
  3. 使用sklearn.decomposition.PCA运行PCA
代码语言:javascript
复制
## set workspace
import numpy as np

from nilearn.datasets import fetch_oasis_vbm
from nilearn.input_data import NiftiMasker
from nilearn.image import index_img

from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.pipeline import Pipeline

from nilearn import plotting

## Load Data  #################################################################

# take only first 30 subjects as example
oasis_dataset = fetch_oasis_vbm(n_subjects=30)
imgs = np.array(oasis_dataset['gray_matter_maps'])

## PIPELINE ###################################################################

# create a random number generator
rng = np.random.RandomState(42)

# Convert Images to 2D Data Array 
niftimasker = NiftiMasker(mask_strategy='template')

# z-standardize images
scaler = StandardScaler()

# Extract 2 Components
pca = PCA(n_components=2,
          svd_solver='full',
          random_state=rng)

# create pipeline
pipe = Pipeline([('niftimasker',niftimasker),
                 ('scaler',scaler),
                 ('pca',pca)])

# call fit_transform on pipeline
X = pipe.fit_transform(imgs)

据我所知,运行PCA后获得的是PCA负载吗?不幸的是,我不明白如何从这得到两个图像,每个图像包含一个PCA组件。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-06 20:16:26

要将数据返回到图像格式,您需要执行一个NiftiMasker.inverse_transform()。要做到这一点,需要在体素空间中保留维数。

所以,现在流水线的工作方式是,在体素空间上使用维数降维。为了减少主题空间中的维度,您将更改以下内容:

代码语言:javascript
复制
pipe = Pipeline([('niftimasker',niftimasker),
             ('scaler',scaler),
#                  ('pca',pca)
            ])

X = pipe.fit_transform(imgs)
X_reduced = pca.fit_transform(X.T).T

然后,您将应用如下逆变换:

代码语言:javascript
复制
component_image = niftimasker.inverse_transform(X_reduced)

然后,要获取每个独立的主题组件映像,您将使用来自nilearn.image的nilearn.image。这是第一个主题组件的图像:

代码语言:javascript
复制
component1_image = index_img(component_image,0)

然而,我认为你对减少体素空间上的幻象感兴趣。因此,为了在逆变换中保留体素维数,需要得到在PCA降维中选择的每个体素特征的索引。按照原来的方式保持管道,并执行以下操作:

代码语言:javascript
复制
X = pipe.fit_transform(imgs)

components = pca.components_
#In your case 2, but replace range(2) with range(n_components)
most_important = [np.abs(components[i]).argmax() for i in range(2)]

然后用x主题和y体素平铺nan数组:(在你的例子中是30x229007)

代码语言:javascript
复制
comp1, comp2 = np.tile(np.nan, [30,229007]), np.tile(np.nan, [30,229007])
for x,y in enumerate(X):
    comp1[x,most_important[0]] = y[0]
    comp2[x,most_important[1]] = y[1]

然后对每个组件应用反向转换:

代码语言:javascript
复制
component1_image = niftimasker.inverse_transform(comp1)
component2_image = niftimasker.inverse_transform(comp2)

现在您将有2个图像,每个图像都有30个主题和一个有效的体素值,表示所选的组件。这取决于您如何在这30个主题上聚合组件体素,在本例中,我将使用来自nilearn.image的平均值图像函数:

代码语言:javascript
复制
mean_component1_image = mean_img(component1_image)
mean_component2_image = mean_img(component2_image)

最后,在这两种情况下分别绘制相应的图像。在体素缩减版本中,您将看到X维(第二个图)中的两个图像有很小的变化,但几乎没有Y和Z。我使用的是来自nilearn.plotting的nilearn.plotting:

代码语言:javascript
复制
plotting.plot_glass_brain(mean_component1_image)
plotting.plot_glass_brain(mean_component2_image)

若要使用覆盖,请调整颜色地图以使其更易于可视化,其他绘图选项请参阅此绘图指南和其他尼尔学绘图指南:

https://nilearn.github.io/plotting/index.html#different-display-modes

如果你还有什么问题请告诉我。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61061896

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档