主要内容

选择分类高维数据的特征

这个例子展示了如何选择特征来分类高维数据。更具体地说,它展示了如何执行序列特征选择,这是最流行的特征选择算法之一。它还展示了如何使用保留和交叉验证来评估所选特征的性能。

减少特征的数量(维数)在统计学习中很重要。对于许多具有大量特征和有限观测量的数据集,例如生物信息学数据,通常许多特征对于产生期望的学习结果是无用的,并且有限的观测量可能导致学习算法对噪声过拟合。减少特征还可以节省存储和计算时间,并提高可理解性。

减少特征的方法主要有两种:特征选择和特征变换。特征选择算法从原始特征集中选择一个特征子集;特征变换方法是将数据从原来的高维特征空间转化为降维的新空间。

加载数据

血清蛋白质组学模式诊断可用于区分有疾病和无疾病患者的观察。使用表面增强激光解吸和电离(SELDI)蛋白质谱生成剖面模式。这些特征是在特定质量/电荷值下的离子强度水平。

本例使用使用WCX2蛋白阵列生成的高分辨率卵巢癌数据集。经过一些预处理步骤,类似于生物信息学工具箱™示例中显示的步骤预处理原始质谱数据(生物信息学工具箱)时,数据集有两个变量奥林匹克广播服务公司而且grp.的奥林匹克广播服务公司变量由216个观测值和4000个特征组成。中的每个元素grp的对应行定义所属的组奥林匹克广播服务公司属于。

负载ovariancancer;谁
名称大小字节类属性grp 216x1 25056 cell obs 216x4000 3456000 single

将数据划分为训练集和测试集

本例中使用的一些函数调用MATLAB®内置随机数生成函数。要复制本例中显示的准确结果,执行下面的命令将随机数生成器设置为已知状态。否则,结果可能会不同。

rng (8000“旋风”);

训练数据上的性能(再替换性能)并不是模型在独立测试集上性能的一个很好的估计。再置换表现通常会过于乐观。要预测所选模型的性能,您需要评估它在未用于构建模型的另一个数据集上的性能。这里,我们使用cvpartition将数据分为大小为160的训练集和大小为56的测试集。训练集和测试集都有大致相同的组比例grp.我们使用训练数据选择特征,并在测试数据上判断所选特征的性能。这通常被称为拒绝验证。另一种用于评估和选择模型的简单且广泛使用的方法是交叉验证,本例后面将对此进行说明。

holdoutCVP = cvpartition(grp,“坚持”56)
holdoutCVP =保留交叉验证分区NumObservations: 216 NumTestSets: 1 TrainSize: 160 TestSize: 56
dataTrain = obs(holdoutcvs .training,:);grpTrain = grp(holdoutCVP.training);

利用所有特征对数据进行分类的问题

如果不首先减少特征的数量,一些分类算法就会在这个例子中使用的数据集上失败,因为特征的数量远远大于观测的数量。在这个例子中,我们使用二次判别分析(QDA)作为分类算法。如果我们在使用所有特征的数据上应用QDA,如下所示,我们将得到一个误差,因为每组中没有足够的样本来估计协方差矩阵。

试一试yhat = category (obs(test(holdoutCVP),:), dataTrain, grpTrain,“二次”);我显示(ME.message);结束
TRAINING中各组的协方差矩阵必须是正定的。

使用简单的过滤器方法选择特征

我们的目标是通过找到一小组重要的特征来降低数据的维数,这些特征可以提供良好的分类性能。特征选择算法可以大致分为两类:过滤器方法和包装器方法。过滤方法依赖于数据的一般特征来评估和选择特征子集,而不涉及所选择的学习算法(本例中的QDA)。包装器方法使用所选学习算法的性能来评估每个候选特征子集。包装器方法搜索更适合所选学习算法的特征,但如果学习算法需要很长时间运行,它们可能比过滤器方法慢得多。“过滤器”和“包装器”的概念在John G. Kohavi R.(1997)中有描述。“特征子集选择的包装器”,《人工智能》,vol . 32, No.1-2, pp.272-324。此示例显示了筛选器方法的一个实例和包装器方法的一个实例。

过滤器通常用作预处理步骤,因为它们简单快速。生物信息学数据的一种广泛使用的过滤方法是在每个特征上分别应用单变量标准,假设特征之间没有相互作用。

例如,我们可以应用t-测试每个特性并进行比较p的绝对值t-statistics)用于每个特征,以衡量它在分离组方面的有效性。

dataTrainG1 = dataTrain(grp2idx(grpTrain)==1,:);dataTrainG2 = dataTrain(grp2idx(grpTrain)==2,:);[h,p,ci,stat] = ttest2(dataTrainG1,dataTrainG2, dataTrainG2,“Vartype”“不平等”);

