Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are there any SVM libraries that support custom kernels that can be used with Visual Studio C++?

It seems like every SVM library for C++ is either

  1. Disallowing custom kernels or
  2. Linux exclusive and would be a holy pain to use with Visual Studio.

Are there any SVM libraries currently available that support custom kernels and are usable in Visual Studio (specifically, 2010)?

like image 922
zebra Avatar asked Jan 16 '23 14:01

zebra


1 Answers

Like I said, it's easy to modify libsvm for what you need and here's the explanation: http://www.csie.ntu.edu.tw/~cjlin/libsvm/faq.html#f418

Since I'm not familiar with those two kernels, I just copied the formulas from Google. I hope I got them right :D

A. Histogram intersection kernel (too bad SO doesn't render Latex): SUM(min(x_i, y_i)) -> we can just change the linear kernel and transform it into this one, so, basically, in version 3.12 (latest version), in svm.cpp:

-> line 233 return dot(x[i],x[j]); - you just have to copy the code from the Kernel::dot method and change it accordingly, so something like this:

double sum = 0;
while(x->index != -1 && y->index != -1)
{
    if(x->index == y->index)
    {
        sum += min(x->value, y->value);
        ++x;
        ++y;
    }
    else
    {
        if(x->index > y->index)
            ++x;
        else
            ++y;
    }           
}
return sum;

(for normal test files, x should have the same length as y. I think the else branch exists for special cases when the test or model file contains attributes with value 0, that can be omitted, but if libsvm produces the expected results with a linear kernel, then it will work OK with this modified one also)

-> line 322 return dot(x,y); - same as above

B. Chi-square kernel: SUM((2 x_i y_i) / (x_i + y_i)) - well, let's see... I think we can try again to modify the linear kernel (maybe some of the optimizations for RBF can be exploited in this case, but let's ignore that for now):

-> line 233 becomes:

double sum = 0;
while(x->index != -1 && y->index != -1)
{
    if(x->index == y->index)
    {
        sum += 2 * x->value * y->value / (x->value + y->value);
        ++x;
        ++y;
    }
    else
    {
        if(x->index > y->index)
            ++x;
        else
            ++y;
    }           
}
return sum;

-> line 322 - same as above

PS: The above code is written in notepad and untested. Please don't kill me if it doesn't work and you have to spend two weeks debugging cryptic C code. [sarcasm]For me it worked from the first try.[/sarcasm] Nevertheless, you can debug it easily once you understand the workflow, by putting break points in those two places. If you run into issues, I'd be happy to provide more help, so just let me know if you get stuck.

like image 112
Mihai Todor Avatar answered Jan 20 '23 09:01

Mihai Todor