2016-04-18 91 views
0

我想使用庫LIBSVM對策略'one against all'對5個測試圖像進​​行分類,以便獲得每個策略的概率類。所使用的代碼波紋管:libsvm matlab中的2個錯誤「模型不支持概率估計和下標分配維度不匹配」

load('D:\xapp.mat'); 
load('D:\xtest.mat'); 
load('D:\yapp.mat');%% matrix contains true class of images yapp=[641;645;1001;1010;1100] 
load('D:\ytest.mat');%% matrix contains unlabeled class of test set ytest=[1;2;3;4;5] 
numLabels=max(yapp); 
numTest=size(ytest,1); 
%# train one-against-all models 
model = cell(numLabels,1); 
for k=1:numLabels 
    model{k} = svmtrain(double(yapp==k),xapp, ['-c 1000 -g 10 -b 1 ']); 
end 
%# get probability estimates of test instances using each model 
prob = zeros(numTest,numLabels); 
for k=1:numLabels 
    [~,~,p] = svmpredict(double(ytest==k), xtest, 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 == ytest) ./ numel(ytest) %# accuracy 

我得到這個錯誤:

型號不支持probabiliy估計
下標的轉讓尺寸不匹配。
錯誤排版(線98)
概率(:,K)= P(:,模型{K} .Label == 1);班%#概率==ķ

請幫我提前解決這個錯誤,並感謝

+0

我估計錯誤在行numLabels = MAX(YAPP);'。在這一行中,你基本上說有1100個標籤,而這是不正確的,因爲你有5個標籤。如果'yapp = [641; 645; 1001; 1010; 1100]',那麼類的數量是'length(yapp)',而不是'max(yapp)'。 – Alessiox

+0

感謝您的回覆,澄清:xapp代表訓練集,xtest包含測試集。我知道proplem來自這行numLabels = max(yapp);但是當我用長度替換max(yapp)時,我得到相同的錯誤。感謝您的任何建議 – aya

+0

你還應該注意'double(yapp == k)'這一行。使用'k'從1到'numLabels'和'yapp',它的範圍是[[641; 645; 1001; 1010; 1100]],這個相等性將永遠不會被驗證。我不認爲這會消除這個錯誤,但是你會得到所有類的全零標籤,並且這永遠不會導致正確的結果。 – Alessiox

回答

0

什麼你正在試圖做的是使用一個代碼段,用於評估SVM分類演出而你的目標是正確估計你的測試集的標籤。

我假設你的五個標籤[641;645;1001;1010;1100](如yapp)。首先你必須刪除ytest,因爲你不知道測試集的任何標籤。用ytest填充一些虛擬值是毫無意義的:SVM將返回我們的預測標籤。

第一個錯誤,因爲在評論中已經指出的是

numLabels=max(yapp); 

你必須按順序收集類的數量變化max()length()

訓練階段幾乎是正確的。
考慮到k從1變爲5而yapp的範圍在上面,您應該考慮將double(yapp==k)更改爲double(yapp==yapp(k)):以這種方式,我們將yapp中的第k個值標記爲正值。鑑於k從1變爲5,那麼yapp(k)將從641變爲1100.

而現在是預測階段。
svmpredict()的第一個輸入應該是測試標籤,但現在我們不知道它們,所以我們可以用零矢量填充它(測試集中將有儘可能多的零)。這是因爲如果測試標籤已知,svmpredict()會自動返回精度,但情況並非如此。所以,你必須在第二個for循環改爲

for k=1:numLabels 
    [~,~,p] = svmpredict(zeros(size(xtest,1),1), xtest, model{k}, '-b 1'); 
    prob(:,k) = p(:,model{k}.Label==1); %# probability of class==k 
end 

,最後用

[~,pred] = max(prob,[],2); 

pred包含預測標籤預測標籤。

注1然而,在這種方法中,您不能測量準確度和/或其他參數,因爲我們稱爲測試集實際上不是測試集。一個測試集是一個標籤集,我們假裝我們不知道它的標籤,以便讓SVM預測它們,然後將預測標籤與實際標籤進行匹配,以便測量它的準確性。

注2:由於第二個for-loop,pred中的預測標籤很可能具有範圍1到5的值。但是,由於您的標籤具有不同的值,因此您可以將映射回考慮到1是641,2是645,3是1001,4是1010,5是1100.

+0

我試過這個,但是我得到了一個矩陣pred作爲同伴pred = [5; 5; 5; 5; 5],但實際上類標籤是在[641; 645; 1001; 1010; 1100]。究竟是什麼問題? – aya

+0

@aya,閱讀*注2 * – Alessiox