为了得到两组在每个特征上的良好分离程度的总体概念,我们绘制了样本的经验累积分布函数(CDF)p值:

ecdf (p);包含(“P值”);ylabel (“提供价值”

大约有35%的功能p-值接近于零,超过50%的特征具有p-values小于0.05,表示在原来的5000个特征中,有超过2500个特征具有较强的判别能力。人们可以根据它们来对这些特征进行分类p的绝对值t-statistic),并从排序列表中选择一些特征。然而,通常很难决定需要多少特性,除非一个人有一些领域知识,或者可以考虑的最大特性数量已经根据外部约束提前规定了。

确定所需特征数量的一个快速方法是在测试集中绘制MCE(错误分类误差,即错误分类的观测值的数量除以观测值的数量)作为特征数量的函数。由于训练集中只有160个观测值,应用QDA的最大特征数量是有限的,否则可能每组中没有足够的样本来估计协方差矩阵。实际上,对于本例中使用的数据,保留分区和两组的大小表明应用QDA的最大允许特征数量约为70个。现在我们计算5到70之间不同数量特征的MCE,并显示MCE作为特征数量的函数。为了合理地估计所选模型的性能,重要的是使用160个训练样本来拟合QDA模型,并计算56个测试观测值(下图中蓝色圆形标记)上的MCE。为了说明为什么再置换误差不是测试误差的一个很好的误差估计,我们还使用红色三角形标记显示了再置换MCE。

