1

I am using the Matlab 2012 svm included in the stats package. I have a binary classification problem where I train a set of vectors and test another set of vectors as the following matlab code shows:

%set the maximum number of iterations
optSVM = statset('MaxIter', 1000000);       

%train the classifier with a set of feature vectors
SVMtrainModel = svmtrain(training_vectors_matrix(:,2:end), training_vectors_matrix(:,1), 'kernel_function' ,  'linear', 'options', optSVM, 'tolkkt', 0.01);

%read the test vectors 
TestV = csvread(test_file);

%Test the feature vectors in the built classifier
TestAttribBin = svmclassify(SVMtrainModel, TestV(:,2:end))  

It' s a quite simple code and would run normally. The training runs ok, but when I test the following error happens:

Subscript indices must either be real  positive integers or logicals.

Error in svmclassify (line 140) 
outclass= glevels(outclass(~unClassified),:); 

So, are my feature vectors with any problem? If I run this same code in different feature vectors (training and testing vectors) the code runs ok. I already checked the feature vectors and there are no NaNs. What should be the cause of this problem?

mad
  • 2,677
  • 8
  • 35
  • 78
  • 1
    It seems the problem must lie with your data, since you say with different data the code works. It is difficult to answer this without seeing a sample of your data. However, one possibility that comes to mind is that the labels in your training data are possibly not integer values? Have you checked that? Maybe worth comparing the class() of your training labels that work, to those that don't? – jcollomosse May 14 '14 at 11:06
  • 1
    Related: [Subscript indices must either be real positive integers or logicals, generic solution](http://stackoverflow.com/q/20054047/983722) – Dennis Jaheruddin May 14 '14 at 13:21

2 Answers2

4

This should be solvable keeping my generic solution to this problem in mind.

1) Run the code with dbstop if error

It will now stop at the line that you provided:

outclass= glevels(outclass(~unClassified),:);

2) Check the possible solutions.

In this case I assume that glevels and outclass are both variables. The next thing to do would be to carefully examine everything that could be an index.

Starting inside out:

  • The first index is ~unClassified, as the ~ operation did not fail, it is safe to say that this is now a logical vector.
  • The second and lastindex is outclass(~unClassified), this one is most likely not consisting of only numbers like 1,2,3,... or true,false values.

The test whether the values are all valid is quite simple, one of these two should hold:

  • To confirm that the values in x are logical: class(x) should return 'logical'
  • To confirm that the values in x are real positive integers: isequal(x, max(1,round(abs(x)))) should return 'true'.
Community
  • 1
  • 1
Dennis Jaheruddin
  • 21,208
  • 8
  • 66
  • 122
  • Thank so much for your answer. I tried dbstop if error and class(unClassified) returned logical. I am using matlab 2013a, so isequal doesn't exist here. Is there any other way to check it? – mad May 14 '14 at 16:41
  • outclass(~unClassified) returns me the following row vector: ans = -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 - 0.0001i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 - 0.0001i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i – mad May 14 '14 at 16:45
  • unClassified returns me the following row vector: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 – mad May 14 '14 at 16:46
  • outclass returns me the following row vector: -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 - 0.0001i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 - 0.0001i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i -1.0000 + 0.0000i – mad May 14 '14 at 16:49
  • glevels is a row vector with -1 and +1 – mad May 14 '14 at 16:59
  • 2
    @mad The fist element of `outclass(~unClassified)` is -1. Of course you cannot access the -1-th row of `glevels` so the error message is accurate. --- Assuming that you are using the standard `svmclassify` and `svmtrain` it is safe to assume that the error is not in the progam, but because you input invalid data. However, if you can't find the problem with your data, and want to find out more it should be helpfull to track back the error and see where the first irregular things happen. – Dennis Jaheruddin May 14 '14 at 18:24
  • You are right, now I know what is wrong with my data. My training matrix is of type complex double, but I don't know why it is. This matrix is lots of double matrices vertically concatenated. How can I convert this complex double matrix to double matrix? – mad May 14 '14 at 20:14
  • @mad That is actually a different question. However, no matter how many matrices there are. If you just concatenate real matrices you will never end up with a complex matrix. Therefore I suspect that one of the source matrices is complex (or you do some very strange concatenation). – Dennis Jaheruddin May 15 '14 at 07:59
  • 1
    @mad No offense, but as MATLAB is quite a stable product, and matrix concatenation is a basic oparation for this language...It seems much more likely that there is either dirt in your data, or a bug in the code that you use, rather than a bug in MATLAB itself. It is up to you ofcourse, but I would still be interested in digging to the point where the imaginary matrices come into existence. – Dennis Jaheruddin May 19 '14 at 09:04
  • You are right. I checked again and some of my matrices (very few) are complex double. But the weird thing is that all matrices are calculated in the same way, but some are double and others are complex double. These matrices are statistics calculated over 5x6 grids in images. I still don't now why some images resulted in complex statistical values and others did not. I am still checking, thank you for your help. – mad May 19 '14 at 16:18
1

This problem can be solve if you remove your NaN rows or data:

    Features(~any(~isnan(Features), 2),:)=[];

maybe you have complex numbers too, then use this code:

    Features3(any(isnan(Features3),2),:)=0;
    Features3 =real(Features3);

first line, make all NaN values turn to zero and the second line turns all complex numbers to be real.