I am trying to learn relevant features in a 300*299 training matrix by taking a random row from it as my test data and applying sequentialfs on it. I have used the following code:

>> Md1=fitcdiscr(xtrain,ytrain);
>> func = @(xtrain, ytrain, xtest, ytest) sum(ytest ~= predict(Md1,xtest));
>> learnt = sequentialfs(func,xtrain,ytrain)

xtrain and ytrain are 299*299 and 299*1 respectively. Predict will give me the predicted label for xtest(which is some random row from original xtrain).

However, when I run my code, I get the following error:

Error using crossval>evalFun (line 480)
The function '@(xtrain,ytrain,xtest,ytest)sum(ytest~=predict(Md1,xtest))' generated the following error:
X must have 299 columns.

Error in crossval>getFuncVal (line 497)
funResult = evalFun(funorStr,arg(:));

Error in crossval (line 343)
    funResult = getFuncVal(1, nData, cvp, data, funorStr, []);

Error in sequentialfs>callfun (line 485)
    funResult = crossval(fun,x,other_data{:},...

Error in sequentialfs (line 353)
                crit(k) = callfun(fun,x,other_data,cv,mcreps,ParOptions);

Error in new (line 13)
    learnt = sequentialfs(func,xtrain,ytrain)

Where did I go wrong?


1 Answer 1


func = @(xtrain, ytrain, xtest, ytest) sum(ytest ~= predict(Md1,xtest));

The function "func" is called by sequentialfs, which does not pass "Md1" to the "predict" function. Therefore, Md1 is unknown to that "cost" function. You should include "Md1=fitcdiscr(xtrain,ytrain);" within your "func" function.

Beside, "sequentialfs" does a 10-fold CV. Why are you trying to pass only 299 samples instead of all 300?

  • $\begingroup$ I am using 299 examples to train and 1 random example as xtest. Also, how should I modify my "func" function? $\endgroup$
    – Apurv
    Commented Nov 15, 2016 at 4:20
  • $\begingroup$ Call Md1=fitcdiscr(xtrain,ytrain); inside your "func" function. Save "func" in a seperate file if necessary. Remember, "sequentialfs" will pass 4 arguments (XTRAIN,ytrain,XTEST,ytest) to func. MATLAB is doing a 10-fold CV if you haven't disabled it already. Why would you need that single observation as a test set? $\endgroup$
    – Sal
    Commented Nov 15, 2016 at 4:28
  • $\begingroup$ out of the 300 observations, I am taking one of them at random as my test data. Basically trying to implement cross-validation. Is it not the right way to do it? $\endgroup$
    – Apurv
    Commented Nov 15, 2016 at 4:37
  • $\begingroup$ MATLAB is doing that cross-validation already. You don't need to do it yourself. Just ,make sure you did NOT set 'cv' = 'none' somewhere in your code. $\endgroup$
    – Sal
    Commented Nov 15, 2016 at 4:45
  • $\begingroup$ ok, got it. So my function handle shuld look like this, right: f = @(xtrain, ytrain, xtest, ytest) sum(ytest ~= predict(fitdiscr(xtrain,ytain),xtest))); ? $\endgroup$
    – Apurv
    Commented Nov 15, 2016 at 4:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.