[~,featureIdxSortbyP] = sort(p,2);对特征进行排序testMCE = 0 (1,14);resubMCE = 0 (1,14);NFS = 5:5:70;Classf = @(xtrain,ytrain,xtest,ytest)...总和(~ strcmp(欧美、分类(xtest、xtrain ytrain,“二次”)));resubCVP = cvpartition(长度(grp),“resubstitution”
resubCVP = Resubstitution (no partition of data) NumObservations: 216 NumTestSets: 1 TrainSize: 216 TestSize: 216
i = 1:14 fs = featureIdxSortbyP(1:nfs(i));testMCE(i) = crossval(classf,obs(:,fs),grp,“分区”holdoutCVP).../ holdoutCVP.TestSize;resubMCE(i) = crossval(classf,obs(:,fs),grp,“分区”, resubCVP) /...resubCVP.TestSize;结束情节(nfs、testMCE“o”nfs resubMCE,“r ^”);包含(“功能数量”);ylabel (“乎”);传奇({“测试集上的MCE”“Resubstitution MCE”},“位置”“西北”);标题(“简单的过滤器特征选择方法”);

为了方便起见,classf定义为匿名函数。它在给定的训练集上拟合QDA,并返回给定测试集的错误分类样本的数量。如果你正在开发自己的分类算法,你可能想把它放在一个单独的文件中,如下所示:

%函数err = classf(xtrain,ytrain,xtest,ytest)% yfit =分类(xtest,xtrain,ytrain,'二次元');% err = sum(~strcmp(ytest,yfit));

再替代MCE过于乐观。当使用更多的特性时,它会持续下降,当使用超过60个特性时,它会下降到零。然而,如果测试误差增加而再替换误差仍然减少,则可能发生过拟合。当使用15个特征时,这种简单的滤波特征选择方法在测试集上得到最小的MCE。该图显示,当使用20个或更多的特征时,过度拟合开始发生。测试集中最小的MCE为12.5%:

testMCE (3)
Ans = 0.1250

以下是实现最小MCE的前15个特征:

featureIdxSortbyP (1:15)
ans =1×152814 2813 2721 2720 2452 2645 2644 2642 2650 2643 2731 2638 2730 2637 2398

应用顺序特征选择

上述特征选择算法没有考虑特征之间的交互作用;此外,根据各自的排名从列表中选择的特征也可能包含冗余信息,因此并非所有的特征都需要。例如,第一个选择的特征(列2814)和第二个选择的特征(列2813)之间的线性相关系数几乎是0.95。

相关系数(dataTrain (:, featureIdxSortbyP (1)), dataTrain (:, featureIdxSortbyP (2)))
ans =0.9447

这种简单的特征选择过程由于速度快,通常用作预处理步骤。更先进的特征选择算法提高了性能。序列特征选择是应用最广泛的特征选择技术之一。它通过依次添加(前向搜索)或删除(后向搜索)来选择一个特征子集,直到满足特定的停止条件。

在本例中,我们以包装器的方式使用前向顺序特征选择来查找重要的特征。更具体地说,由于分类的典型目标是最小化MCE,因此特征选择过程使用学习算法QDA的MCE对每个候选特征子集执行顺序搜索,作为该子集的性能指标。训练集用于选择特征并拟合QDA模型,测试集用于评估最终选择的特征的性能。在特征选择过程中,为了评估和比较每个候选特征子集的性能,我们对训练集应用分层的10倍交叉验证。我们稍后将说明为什么对训练集应用交叉验证是重要的。

首先,我们为训练集生成一个分层的10倍分区:

tenfoldCVP = cvpartition(grpTrain,“kfold”, 10)
tenfoldCVP = K-fold交叉验证分区NumObservations: 160 NumTestSets: 10 TrainSize: 144 144 144 144 144 144 144 144 144 144 144 144 144 TestSize: 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16

然后我们使用前一节的过滤结果作为预处理步骤来选择特征。例如,我们在这里选择了150个特征:

fs1 = featureIdxSortbyP(1:50 0);

我们对这150个特征应用前向顺序特征选择。这个函数sequentialfs提供一种简单的方法(默认选项)来决定需要多少特性。当发现交叉验证MCE的第一个局部最小值时停止。

fsLocal = sequentialfs(classf,dataTrain(:,fs1),grpTrain,“简历”, tenfoldCVP);

所选特性如下:

fs1 (fsLocal)
ans =1×323378643288

为了评估具有这三个特征的所选模型的性能,我们计算了56个测试样本的MCE。

testmclocalal = crossval(classf,obs(:,fs1(fsLocal)),grp,“分区”...holdoutCVP) / holdoutCVP。TestSize
testmclocalal = 0.0714

由于只选择了三个特征,使用简单的过滤器特征选择方法,MCE仅比最小MCE的一半多一点。

算法可能已经过早地停止了。有时,通过在一个合理的特征数量范围内寻找交叉验证MCE的最小值,可以获得更小的MCE。例如,我们将交叉验证MCE绘制为最多50个特征数量的函数。

[fsCVfor50,historyCV] = sequentialfs(classf,dataTrain(:,fs1),grpTrain,...“简历”tenfoldCVP,“Nf”, 50);情节(historyCV。暴击,“o”);包含(“功能数量”);ylabel (“简历多国评价”);标题(“带有交叉验证的前向顺序特征选择”);

当使用10个特征时,交叉验证MCE达到最小值,该曲线在10个特征到35个特征的范围内保持平坦。此外,当使用超过35个特征时,曲线会上升,这意味着会发生过拟合。

通常情况下,特征越少越好,所以我们在这里挑选了10个特征:

fsCVfor10 = fs1(historyCV.In(10,:))
fsCVfor10 =1×102814 2721 2720 2452 2650 2731 2337 2658 864 3288

为按顺序向前过程中选择的顺序显示这10个特征,我们找到它们第一次成为true的行historyCV输出:

[orderlist,ignore] = find([historyCV.In(1,:);diff(historyCV.In(1:10,:))]');fs1 (orderlist)
ans =1×102337 864 3288 2721 2814 2658 2452 2731 2650 2720

为了评估这10个特征,我们计算了它们在测试集中QDA的MCE。我们得到了目前为止最小的MCE值:

testMCECVfor10 = crossval(classf,obs(:,fsCVfor10),grp,“分区”...holdoutCVP) / holdoutCVP。TestSize
testMCECVfor10 = 0.0357

有趣的是,观察训练集上的再替换MCE值(即,在特征选择过程中不执行交叉验证)作为特征数量的函数:

[fsResubfor50,historyResub] = sequentialfs(classf,dataTrain(:,fs1),...grpTrain,“简历”“resubstitution”“Nf”, 50);情节(1:50,historyCV。暴击,“波”、1:50 historyResub。暴击,“r ^”);包含(“功能数量”);ylabel (“乎”);传奇({“10倍CV MCE”“Resubstitution MCE”},“位置”“不”);

再次,这里的再替代MCE值过于乐观。大多数都小于交叉验证MCE值,并且当使用16个特征时,再替换MCE将趋于零。我们可以在测试集上计算这16个特征的MCE值,看看它们的真实性能:

fsResubfor16 = fs1(historyresubin (16,:));testMCEResubfor16 = crossval(classf,obs(:,fsResubfor16),grp,“分区”...holdoutCVP) / holdoutCVP。TestSize
testMCEResubfor16 = 0.0714

testMCEResubfor16,这16个特征(在特征选择过程中通过置换选择)在测试集上的性能大约是for的两倍testMCECVfor10, 10个特征(在特征选择过程中通过10次交叉验证选择)在测试集上的性能。这再次表明,对于评估和选择特征,再替换误差通常不是一个很好的性能估计。我们可能希望避免使用重复替换错误,不仅在最后的评估步骤中,而且在特征选择过程中。

另请参阅

相关的话题