2017-09-13 3 views
2

J'ai écrit ce que je crois être un simple classificateur SVM [SVM = Support Vector Machine]. "Test" avec des données normalement distribuées avec différents paramètres, le classificateur me renvoie une précision de 50%. Qu'est-ce qui ne va pas?Précision du niveau de chance pour des données clairement séparables

Voici le code, les résultats doivent être reproductibles:

features1 = normrnd(1,5,[100,5]); 
features2 = normrnd(50,5,[100,5]); 
features = [features1;features2]; 
labels = [zeros(100,1);ones(100,1)]; 

%% SVM-Classification 
nrFolds = 10; %number of folds of crossvalidation 
kernel = 'linear'; % 'linear', 'rbf' or 'polynomial' 
C = 1; % C is the 'boxconstraint' parameter. 

cvFolds = crossvalind('Kfold', labels, nrFolds); 


for i = 1:nrFolds       % iterate through each fold 
    testIdx = (cvFolds == i);    % indices test instances 
    trainIdx = ~testIdx;      % indices training instances 

    % train the SVM 
    cl = fitcsvm(features(trainIdx,:), labels(trainIdx),'KernelFunction',kernel,'Standardize',true,... 
    'BoxConstraint',C,'ClassNames',[0,1]); 

    [label,scores] = predict(cl, features(testIdx,:)); 
    eq = sum(labels(testIdx)); 
    accuracy(i) = eq/numel(labels(testIdx)); 

end 

crossValAcc = mean(accuracy) 

Répondre

2

Vous n'êtes pas correctement calculez l'exactitude. Vous devez déterminer le nombre de prédictions correspondant aux données d'origine. Vous résumez simplement le nombre total de 1 dans l'ensemble de test, et non le nombre réel de prédictions correctes.

Par conséquent, vous devez changer votre déclaration eq à ceci:

eq = sum(labels(testIdx) == label); 

Rappelons que labels(testIdx) extrait le véritable label de votre jeu de test et label est les résultats prévus de votre modèle SVM. Cela génère correctement un vecteur de 0/10 signifie que la prédiction ne correspond pas à l'étiquette réelle de l'ensemble de test et 1 signifie qu'ils sont d'accord. Sommer sur chaque fois qu'ils sont d'accord, ou chaque fois que le vecteur est 1 est le moyen de calculer la précision.

+0

oui bug total, l'a réalisé tout à l'heure! question: est-ce que la logique globale est correcte? Je suppose que lorsque je n'optimise pas pour les hyperparamètres (comme ici), alors cette précision de validation est égale à la précision de mon classificateur sur un nouveau test? – Pegah

+1

@Pegah En effet votre logique est parfaitement bien. De plus, si vous n'optimisez pas les hyperparamètres dans ce cas, si l'espace caractéristique est complètement linéairement séparable, votre précision de validation croisée à chaque pli doit correspondre, ce qui signifie que la moyenne doit correspondre à la précision réelle. Vous avez artificiellement fait votre jeu de données avec les moyens étant très différents les uns des autres pour s'assurer qu'il n'y a pas de chevauchement entre les deux distributions de données, ce qui devrait certainement vous donner la même validation croisée à chaque fois. – rayryeng

+1

a un sens, merci beaucoup – Pegah