1
votes

I have a question regarding libsvm predicting accuracy. I generated svm model file using easy.py. Now, when I am trying to predict the test vectors programatically in python, it shows wrongly predicted labels (all 1's) whereas, using easy.py I get an accuracy of 91%.

Each line of my test and train data is in the following format:

1 1:255 2:246 3:218 4:198 5:186 6:168 7:177 8:218 9:255 10:255 11:255 12:255 13:255 14:255 15:255 16:255 17:255 18:255 19:255 20:255 21:255 22:255 23:255 24:255 25:255 26:219 27:185 28:162 29:145 30:144 31:255 32:253 33:228 34:197

The code is as follows, am I doing anything wrong over here?

wimn_model = svm.svm_model("newtraindata.txt.model")
#load model
wimn_f_test=open('newtestdata.txt','r');
#load test data and train data
wimn_f_train=open('newtraindata.txt','r');

ii=0
for eachline in wimn_f_test:
        vec=eachline
        v=vec.split()
        vector={}
        ii=ii+1
        #print v[0]
        wimn_test_labels.append(int(v[0]))
        for i in range(1,len(v)):
                s=v[i].split(":")
                #print s[1]
                vector[i]=int(s[1])
        wimn_test_vectors.append(vector)
print "wimn test "+str(len(wimn_test_vectors))
# get the training and testing vectors and labels.
ii=0        
for eachline in wimn_f_train:
        vec=eachline
        v=vec.split()
        vector={}
        ii=ii+1
        wimn_train_labels.append(int(v[0]))
        #print v[0]
        for i in range(1,len(v)):
                s=v[i].split(":")
                #print s[1]
                vector[i]=int(s[1])
        wimn_train_vectors.append(vector)
print "wimn train "+str( len(wimn_train_vectors))

s=len(wimn_train_labels)
for i_s in range(0,s):
        #print i_s
        ww.append(wimn_model.predict(wimn_train_vectors[i_s]))

# wrongly predicted labels are in ww. correct labels are in wimn_train_labels, wimn_test_labels.
1
Why do you give the data in a dict instead of list/tuple? Also, what is your libsvm version? - highBandWidth
by default libsvm maximizes accuracy, (TP+TN)/ALL, which in a binary problem with majority of samples coming from one class results in labelling all data with one label. Maximize F-score (2*precision*recall)/(precision+recall), instead. - matcheek
I figured out the solution. For some reason libsvm (libsvm 3.0 is the version I use) predicts wrong class labels when I try to predict it with original test_data it predicts all as 1's. But, when I try to predict it with scaled test_data, it predicts the right values (as expected from output of executing easy.py ) @highbandwidth: I use libsvm 3.0 (though 3.1 is out there). I am reading the test vectors as a list of dicts with each dict representing a feature vector. I found some tutorial on the web using the same, so I did the same. - garak

1 Answers

0
votes

One needs to load the scaled input values in order to get the predicted values. The problem got solved.

But there seems to be some dis-similarity between easy.py generated predicted labels and the ones when I load a model and predict the labels.

There is no proper documentation on libsvm on the web.