在我的项目中,我使用三维核磁共振数据,其中第四个维度代表不同的主题(我使用包尼尔温 )。我正在使用sklearn.decomposition.PCA从我的数据中提取给定数量的主成分。现在,我想在大脑图像上分别绘制这些成分,也就是说,我想用我提取的成分(在本例中是2)以不同的颜色显示一个大脑图像。
下面是使用OASIS数据集的示例代码,可以通过尼尔温API下载
nilearn.input_data.NiftiMasker掩蔽,它将我的4维数据转换成2维数组(n_subjects X n_voxels)。StandardScaler规范数据矩阵sklearn.decomposition.PCA运行PCA## 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组件。
发布于 2020-04-06 20:16:26
要将数据返回到图像格式,您需要执行一个NiftiMasker.inverse_transform()。要做到这一点,需要在体素空间中保留维数。
所以,现在流水线的工作方式是,在体素空间上使用维数降维。为了减少主题空间中的维度,您将更改以下内容:
pipe = Pipeline([('niftimasker',niftimasker),
('scaler',scaler),
# ('pca',pca)
])
X = pipe.fit_transform(imgs)
X_reduced = pca.fit_transform(X.T).T然后,您将应用如下逆变换:
component_image = niftimasker.inverse_transform(X_reduced)然后,要获取每个独立的主题组件映像,您将使用来自nilearn.image的nilearn.image。这是第一个主题组件的图像:
component1_image = index_img(component_image,0)然而,我认为你对减少体素空间上的幻象感兴趣。因此,为了在逆变换中保留体素维数,需要得到在PCA降维中选择的每个体素特征的索引。按照原来的方式保持管道,并执行以下操作:
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)
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]然后对每个组件应用反向转换:
component1_image = niftimasker.inverse_transform(comp1)
component2_image = niftimasker.inverse_transform(comp2)现在您将有2个图像,每个图像都有30个主题和一个有效的体素值,表示所选的组件。这取决于您如何在这30个主题上聚合组件体素,在本例中,我将使用来自nilearn.image的平均值图像函数:
mean_component1_image = mean_img(component1_image)
mean_component2_image = mean_img(component2_image)最后,在这两种情况下分别绘制相应的图像。在体素缩减版本中,您将看到X维(第二个图)中的两个图像有很小的变化,但几乎没有Y和Z。我使用的是来自nilearn.plotting的nilearn.plotting:
plotting.plot_glass_brain(mean_component1_image)
plotting.plot_glass_brain(mean_component2_image)若要使用覆盖,请调整颜色地图以使其更易于可视化,其他绘图选项请参阅此绘图指南和其他尼尔学绘图指南:
https://nilearn.github.io/plotting/index.html#different-display-modes
如果你还有什么问题请告诉我。
https://stackoverflow.com/questions/61061896
复制相似问题