gpt4 book ai didi

matlab - 使用交叉验证和 F1 分数选择 SVM 参数

转载 作者:行者123 更新时间:2023-11-30 08:37:26 27 4
gpt4 key购买 nike

我需要在 SVM 中调整 C 和 Sigma 时跟踪 F1 分数,例如,下面的代码跟踪准确度,我需要将其更改为 F1-Score,但我无法做到这一点……。

%# read some training data
[labels,data] = libsvmread('./heart_scale');

%# grid of parameters
folds = 5;
[C,gamma] = meshgrid(-5:2:15, -15:2:3);

%# grid search, and cross-validation
cv_acc = zeros(numel(C),1);
for i=1:numel(C)
cv_acc(i) = svmtrain(labels, data, ...
sprintf('-c %f -g %f -v %d', 2^C(i), 2^gamma(i), folds));
end

%# pair (C,gamma) with best accuracy
[~,idx] = max(cv_acc);

%# now you can train you model using best_C and best_gamma
best_C = 2^C(idx);
best_gamma = 2^gamma(idx);
%# ...

我看到了以下两个链接

Retraining after Cross Validation with libsvm

10 fold cross-validation in one-against-all SVM (using LibSVM)

我确实明白,我必须首先在训练数据上找到最佳的 C 和 gamma/sigma 参数,然后使用这两个值进行留一交叉验证分类实验,所以我现在想要的是首先进行网格搜索来调整 C 和 sigma。请我更喜欢使用 MATLAB-SVM 而不是 LIBSVM。下面是我的留一交叉验证分类代码。

... clc
clear all
close all
a = load('V1.csv');
X = double(a(:,1:12));
Y = double(a(:,13));
% train data
datall=[X,Y];
A=datall;
n = 40;
ordering = randperm(n);
B = A(ordering, :);
good=B;
input=good(:,1:12);
target=good(:,13);
CVO = cvpartition(target,'leaveout',1);
cp = classperf(target); %# init performance tracker
svmModel=[];
for i = 1:CVO.NumTestSets %# for each fold
trIdx = CVO.training(i);
teIdx = CVO.test(i);
%# train an SVM model over training instances

svmModel = svmtrain(input(trIdx,:), target(trIdx), ...
'Autoscale',true, 'Showplot',false, 'Method','ls', ...
'BoxConstraint',0.1, 'Kernel_Function','rbf', 'RBF_Sigma',0.1);
%# test using test instances
pred = svmclassify(svmModel, input(teIdx,:), 'Showplot',false);
%# evaluate and update performance object
cp = classperf(cp, pred, teIdx);
end
%# get accuracy
accuracy=cp.CorrectRate*100
sensitivity=cp.Sensitivity*100
specificity=cp.Specificity*100
PPV=cp.PositivePredictiveValue*100
NPV=cp.NegativePredictiveValue*100
%# get confusion matrix
%# columns:actual, rows:predicted, last-row: unclassified instances
cp.CountingMatrix
recallP = sensitivity;
recallN = specificity;
precisionP = PPV;
precisionN = NPV;
f1P = 2*((precisionP*recallP)/(precisionP + recallP));
f1N = 2*((precisionN*recallN)/(precisionN + recallN));
aF1 = ((f1P+f1N)/2);

我已经更改了代码但我犯了一些错误,并且出现了错误,

a = load('V1.csv');
X = double(a(:,1:12));
Y = double(a(:,13));
% train data
datall=[X,Y];
A=datall;
n = 40;
ordering = randperm(n);
B = A(ordering, :);
good=B;
inpt=good(:,1:12);
target=good(:,13);
k=10;
cvFolds = crossvalind('Kfold', target, k); %# get indices of 10-fold CV
cp = classperf(target); %# init performance tracker
svmModel=[];
for i = 1:k
testIdx = (cvFolds == i); %# get indices of test instances
trainIdx = ~testIdx;
C = 0.1:0.1:1;
S = 0.1:0.1:1;
fscores = zeros(numel(C), numel(S)); %// Pre-allocation
for c = 1:numel(C)
for s = 1:numel(S)
vals = crossval(@(XTRAIN, YTRAIN, XVAL, YVAL)(fun(XTRAIN, YTRAIN, XVAL, YVAL, C(c), S(c))),inpt(trainIdx,:),target(trainIdx));
fscores(c,s) = mean(vals);
end
end
end

[cbest, sbest] = find(fscores == max(fscores(:)));
C_final = C(cbest);
S_final = S(sbest);

