[scikit-learn] using a mask for brain images
Gael Varoquaux
gael.varoquaux at normalesup.org
Fri May 5 01:59:26 EDT 2017
Hi Alle,
I think that what has changed between 2014 and today is that the
coefficients coef are now a 2D array (number of hyperplanes x number of
features). In your case, the first direction is of length one, so you
could just do:
coef = clf.coef_[0]
and your script should work.
The code of the Abraham paper cannot be updated, because papers are not
living objects. However, we are maintaining a package that encodes all
these patterns in higher-level construct: http://nilearn.github.io/
It might be a good idea to use this package, as it is maintained and has
quality assurance.
Best,
Gaël
On Thu, May 04, 2017 at 05:52:27PM +0200, Alle Meije Wink wrote:
> I have a script to classify MRI perfusion maps from healthy subjects and
> patients. For the file IO and the classifier I have started with the example
> code in Abraham et al 2014 [https://arxiv.org/pdf/1412.3919.pdf].
> I use the same classifier as in the paper to produce a back-projected map of
> classification weights, which I then want to 'unmask' like in the paper:
> coef=clf.coef_
> coef=featureselection.inverse_transform(coef)
> and
> map_name='weights_check.nii.gz'
> wmap=np.zeros(mask.shape, dtype=X.dtype)
> wmap[mask]=coef
> img=nb.Nifti1Image(wmap,np.eye(4))
> img.to_filename(map_name)
> But the line "wmap[mask]=coef" throws an error "ValueError: boolean index array
> should have 1 dimension". I tried the example code from the paper and that
> works.
> Is the 'coef' array of back-projected SVM weights in some way different than
> the masked input image? Or am I doing something else wrong? The error suggests
> that the mask array is the problem.
> The complete script is attached.
> Many thanks for your help!
> Alle Meije
> # -*- coding: utf-8 -*-
> """
> classify MR images from controls (CON) and patients (MCI)
> """
> import os
> import numpy as np
> import nibabel as nb
> import sklearn as sl
> from sklearn.feature_selection import f_classif
> from sklearn import svm
> def subj_lists( rootdir='/data/a.wink/MR', starts=['CON','MCI'] ):
> # make and empty list for each patient group
> slists=[]
> for i in range(0,len(starts)):
> slists.append([]);
> # add subjects to the group based on
> for root, dirs, files in os.walk(rootdir):
> for fname in files:
> for i in range(0,len(starts)):
> if fname.startswith(starts[i]):
> slists[i].append(os.path.join(root,fname))
> print('finished building subject lists')
> return slists
> def mk_mask ( subj_lists=[] ):
> # check whether mask can be loaded
> mname='mask_check.nii.gz'
> if os.path.isfile(mname):
> msk=nb.load(mname).get_data()
> # or must be built (values >20% in the subject images and >20% grey matter in the template)
> else:
> num_im=0;
> for i in range(0,len(subj_lists)):
> for fname in subj_lists[i]:
> imdata=nb.load(fname).get_data()
> if 'msk' not in locals():
> msk=np.absolute(imdata)
> else:
> msk=msk+np.absolute(imdata)
> num_im+=1
> msk/=num_im
> msk/=np.amax(msk)
> msk[msk<.2]=0
> msk[msk>0]=1
> grey=nb.load('/usr/local/spm8/apriori/grey.nii').get_data()
> grey[grey<.2]=0
> grey[grey>0]=1
> msk=msk*grey
> img=nb.Nifti1Image(msk,np.eye(4))
> img.to_filename(mname)
> msk=msk.astype(bool)
> print('finished building mask')
> return msk, mname
> def load_images( subj_lists=[], mask=[] ):
> # load all the images, build a matrix X or subjects (rows) * inmask-voxels (columns)
> num_im=0;
> for i in range(0,len(subj_lists)):
> for fname in subj_lists[i]:
> imdata=nb.load(fname).get_data()
> num_im+=1
> print '\r' + str(num_im) +'\r',
> if 'the_matrix' not in locals():
> the_matrix=imdata[mask].T
> else:
> the_matrix=np.vstack((the_matrix,imdata[mask].T))
> print('finished building matrix X')
> return the_matrix
> def main():
> # get the input data
> subjlists = subj_lists()
> y=np.concatenate( ([-1 for _ in range(len(subjlists[0]))],
> [ 1 for _ in range(len(subjlists[1]))]) )
> mask, mas_name = mk_mask(subjlists)
> X = load_images(subjlists,mask)
> print "number of subjects, voxels: %d, %d" % X.shape
> # select features
> featureselection=sl.feature_selection.SelectKBest(f_classif, k=8000)
> X_reduced=featureselection.fit_transform(X,y)
> # classify
> clf=svm.SVC(kernel='linear')
> clf.fit(X_reduced,y)
> # make discrimination map
> coef=clf.coef_
> coef=featureselection.inverse_transform(coef)
> map_name='weights_check.nii.gz'
> wmap=np.zeros(mask.shape, dtype=X.dtype)
> wmap[mask]=coef
> img=nb.Nifti1Image(wmap,np.eye(4))
> img.to_filename(map_name)
> if __name__ == "__main__":
> main()
> _______________________________________________
> scikit-learn mailing list
> scikit-learn at python.org
> https://mail.python.org/mailman/listinfo/scikit-learn
--
Gael Varoquaux
Researcher, INRIA Parietal
NeuroSpin/CEA Saclay , Bat 145, 91191 Gif-sur-Yvette France
Phone: ++ 33-1-69-08-79-68
http://gael-varoquaux.info http://twitter.com/GaelVaroquaux
More information about the scikit-learn
mailing list