How can I use fitcsvm and pass parameters to a custom kernel?

How can I use fitcsvm and pass parameters to a custom kernel?
I currently use svmtrain and svmclassify with custom kernels that take parameters. However, I need to use fitcsvm for some of the new functionality it offers.
The fitcsvm example with a custom kernel hard codes the parameter, rather than passing it. This is insufficient for my requirements.
KernelParameters is a read-only structure that is output from fitcsvm, it is not an input.
The only parameter that can be passed into a kernel, is PolynomialOrder, which is only allowed for the polynomial kernel (otherwise fitcsvm returns an error).

 Accepted Answer

As a workaround, you can pass global variables to the kernel functions.

3 Comments

Thank-you Zhaodong. I solved it a while ago, but there is more to the problem and this is worth reading!
Put aside my original question about extra kernel parameters. With fitcsvm you cannot (directly) use a custom kernel defined by: an anonymous function, an object's method, or a nested function. You can use them with svmtrain and svmclassify.
Normally the solution to extra kernel parameters is easy without global variables. I could use an anonymous function myfun=@(u,v)myKernel(u,v,extra_parameters); or since I am using object-oriented code, I could use an object with a method that only takes 2 parameters as input and accesses the extra kernel parameters from the object's private or public data elements.
The problem is Matlab's R2014a code requires a function in a file (.m or MEX), which is "unusual" to say things in a nice way.
To be clear, in the Matlab R2014a code:
/Applications/MATLAB_R2014a.app/toolbox/stats/classreg/+classreg/+learning/+modelparams/SVMParams.m
on line 198 it tests for the existence of a .m file and outputs an error if it is not found:
if exist(kernelfun,'file')==0
So to solve the problem for R2014a, I had to create a .m file and I had to use a global variable with a function handle. Matlab should fix this so that a function handle can be used directly.
function K = myKernelProxy(U,V)
global khandle
K = khandle(U,V);
end
Thank you Andre! Actually after giving my previous answer, I found the same issue as yours. I would appreciate your detailed explanation and the new option. Besides, I solved this problem by using a third-party library, libsvm (probably you have already heard about that). This library provides much more flexibilities on defining the kernel function, since you can directly provide the kernel matrix. Also the solver in libsvm seems to be running faster than svmtrain in Matlab. You can have a try if you like. :)
Thanks Andre! It took me a while to work out what you mean so I will share it for the benefit of others.
The function myKernelProxy is saved as myKernelProxy.m and referenced in the call of fitcsvm() or fitrsvm().
The main script has to look something like this:
global khandle
% define the function handle as required
khandle = @(U,V) myCustomKernel(U,V,gamma);
mdl = fitrsvm(X,y,'KernelFunction','myKernelProxy');
function K = myCustomKernel(u,v,gamma)
% here goes the kernel matrix code with all parameters
D=myDistFcn(u,v);
G=exp(-gamma*D.^2);
end
What I am not yet sure about is how save the global function handle is. I am using this in the context of optimising hyper-parameters and want to use parallel processing. So I need to find out if any handle version could get accessed by the wrong worker.
Any suggestions?

Sign in to comment.

More Answers (0)

Products

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!