JuliaML / LIBSVM.jl

LIBSVM bindings for Julia
Other
88 stars 35 forks source link

Predict Doesn't work with one class SVM #16

Closed ghost closed 7 years ago

ghost commented 8 years ago

The code for running a classical SVM -- which is directly from the documentation-- works fine: using RDatasets, LIBSVM iris = dataset("datasets", "iris"); labels = iris[:Species]; instances = array(iris[:, 1:4])'; model = svmtrain(labels[1:2:end], instances[:, 1:2:end],svm_type=int32(0),kernel_type=int32(2)); (predicted_labels, decision_values) = svmpredict(model, instances[:, 2:2:end]); @printf "Accuracy: %.2f%%\n" mean((predicted_labels .== labels[2:2:end]))*100;

However, attempting to run a single-class SVM (by changing the "svm_type" to 2) fails. This is true even in simplest case, where i tweak the Iris dataset so all labels of train and test set are identical. using RDatasets, LIBSVM; iris = dataset("datasets", "iris"); labels = iris[:Species]; labels[1:end]="setosa"; instances = array(iris[:, 1:4])'; model = svmtrain(labels[1:2:end], instances[:, 1:2:end],svm_type=int32(2),kernel_type=int32(2)); (predicted_labels, decision_values) = svmpredict(model, instances[:, 2:2:end]); @printf "Accuracy: %.2f%%\n" mean((predicted_labels .== labels[2:2:end]))*100;

The problem appears to come from the following section of svmpredict() output = ccall(fn, Float64, (Ptr{Void}, Ptr{SVMNode}, Ptr{Float64}), model.ptr, nodeptrs[i], pointer(decvalues, nlabels*(i-1)+1)); class[i] = model.labels[int(output)]

For the single class SVM case, the output can sometimes be "-1", whereas there is (obviously) no model label located in position -1 of the array. I'm not sure if "-1" is supposed to represent "the other" class (upon which we haven't trained), or if it's representing an error in the ccall.

mpastell commented 7 years ago

Fixed on master