2012-01-21 13 views
12

मुझे पता है कि LIBSVM बहु-वर्ग एसवीएम की बात करते समय केवल एक बनाम एक वर्गीकरण की अनुमति देता है। हालांकि, मैं इसे एक-विरुद्ध-वर्गीकरण करने के लिए थोड़ा सा ट्विक करना चाहता हूं। मैंने नीचे एक-एक-एक करके प्रदर्शन करने की कोशिश की है। क्या यह सही दृष्टिकोण है?मल्टी-क्लास एसवीएम (सभी बनाम एक)

कोड:

TrainLabel;TrainVec;TestVec;TestLaBel; 
u=unique(TrainLabel); 
N=length(u); 
if(N>2) 
    itr=1; 
    classes=0; 
    while((classes~=1)&&(itr<=length(u))) 
     c1=(TrainLabel==u(itr)); 
     newClass=c1; 
     model = svmtrain(TrainLabel, TrainVec, '-c 1 -g 0.00154'); 
     [predict_label, accuracy, dec_values] = svmpredict(TestLabel, TestVec, model); 
     itr=itr+1; 
    end 
itr=itr-1; 
end 

मैं कुछ गलतियों किया है हो सकता है। मैं कुछ फीडबैक सुनना चाहता हूं। धन्यवाद।

दूसरा भाग: अंगूर के रूप में कहा गया: मुझे अंतिम उत्तर के साथ आने के लिए Sum-pooling (या सरलीकृत समाधान के रूप में मतदान) करने की आवश्यकता है। मुझे यकीन नहीं है कि यह कैसे करें। मुझे इसके बारे में कुछ मदद चाहिए; मैंने अजगर फ़ाइल देखी लेकिन अभी भी बहुत यकीन नहीं है। मैं कुछ मदद की जरूरत है।

+0

वास्तव में सवाल क्या है? आप पूछ रहे हैं कि LibSVM के साथ एक-बनाम सभी वर्गीकरण कैसे करें? क्या प्रोग्राम आपके द्वारा अपेक्षित परिणाम आउटपुट करता है? बीटीडब्ल्यू, लिब्सवीएम पैरामीटर '-सी 1-जी 0.00153' होना चाहिए (आपको अंतिम एकल उद्धरण की कमी है)। – grapeot

+0

मैंने प्रश्न संपादित किया है ... – lakesh

+1

@lakesh: मैंने एक समान प्रश्न का उत्तर पोस्ट किया है, तो आपको उपयोगी मिल सकता है: http://stackoverflow.com/a/9049808/97160 – Amro

उत्तर

10
%# Fisher Iris dataset 
load fisheriris 
[~,~,labels] = unique(species); %# labels: 1/2/3 
data = zscore(meas);    %# scale features 
numInst = size(data,1); 
numLabels = max(labels); 

%# split training/testing 
idx = randperm(numInst); 
numTrain = 100; numTest = numInst - numTrain; 
trainData = data(idx(1:numTrain),:); testData = data(idx(numTrain+1:end),:); 
trainLabel = labels(idx(1:numTrain)); testLabel = labels(idx(numTrain+1:end)); 
%# train one-against-all models 
model = cell(numLabels,1); 
for k=1:numLabels 
    model{k} = svmtrain(double(trainLabel==k), trainData, '-c 1 -g 0.2 -b 1'); 
end 

%# get probability estimates of test instances using each model 
prob = zeros(numTest,numLabels); 
for k=1:numLabels 
    [~,~,p] = svmpredict(double(testLabel==k), testData, model{k}, '-b 1'); 
    prob(:,k) = p(:,model{k}.Label==1); %# probability of class==k 
end 

%# predict the class with the highest probability 
[~,pred] = max(prob,[],2); 
acc = sum(pred == testLabel) ./ numel(testLabel) %# accuracy 
C = confusionmat(testLabel, pred)     %# confusion matrix 
4

कोड से मैं देख सकता हूं कि आप लेबल को "कुछ कक्षा" बनाम "इस वर्ग में नहीं" बनाते हैं, और फिर प्रशिक्षण और परीक्षण करने के लिए LibSVM को आमंत्रित करते हैं। कुछ प्रश्न और सुझाव:

  1. प्रशिक्षण के लिए आप मूल TrainingLabel का उपयोग क्यों कर रहे हैं? मेरी राय में, यह model = svmtrain(newClass, TrainVec, '-c 1 -g 0.00154'); होना चाहिए?
  2. संशोधित प्रशिक्षण तंत्र के साथ, आपको भविष्यवाणी भाग को ट्विक करने की भी आवश्यकता है, जैसे कि अंतिम लेबल निर्धारित करने के लिए योग-पूलिंग का उपयोग करना। संभाव्यता आउटपुट सक्षम करने के लिए -b लिबएसवीएम में स्विच करने से सटीकता में सुधार होगा।
+0

बहुत बहुत धन्यवाद ... btw, क्या आप LIBSVM का उपयोग करके एक बनाम एक को कैसे करें? मुझे यकीन नहीं है कि यह कैसे करें ... – lakesh

+1

इनपुट 0 के रूप में 0 <=> 1 या -1 <=> 1 के अलावा बस लेबल डालें। LibSVM इसे पहचान लेगा और बहु-वर्ग वर्गीकरण करने का प्रयास करेगा। – grapeot

+0

तो वह एक बनाम है? – lakesh

1

संभावना अनुमान के बजाय, आप भी निर्णय मूल्यों के रूप में एक ही उद्देश्य को प्राप्त करने

[~,~,d] = svmpredict(double(testLabel==k), testData, model{k}); 
prob(:,k) = d * (2 * model{i}.Label(1) - 1); 

इस प्रकार उपयोग कर सकते हैं।

संबंधित मुद्दे