我想通过使用二进制掩码来应用特征选择。二进制掩码是通过使用模板文件和阈值创建的,因此掩码文件中的 1 和 0 与模板对象中高于或低于该阈值的值相对应。在下一步中,我想使用此掩码“剪切”数据集中的特征,并将此特征选择子集传递给其他后续管道步骤。掩码构建过程和预处理过程都使用关键字参数(例如我刚才提到的阈值),它们可以被视为超参数,因此可以通过嵌套交叉验证进行优化。我怎样才能(或者更好地)在一个管道中实现掩模构建过程的优化和以下管道步骤?
这是使用 nilearn 的 oasis 数据集的示例:
假设我有一个名为 nifti 的文件template
,它用作二进制掩码的模板。我还有来自 30 个主题(特征)及其年龄(标签)的灰质 mri 图像:
import numpy as np
from nilearn import datasets
from sklearn.svm import SVC
from nilearn.input_data import NiftiMasker
from sklearn.preprocessing import Binarizer
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import cross_val_score
from sklearn.pipeline import Pipeline
from nilearn import image
n_subjects = 30
############################################################################
# load template file which serves as mask
template = image.load_img("./template.nii.gz").get_data()
# load oasis dataset
oasis_dataset = datasets.fetch_oasis_vbm(n_subjects=n_subjects)
# load features
X = oasis_dataset.gray_matter_maps
# load labels
age = oasis_dataset.ext_vars['age'].astype(float)
管道应该将模板和特征都作为输入。然后应用嵌套交叉验证来找到最佳超参数。管道必须包含一个切割函数mask_cutter
,该函数将掩码和特征作为输入,并返回原始数据集的特征子集。在这个例子中,阈值set_mask
和 C 参数svc
都应该被优化(注意以下部分是无效的伪代码):
# Set up possible values of parameters to optimize over
p_grid = {
"mask__threshold": np.array([1,2,3]),
"svc__C": np.array([4,5,6])
}
# Binarizer to create binary mask using template
set_mask = Binarizer()
# NiftiMasker to cut out features from X using binary mask
mask_cutter = NiftiMasker()
# Use Support Vector Classification Algorithm
svc = SVC(kernel='linear')
# create pipeline
mask_svc = Pipeline([
('mask',set_mask),
('cut',mask_cutter),
('svc', svc)
])
###########################################################################
grid = GridSearchCV(mask_svc, param_grid=p_grid, cv=3)
nested_cv_scores = cross_val_score(grid, X, age, cv=3)