在 MATLAB 中使用嵌套 SVM 调整参数
Tune parameters with nested SVM in MATLAB
我有一个包含 20 个测试对象的数据集,其中包含 50 个变量和一个 1
和 0
的结果向量,用于确定它们的状态。我想设置一个嵌套的交叉验证,以便我在内部折叠中执行特征选择以及调整 SVM 的超参数。那么这些参数应该在外折上进行测试。
我以前在使用逻辑回归(使用 sequentialfs)的特征选择方面做过这个,但我不知道如何同时进行特征选择和超参数调整。
一些示例代码是理想的,但是对给定输出的设置和解释的一般解释也会有所帮助,因为我是 SVM 的新手。
特征选择必须向前。如果可能的话,我希望输出是具有参数和所选特征的最佳整体 SVM。当然我也想知道测试集上的错误率。使用的内核是二阶多项式,所以我想只有一个参数需要调整?
此外,我希望它在内部和外部交叉验证上都是 5 倍。
编辑:我找到了一些示例代码,它们应该可以满足我的要求,但我似乎无法让它工作。谁能解释一下如何在 MATLAB 中设置它?
https://stats.stackexchange.com/questions/40906/nested-cross-validation-for-classification-in-matlab
我提出以下答案,其中 allData
包含所有数据。每一行都是一个条目,每一列都是一个特征。名为 targets
的变量将包含 objective 类。有了这个假设,我将逐部分解释下面附加的代码。
变量 featSize
将具有特征数。
featSize = size(allData, 2);
变量kFolds
将包含您想要的折叠数。你说5
,但我建议你至少10
,如果你有足够的数据。
kFolds = 5;
结构 bestSVM
将是您需要的 "output"。你可以在最后清除所有变量,除了这个。该结构将包含最佳 SVM 及其参数以及将产生最佳性能的特征索引。
bestSVM = struct('SVMModel', NaN, 'C', NaN, 'FeaturesIdx', NaN, 'Score', Inf);
变量kIdx
将包含基于数据和折叠数的交叉验证指数。它使用matlab的函数crossvalind().
kIdx = crossvalind('Kfold', length(targets), kFolds);
现在,主 outer 循环将 运行 您在 kFolds
中指定的次数,并将准备训练集和测试集( trainData
、testData
)及其对应的目标(trainTarg
、testTarg
)如下:
for k = 1:kFolds
trainData = allData(kIdx~=k, :);
trainTarg = targets(kIdx~=k);
testData = allData(kIdx==k, :);
testTarg = targets(kIdx==k);
现在,我们准备进行特征选择。我们将变量 bestFeatScore
初始化为 Inf
以便稍后我们可以将 SVM 的性能(分数)与该值进行比较(进一步向下可能更有意义)。我们还初始化了一个结构 bestFeatCombo
,它将包含所有可能的特征组合中最好的 SVM
及其相应的特征索引 feat
和参数 C
.
bestFeatScore = inf;
bestFeatCombo = struct('SVM', NaN, 'feat', NaN, 'C', NaN);
特征组合的可能数量是2^featSize - 1
。例如,如果您总共有两个特征,则有 2^2 - 1 = 3
个选择:1) 仅选择特征 1,2) 仅选择特征 2,3) 仅选择特征 1 和 2。因此,我们需要一个 for
循环来遍历所有可能的特征组合。
for b = 1:(2^featSize) - 1
但是,有一个棘手的部分(我相信有更好的解决方案),您需要首先开始选择功能集。我认为这是一个二进制表示问题。假设你总共有三个特征 [f1, f2, f3]
,那么,我们可以说二元向量 [1, 0, 0]
代表特征的选择 f1
并忽略其余部分。将二进制向量传递给 matlab 会给你一个索引错误。所以,我发现解决这个问题的最好方法是使用 matlab 的 find() function that will find the "indices and values of nonzero elements". Thus, if we do featCombo = find([1, 0, 0])
, the variable featCombo
would be equal to 1
. So, what I did was use the variable b
(from the for loop above) that will contain a number indicating the current possible combination of features and convert it to a binary vector of size featSize
using matlab's function de2bi()。例如,de2bi(1, 3)
给出 [1, 0, 0]
,如您所见,它使用左边的数字作为最低位。 de2bi(3, 3)
给出 [1, 1, 0]
,de2bi(5, 3)
给出 [1, 0, 1]
,依此类推。然后,如果您在 de2bi()
上使用 find()
函数,将生成您要从中选择的功能的索引。
featCombo = find(de2bi(b, featSize));
例如,如果featSize = 3
,这个:
for b = 1:(2^featSize) - 1; display(de2bi(b, featSize)); end;
会给你像这样的东西:
1 0 0
0 1 0
1 1 0
0 0 1
1 0 1
0 1 1
1 1 1
结合查找如下:
for b = 1:(2^featSize) - 1; display(find(de2bi(b, featSize))); end;
会给你像这样的东西:
1
2
1 2
3
1 3
2 3
1 2 3
适合用作logical indexing。因此,featCombo
将包含要选择的特征集(带有索引的向量)。
下一部分将为 BoxConstraint C
初始化 grid search 的变量,这也称为超参数(取决于 SVM 类型,您可能有其他参数)。 bestCScore
将包含网格搜索期间 SVM 的最佳性能,bestC
将包含最佳 C
参数,而 bestCSVM
将包含搜索期间训练最好的 SVM。变量 gridC
将包含搜索 space,在我的示例中从 2^-5
、2^-3
到 2^15
。如果您有足够的计算资源,我建议您将 2.^(-5:2:15)
更改为更小的增量,例如 2.^(-5:1:15)
,甚至更小的 2.^(-5:0.1:15)
,但要小心,因为它需要一段时间才能完成.同样,如果你的计算能力低(或时间有限),将间隔增加到 2.^(-5:3:15)
甚至 2.^(-5:4:15)
,知道它会选择不好的超参数。
bestCScore = inf;
bestC = NaN;
bestCSVM = NaN;
gridC = 2.^(-5:2:15);
接下来,我们将开始基于数组gridC
的网格搜索,我们将使用matlab的函数fitcsvm()训练一个SVM。 SVM 使用由 当前折叠 确定的当前 trainData
以及由 featCombo
确定的特定选择特征进行训练。训练目标 trainTarg
也由当前折叠决定。请注意 a) 我正在使用 RBF 内核类型(因为您没有指定它),并且 b) 我让 matlab auto determine 内核规模。如果你想使用另一个内核,这段代码将需要一些修改。
for C = gridC
anSVMModel = fitcsvm(trainData(:, featCombo), trainTarg, ...
'KernelFunction', 'RBF', 'KernelScale', 'auto', ...
'BoxConstraint', C);
下一步是确定 SVM 对该参数、该组特征、该折叠的执行情况。我们使用 SVM 的函数 loss() 来做到这一点。
L = loss(anSVMModel,testData(:, featCombo), testTarg);
如果当前SVM(anSVMModel
)的表现优于之前的最佳表现,我们会将分数保存到bestCScore
,将最佳参数保存到bestC
,将最佳SVM保存到bestC
bestCSVM
。
if L < bestCScore
bestCScore = L;
bestC = C;
bestCSVM = anSVMModel;
end
end
在inner-most循环结束时,我们应该拥有当前特征集的最佳超参数和SVM。因此,如果这个 SVM 对于任何其他特征集的得分高于任何其他先前训练的 SVM,我们将把那个 SVM、那组特征和那个超参数保存到 bestFeatCombo.SVM
给出的结构中,bestFeatCombo.feat
, bestFeatCombo.C` 分别.
if (bestCScore < bestFeatScore) || ...
((bestCScore == bestFeatScore) && ...
(length(featCombo) < length(bestFeatCombo.feat)))
bestFeatScore = bestCScore;
bestFeatCombo.SVM = bestCSVM;
bestFeatCombo.feat = featCombo;
bestFeatCombo.C = bestC;
end
end
但是请注意,在上面的 if
语句中,我在 or
子句中做了一个特例。我是说,如果当前 SVM 的表现(分数)与 迄今为止最好的 相同,但当前 SVM 具有较小的功能集但提供相同的性能,我选择替换目前为止最好的 SVM 使用较少的特征。
现在,在 中间 循环结束时,我们应该拥有针对任何特征集的最佳 SVM,具有最佳超参数 C
(到网格搜索允许的范围)。因此,我们可以将当前最佳(存储在结构bestFeatCombo
中)与迄今为止的总体最佳(存储在结构中)进行比较bestSVM
).
if bestFeatScore < bestSVM.Score
bestSVM.SVMModel = bestFeatCombo.SVM;
bestSVM.C = bestFeatCombo.C;
bestSVM.FeaturesIdx = bestFeatCombo.feat;
bestSVM.Score = bestFeatScore
end
end
到此结束。正如我所说,您想要的输出在 bestSVM
中,其中包含 kFolds
中最好的 SVM,用于最好的特征组合,以及最好的超参数 C
作为允许网格搜索。
我希望这是有道理的。下面是一个使用 matlab 的 fisheriris
数据集的工作示例,该数据集具有 100
个样本和 4
个特征。
工作代码:
load fisheriris
inds = ~strcmp(species,'setosa');
allData = meas(inds,:);
targets = species(inds);
featSize = size(allData, 2);
kFolds = 5; % this is where you specify your number of folds
bestSVM = struct('SVMModel', NaN, ... % this is to store the best SVM
'C', NaN, 'FeaturesIdx', NaN, 'Score', Inf);
kIdx = crossvalind('Kfold', length(targets), kFolds);
for k = 1:kFolds
trainData = allData(kIdx~=k, :);
trainTarg = targets(kIdx~=k);
testData = allData(kIdx==k, :);
testTarg = targets(kIdx==k);
% forward feature selection starts
bestFeatScore = inf;
bestFeatCombo = struct('SVM', NaN, 'feat', NaN, 'C', NaN);
for b = 1:(2^featSize) - 1
% this is to choose the features. e.g. [1 0 0] selects the first
% feature out of three features.
featCombo = find(de2bi(b, featSize));
% this is the grid search for the BoxConstraint
bestCScore = inf;
bestC = NaN;
bestCSVM = NaN;
gridC = 2.^(-5:2:15);
for C = gridC
anSVMModel = fitcsvm(trainData(:, featCombo), trainTarg, ...
'KernelFunction', 'RBF', 'KernelScale', 'auto', ...
'BoxConstraint', C);
L = loss(anSVMModel,testData(:, featCombo), testTarg);
if L < bestCScore % saving best SVM on parameter
bestCScore = L; % selection
bestC = C;
bestCSVM = anSVMModel;
end
end
% saving the best SVM on feature selection
if (bestCScore < bestFeatScore) || ...
((bestCScore == bestFeatScore) && ...
(length(featCombo) < length(bestFeatCombo.feat)))
bestFeatScore = bestCScore;
bestFeatCombo.SVM = bestCSVM;
bestFeatCombo.feat = featCombo;
bestFeatCombo.C = bestC;
end
end
% saving the best SVM over all folds
if bestFeatScore < bestSVM.Score
bestSVM.SVMModel = bestFeatCombo.SVM;
bestSVM.C = bestFeatCombo.C;
bestSVM.FeaturesIdx = bestFeatCombo.feat;
bestSVM.Score = bestFeatScore
end
end
编辑
要同时回答您编辑的问题,您希望在其中对参数选择进行另一个 5 折交叉验证,这是您需要做的。
请将 最里面的 循环更改为如下所示:
% this is the grid search for the BoxConstraint
bestCScore = inf;
bestC = NaN;
gridC = 2.^(-5:2:15);
for C = gridC
% cross validation for parameter C
kIdxC = crossvalind('Kfold', length(trainTarg), kFolds);
L = zeros(1, kFolds);
for kC = 1:kFolds
trainDataC = trainData(kIdxC~=kC, :);
trainTargC = trainTarg(kIdxC~=kC);
testDataC = trainData(kIdxC==kC, :);
testTargC = trainTarg(kIdxC==kC);
anSVMModel = fitcsvm(trainDataC(:, featCombo), trainTargC, ...
'KernelFunction', 'RBF', 'KernelScale', 'auto', ...
'BoxConstraint', C);
L(kC) = loss(anSVMModel,testDataC(:, featCombo), testTargC);
end
L = mean(L);
if L < bestCScore
bestCScore = L;
bestC = C;
end
end
% we need to retrain here and save the SVM for the best C
bestCSVM = fitcsvm(trainData(:, featCombo), trainTarg, ...
'KernelFunction', 'RBF', 'KernelScale', 'auto', ...
'BoxConstraint', bestC);
bestCScore = loss(bestCSVM,testData(:, featCombo), testTarg);
代码使用标准简历。但请注意以下行很重要:
L(kC) = loss(anSVMModel,testDataC(:, featCombo), testTargC);
在这一行中,您将保存所有折叠中的所有表演。但是,请注意,您必须对其进行平均,这就是 CV 的目的。
L = mean(L);
你还需要再训练一次。
我有一个包含 20 个测试对象的数据集,其中包含 50 个变量和一个 1
和 0
的结果向量,用于确定它们的状态。我想设置一个嵌套的交叉验证,以便我在内部折叠中执行特征选择以及调整 SVM 的超参数。那么这些参数应该在外折上进行测试。
我以前在使用逻辑回归(使用 sequentialfs)的特征选择方面做过这个,但我不知道如何同时进行特征选择和超参数调整。
一些示例代码是理想的,但是对给定输出的设置和解释的一般解释也会有所帮助,因为我是 SVM 的新手。
特征选择必须向前。如果可能的话,我希望输出是具有参数和所选特征的最佳整体 SVM。当然我也想知道测试集上的错误率。使用的内核是二阶多项式,所以我想只有一个参数需要调整?
此外,我希望它在内部和外部交叉验证上都是 5 倍。
编辑:我找到了一些示例代码,它们应该可以满足我的要求,但我似乎无法让它工作。谁能解释一下如何在 MATLAB 中设置它?
https://stats.stackexchange.com/questions/40906/nested-cross-validation-for-classification-in-matlab
我提出以下答案,其中 allData
包含所有数据。每一行都是一个条目,每一列都是一个特征。名为 targets
的变量将包含 objective 类。有了这个假设,我将逐部分解释下面附加的代码。
变量 featSize
将具有特征数。
featSize = size(allData, 2);
变量kFolds
将包含您想要的折叠数。你说5
,但我建议你至少10
,如果你有足够的数据。
kFolds = 5;
结构 bestSVM
将是您需要的 "output"。你可以在最后清除所有变量,除了这个。该结构将包含最佳 SVM 及其参数以及将产生最佳性能的特征索引。
bestSVM = struct('SVMModel', NaN, 'C', NaN, 'FeaturesIdx', NaN, 'Score', Inf);
变量kIdx
将包含基于数据和折叠数的交叉验证指数。它使用matlab的函数crossvalind().
kIdx = crossvalind('Kfold', length(targets), kFolds);
现在,主 outer 循环将 运行 您在 kFolds
中指定的次数,并将准备训练集和测试集( trainData
、testData
)及其对应的目标(trainTarg
、testTarg
)如下:
for k = 1:kFolds
trainData = allData(kIdx~=k, :);
trainTarg = targets(kIdx~=k);
testData = allData(kIdx==k, :);
testTarg = targets(kIdx==k);
现在,我们准备进行特征选择。我们将变量 bestFeatScore
初始化为 Inf
以便稍后我们可以将 SVM 的性能(分数)与该值进行比较(进一步向下可能更有意义)。我们还初始化了一个结构 bestFeatCombo
,它将包含所有可能的特征组合中最好的 SVM
及其相应的特征索引 feat
和参数 C
.
bestFeatScore = inf;
bestFeatCombo = struct('SVM', NaN, 'feat', NaN, 'C', NaN);
特征组合的可能数量是2^featSize - 1
。例如,如果您总共有两个特征,则有 2^2 - 1 = 3
个选择:1) 仅选择特征 1,2) 仅选择特征 2,3) 仅选择特征 1 和 2。因此,我们需要一个 for
循环来遍历所有可能的特征组合。
for b = 1:(2^featSize) - 1
但是,有一个棘手的部分(我相信有更好的解决方案),您需要首先开始选择功能集。我认为这是一个二进制表示问题。假设你总共有三个特征 [f1, f2, f3]
,那么,我们可以说二元向量 [1, 0, 0]
代表特征的选择 f1
并忽略其余部分。将二进制向量传递给 matlab 会给你一个索引错误。所以,我发现解决这个问题的最好方法是使用 matlab 的 find() function that will find the "indices and values of nonzero elements". Thus, if we do featCombo = find([1, 0, 0])
, the variable featCombo
would be equal to 1
. So, what I did was use the variable b
(from the for loop above) that will contain a number indicating the current possible combination of features and convert it to a binary vector of size featSize
using matlab's function de2bi()。例如,de2bi(1, 3)
给出 [1, 0, 0]
,如您所见,它使用左边的数字作为最低位。 de2bi(3, 3)
给出 [1, 1, 0]
,de2bi(5, 3)
给出 [1, 0, 1]
,依此类推。然后,如果您在 de2bi()
上使用 find()
函数,将生成您要从中选择的功能的索引。
featCombo = find(de2bi(b, featSize));
例如,如果featSize = 3
,这个:
for b = 1:(2^featSize) - 1; display(de2bi(b, featSize)); end;
会给你像这样的东西:
1 0 0
0 1 0
1 1 0
0 0 1
1 0 1
0 1 1
1 1 1
结合查找如下:
for b = 1:(2^featSize) - 1; display(find(de2bi(b, featSize))); end;
会给你像这样的东西:
1
2
1 2
3
1 3
2 3
1 2 3
适合用作logical indexing。因此,featCombo
将包含要选择的特征集(带有索引的向量)。
下一部分将为 BoxConstraint C
初始化 grid search 的变量,这也称为超参数(取决于 SVM 类型,您可能有其他参数)。 bestCScore
将包含网格搜索期间 SVM 的最佳性能,bestC
将包含最佳 C
参数,而 bestCSVM
将包含搜索期间训练最好的 SVM。变量 gridC
将包含搜索 space,在我的示例中从 2^-5
、2^-3
到 2^15
。如果您有足够的计算资源,我建议您将 2.^(-5:2:15)
更改为更小的增量,例如 2.^(-5:1:15)
,甚至更小的 2.^(-5:0.1:15)
,但要小心,因为它需要一段时间才能完成.同样,如果你的计算能力低(或时间有限),将间隔增加到 2.^(-5:3:15)
甚至 2.^(-5:4:15)
,知道它会选择不好的超参数。
bestCScore = inf;
bestC = NaN;
bestCSVM = NaN;
gridC = 2.^(-5:2:15);
接下来,我们将开始基于数组gridC
的网格搜索,我们将使用matlab的函数fitcsvm()训练一个SVM。 SVM 使用由 当前折叠 确定的当前 trainData
以及由 featCombo
确定的特定选择特征进行训练。训练目标 trainTarg
也由当前折叠决定。请注意 a) 我正在使用 RBF 内核类型(因为您没有指定它),并且 b) 我让 matlab auto determine 内核规模。如果你想使用另一个内核,这段代码将需要一些修改。
for C = gridC
anSVMModel = fitcsvm(trainData(:, featCombo), trainTarg, ...
'KernelFunction', 'RBF', 'KernelScale', 'auto', ...
'BoxConstraint', C);
下一步是确定 SVM 对该参数、该组特征、该折叠的执行情况。我们使用 SVM 的函数 loss() 来做到这一点。
L = loss(anSVMModel,testData(:, featCombo), testTarg);
如果当前SVM(anSVMModel
)的表现优于之前的最佳表现,我们会将分数保存到bestCScore
,将最佳参数保存到bestC
,将最佳SVM保存到bestC
bestCSVM
。
if L < bestCScore
bestCScore = L;
bestC = C;
bestCSVM = anSVMModel;
end
end
在inner-most循环结束时,我们应该拥有当前特征集的最佳超参数和SVM。因此,如果这个 SVM 对于任何其他特征集的得分高于任何其他先前训练的 SVM,我们将把那个 SVM、那组特征和那个超参数保存到 bestFeatCombo.SVM
给出的结构中,bestFeatCombo.feat
, bestFeatCombo.C` 分别.
if (bestCScore < bestFeatScore) || ...
((bestCScore == bestFeatScore) && ...
(length(featCombo) < length(bestFeatCombo.feat)))
bestFeatScore = bestCScore;
bestFeatCombo.SVM = bestCSVM;
bestFeatCombo.feat = featCombo;
bestFeatCombo.C = bestC;
end
end
但是请注意,在上面的 if
语句中,我在 or
子句中做了一个特例。我是说,如果当前 SVM 的表现(分数)与 迄今为止最好的 相同,但当前 SVM 具有较小的功能集但提供相同的性能,我选择替换目前为止最好的 SVM 使用较少的特征。
现在,在 中间 循环结束时,我们应该拥有针对任何特征集的最佳 SVM,具有最佳超参数 C
(到网格搜索允许的范围)。因此,我们可以将当前最佳(存储在结构bestFeatCombo
中)与迄今为止的总体最佳(存储在结构中)进行比较bestSVM
).
if bestFeatScore < bestSVM.Score
bestSVM.SVMModel = bestFeatCombo.SVM;
bestSVM.C = bestFeatCombo.C;
bestSVM.FeaturesIdx = bestFeatCombo.feat;
bestSVM.Score = bestFeatScore
end
end
到此结束。正如我所说,您想要的输出在 bestSVM
中,其中包含 kFolds
中最好的 SVM,用于最好的特征组合,以及最好的超参数 C
作为允许网格搜索。
我希望这是有道理的。下面是一个使用 matlab 的 fisheriris
数据集的工作示例,该数据集具有 100
个样本和 4
个特征。
工作代码:
load fisheriris
inds = ~strcmp(species,'setosa');
allData = meas(inds,:);
targets = species(inds);
featSize = size(allData, 2);
kFolds = 5; % this is where you specify your number of folds
bestSVM = struct('SVMModel', NaN, ... % this is to store the best SVM
'C', NaN, 'FeaturesIdx', NaN, 'Score', Inf);
kIdx = crossvalind('Kfold', length(targets), kFolds);
for k = 1:kFolds
trainData = allData(kIdx~=k, :);
trainTarg = targets(kIdx~=k);
testData = allData(kIdx==k, :);
testTarg = targets(kIdx==k);
% forward feature selection starts
bestFeatScore = inf;
bestFeatCombo = struct('SVM', NaN, 'feat', NaN, 'C', NaN);
for b = 1:(2^featSize) - 1
% this is to choose the features. e.g. [1 0 0] selects the first
% feature out of three features.
featCombo = find(de2bi(b, featSize));
% this is the grid search for the BoxConstraint
bestCScore = inf;
bestC = NaN;
bestCSVM = NaN;
gridC = 2.^(-5:2:15);
for C = gridC
anSVMModel = fitcsvm(trainData(:, featCombo), trainTarg, ...
'KernelFunction', 'RBF', 'KernelScale', 'auto', ...
'BoxConstraint', C);
L = loss(anSVMModel,testData(:, featCombo), testTarg);
if L < bestCScore % saving best SVM on parameter
bestCScore = L; % selection
bestC = C;
bestCSVM = anSVMModel;
end
end
% saving the best SVM on feature selection
if (bestCScore < bestFeatScore) || ...
((bestCScore == bestFeatScore) && ...
(length(featCombo) < length(bestFeatCombo.feat)))
bestFeatScore = bestCScore;
bestFeatCombo.SVM = bestCSVM;
bestFeatCombo.feat = featCombo;
bestFeatCombo.C = bestC;
end
end
% saving the best SVM over all folds
if bestFeatScore < bestSVM.Score
bestSVM.SVMModel = bestFeatCombo.SVM;
bestSVM.C = bestFeatCombo.C;
bestSVM.FeaturesIdx = bestFeatCombo.feat;
bestSVM.Score = bestFeatScore
end
end
编辑
要同时回答您编辑的问题,您希望在其中对参数选择进行另一个 5 折交叉验证,这是您需要做的。
请将 最里面的 循环更改为如下所示:
% this is the grid search for the BoxConstraint
bestCScore = inf;
bestC = NaN;
gridC = 2.^(-5:2:15);
for C = gridC
% cross validation for parameter C
kIdxC = crossvalind('Kfold', length(trainTarg), kFolds);
L = zeros(1, kFolds);
for kC = 1:kFolds
trainDataC = trainData(kIdxC~=kC, :);
trainTargC = trainTarg(kIdxC~=kC);
testDataC = trainData(kIdxC==kC, :);
testTargC = trainTarg(kIdxC==kC);
anSVMModel = fitcsvm(trainDataC(:, featCombo), trainTargC, ...
'KernelFunction', 'RBF', 'KernelScale', 'auto', ...
'BoxConstraint', C);
L(kC) = loss(anSVMModel,testDataC(:, featCombo), testTargC);
end
L = mean(L);
if L < bestCScore
bestCScore = L;
bestC = C;
end
end
% we need to retrain here and save the SVM for the best C
bestCSVM = fitcsvm(trainData(:, featCombo), trainTarg, ...
'KernelFunction', 'RBF', 'KernelScale', 'auto', ...
'BoxConstraint', bestC);
bestCScore = loss(bestCSVM,testData(:, featCombo), testTarg);
代码使用标准简历。但请注意以下行很重要:
L(kC) = loss(anSVMModel,testDataC(:, featCombo), testTargC);
在这一行中,您将保存所有折叠中的所有表演。但是,请注意,您必须对其进行平均,这就是 CV 的目的。
L = mean(L);
你还需要再训练一次。