......

以及功能......

.....
function fscore = fun(XTRAIN, YTRAIN, XVAL, YVAL, C, S)
svmModel = svmtrain(XTRAIN, YTRAIN, ...
'Autoscale',true, 'Showplot',false, 'Method','ls', ...
'BoxConstraint', C, 'Kernel_Function','rbf', 'RBF_Sigma', S);

pred = svmclassify(svmModel, XVAL, 'Showplot',false);

cp = classperf(YVAL, pred)
%# get accuracy
accuracy=cp.CorrectRate*100
sensitivity=cp.Sensitivity*100
specificity=cp.Specificity*100
PPV=cp.PositivePredictiveValue*100
NPV=cp.NegativePredictiveValue*100
%# get confusion matrix
%# columns:actual, rows:predicted, last-row: unclassified instances
cp.CountingMatrix
recallP = sensitivity;
recallN = specificity;
precisionP = PPV;
precisionN = NPV;
f1P = 2*((precisionP*recallP)/(precisionP + recallP));
f1N = 2*((precisionN*recallN)/(precisionN + recallN));
fscore = ((f1P+f1N)/2);

end

最佳答案

所以基本上你想采用你的这一行:

svmModel = svmtrain(input(trIdx,:), target(trIdx), ...
'Autoscale',true, 'Showplot',false, 'Method','ls', ...
'BoxConstraint',0.1, 'Kernel_Function','rbf', 'RBF_Sigma',0.1);

将其放入一个改变 'BoxConstraint''RBF_Sigma' 参数的循环中,然后使用 crossval输出该迭代参数组合的 f1 分数。

您可以使用与 libsvm 代码示例中完全相同的单个 for 循环(即使用 meshgrid1:numel(),这可能更快)或嵌套的 for 循环。我将使用嵌套循环,以便您可以使用两种方法:

C = [0.001, 0.003, 0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30, 100, 300] %// you must choose your own set of values for the parameters that you want to test. You can either do it this way by explicitly typing out a list
S = 0:0.1:1 %// or you can do it this way using the : operator
fscores = zeros(numel(C), numel(S)); %// Pre-allocation
for c = 1:numel(C)
for s = 1:numel(S)
vals = crossval(@(XTRAIN, YTRAIN, XVAL, YVAL)(fun(XTRAIN, YTRAIN, XVAL, YVAL, C(c), S(c)),input(trIdx,:),target(trIdx));
fscores(c,s) = mean(vals);
end
end

%// Then establish the C and S that gave you the bet f-score. Don't forget that c and s are just indexes though!
[cbest, sbest] = find(fscores == max(fscores(:)));
C_final = C(cbest);
S_final = S(sbest);

现在我们只需定义函数fun。文档对乐趣有这样的说法:

fun is a function handle to a function with two inputs, the training subset of X, XTRAIN, and the test subset of X, XTEST, as follows:

testval = fun(XTRAIN,XTEST) Each time it is called, fun should use XTRAIN to fit a model, then return some criterion testval computed on XTEST using that fitted model.

所以乐趣需要:

  • 输出单个 f 分数
  • 将 X 和 Y 的训练集和测试集作为输入。请注意,这些都是实际训练集的子集!将它们视为训练集的训练和验证子集。另请注意,crossval 将为您拆分这些设置!
  • 在训练子集上训练分类器(使用循环中当前的 CS 参数)
  • 在测试(或验证)子集上运行新的分类器
  • 计算并输出性能指标(在您的情况下,您需要 f1 分数)

您会注意到 fun 不能接受任何额外的参数,这就是为什么我将它包装在匿名函数中,以便我们可以传递当前的 CS 值。(即上面的所有 @(...)(fun(...)) 内容。这只是“转换”我们的六个的技巧将参数 fun 转换为 crossval 所需的 4 个参数之一。

function fscore = fun(XTRAIN, YTRAIN, XVAL, YVAL, C, S)

svmModel = svmtrain(XTRAIN, YTRAIN, ...
'Autoscale',true, 'Showplot',false, 'Method','ls', ...
'BoxConstraint', C, 'Kernel_Function','rbf', 'RBF_Sigma', S);

pred = svmclassify(svmModel, XVAL, 'Showplot',false);

CP = classperf(YVAL, pred)

fscore = ... %// You can do this bit the same way you did earlier
end

关于matlab - 使用交叉验证和 F1 分数选择 SVM 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28167652/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com