Python 中使用 LibSVM 预计算内核

发布于 2024-08-26 10:34:31 字数 559 浏览 6 评论 0原文

我已经在网上搜索了大约 3 个小时,但还没有找到解决方案。我想为 libsvm 提供一个预计算内核并对数据集进行分类,但是:

  • 如何生成预计算内核? (例如,虹膜数据的基本预计算内核是什么?)

  • 在libsvm文档中,指出:

    对于预计算内核,每个实例的第一个元素必须是 身份证件。例如,

     样本 = [[1, 0, 0, 0, 0], [2, 0, 1, 0, 1], [3, 0, 0, 1, 1], [4, 0, 1, 1, 2]]
            问题= svm_问题(标签,样本)
            参数 = svm_parameter(kernel_type=PRECOMPUTED)
    

什么是 ID?目前还没有更多细节。我可以按顺序分配 ID 吗?

非常感谢任何 libsvm 帮助和预计算内核的示例。

I've been searching the net for ~3 hours but I couldn't find a solution yet. I want to give a precomputed kernel to libsvm and classify a dataset, but:

  • How can I generate a precomputed kernel? (for example, what is the basic precomputed kernel for Iris data?)

  • In the libsvm documentation, it is stated that:

    For precomputed kernels, the first element of each instance must be
    the ID. For example,

            samples = [[1, 0, 0, 0, 0], [2, 0, 1, 0, 1], [3, 0, 0, 1, 1], [4, 0, 1, 1, 2]]
            problem = svm_problem(labels, samples)
            param = svm_parameter(kernel_type=PRECOMPUTED)
    

What is a ID? There's no further details on that. Can I assign ID's sequentially?

Any libsvm help and an example of precomputed kernels really appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我是有多爱你 2024-09-02 10:34:31

首先,一些内核和 SVM 的背景...

如果你想为 n 个向量(任意维度)预先计算内核,需要做的是计算每对示例之间的核函数。核函数接受两个向量并给出一个标量,因此您可以将预先计算的核视为一个 nxn 标量矩阵。它通常称为核矩阵,有时也称为 Gram 矩阵。

有许多不同的内核,最简单的是线性内核(也称为点积):

sum(x_i * y_i) for i in [1..N] where (x_1,...,x_N) ( y_1,..,y_N) 是向量

其次,试图回答你的问题...

有关 libsvm 中预计算内核的文档实际上非常好...

Assume the original training data has three four-feature instances 
and testing data has one instance:

15  1:1 2:1 3:1 4:1
45      2:3     4:3
25          3:1
15  1:1     3:1

If the linear kernel is used, we have the following 
new training/testing sets:

15  0:1 1:4 2:6  3:1
45  0:2 1:6 2:18 3:0 
25  0:3 1:1 2:0  3:1

15  0:? 1:2 2:0  3:1

第二个中的每个向量示例是内核矩阵中的一行。索引零处的值是 ID 值,它似乎只是一个顺序计数。第一个向量索引 1 处的值是第一个示例中的第一个向量与其自身的核函数值(即 (1x1)+(1x1)+(1x1)+(1x1) = 4),第二个是第一个向量与第二个向量的核函数值(即(1x3)+(1x3)=6)。示例的其余部分也是如此。您可以看到,核矩阵是对称的,它应该是对称的,因为 K(x,y) = K(y,x)。

值得指出的是,第一组向量以稀疏格式表示(即缺失值为零),但内核矩阵不是也不应该是稀疏的。我不知道为什么,这似乎是 libsvm 的事情。

First of all, some background to kernels and SVMs...

If you want to pre-compute a kernel for n vectors (of any dimension), what need to do is calculate the kernel function between each pair of examples. The kernel function takes two vectors and gives a scalar, so you can think of a precomputed kernel as a nxn matrix of scalars. It's usually called the kernel matrix, or sometimes the Gram matrix.

There are many different kernels, the simplest is the linear kernel (also known as the dot product):

sum(x_i * y_i) for i in [1..N] where (x_1,...,x_N) (y_1,..,y_N) are vectors

Secondly, trying to answer your problem...

The documentation about precomputed kernels in libsvm is actually pretty good...

Assume the original training data has three four-feature instances 
and testing data has one instance:

15  1:1 2:1 3:1 4:1
45      2:3     4:3
25          3:1
15  1:1     3:1

If the linear kernel is used, we have the following 
new training/testing sets:

15  0:1 1:4 2:6  3:1
45  0:2 1:6 2:18 3:0 
25  0:3 1:1 2:0  3:1

15  0:? 1:2 2:0  3:1

Each vector here in the second example is a row in the kernel matrix. The value at index zero is the ID value and it just seems to be a sequential count. The value at index 1 of the first vector is the value of the kernel function of the first vector from the first example with itself (i.e. (1x1)+(1x1)+(1x1)+(1x1) = 4), the second is the value of the kernel function of the first vector with the second (i.e. (1x3)+(1x3)=6). It follows on like that for the rest of the example. You can see in that the kernel matrix is symmetric, as it should be, because K(x,y) = K(y,x).

It's worth pointing out that the first set of vectors are represented in a sparse format (i.e. missing values are zero), but the kernel matrix isn't and shouldn't be sparse. I don't know why that is, it just seems to be a libsvm thing.

九公里浅绿 2024-09-02 10:34:31

scikit-learn 在处理自定义内核时隐藏了 libsvm 的大部分细节。您可以只传递任意函数作为内核,它会为您计算 gram 矩阵,也可以传递预先计算的内核 Gram 矩阵。

对于第一个,语法是:

   >>> from scikits.learn import svm
   >>> clf = svm.SVC(kernel=my_kernel)

其中 my_kernel 是你的核函数,然后你可以调用 clf.fit(X, y) 它会为你计算核矩阵。在第二种情况下,语法是:

   >>> from scikits.learn import svm
   >>> clf = svm.SVC(kernel="precomputed")

当您调用 clf.fit(X, y) 时,X 必须是矩阵 k(X, X),其中 k 是您的内核。另请参阅此示例以了解更多详细信息:

http://scikit-learn.org/稳定/auto_examples/svm/plot_custom_kernel.html

scikit-learn hides most of the details of libsvm when handling custom kernels. You can either just pass an arbitrary function as your kernel and it will compute the gram matrix for you or pass the precomputed Gram matrix of the kernel.

For the first one, the syntax is:

   >>> from scikits.learn import svm
   >>> clf = svm.SVC(kernel=my_kernel)

where my_kernel is your kernel function, and then you can call clf.fit(X, y) and it will compute the kernel matrix for you. In the second case the syntax is:

   >>> from scikits.learn import svm
   >>> clf = svm.SVC(kernel="precomputed")

And when you call clf.fit(X, y), X must be the matrix k(X, X), where k is your kernel. See also this example for more details:

http://scikit-learn.org/stable/auto_examples/svm/plot_custom_kernel.html

十年九夏 2024-09-02 10:34:31

这是一个可以正常工作的简单的 2 类 3 向量自定义内核输入文件。我将解释这些部分(尽管你也应该看到 StompChicken 的答案):


1 0:1 1:10 2:12 3:21
2 0:2 1:12 2:19 3:30
1 0:3 1:21 2:30 3:130

每行的第一个数字是它所属的类别。
每行的下一个条目的形式为 0:n,并且必须是连续的,即
第一次参赛时比分是 0:1
第二次进入时 0:2
第三个条目上为 0:3

可能的原因是 libsvm 返回与输出文件中的向量相匹配的值 alpha_i,但对于预先计算的内核,不会显示向量(这可能非常大),而是显示索引 0 :n 与该向量一起显示,以使您的输出更容易与您的输入匹配。特别是因为输出与您放入它们的顺序不同,它是按类别分组的。因此,当您读取输入文件时,能够将 libsvm 的输出与您自己的输入进行匹配以获得这些 0:n 值,这对您非常有用。这里可以看到输出

svm_type c_svc
kernel_type 预计算
nr_class 2
总计 sv 3
ρ-1.53​​951
标签 1 2
nr_sv 2 1
SV
0.4126650675419768 0:1
0.03174528241667363 0:3
-0.4444103499586504 0:2

重要的是要注意,使用预计算内核时,您不能像使用所有其他内核那样省略零条目。它们必须明确包含在内。

Here is a simple two category 3 vector custom kernel input file that works correctly. I will explain the parts (though you should also see StompChicken's answer):


1 0:1 1:10 2:12 3:21
2 0:2 1:12 2:19 3:30
1 0:3 1:21 2:30 3:130

The first number on each line is which category it belongs to.
The next entry on each line is of the form 0:n and it must be sequential, i.e.
0:1 on first entry
0:2 on second entry
0:3 on thrid entry

A possible reason for this is that libsvm returns values alpha_i that go with your vectors in the output file, but for precomputed kernels the vectors are not displayed (which could be truly huge) rather the index 0:n that went with that vector is shown to make your output easier to match up with your input. Especially since the output is not in the same order you put them in it is grouped by category. It is thus very useful for you when reading the input file to be able to match up libsvm's outputs with your own inputs to have those 0:n values. Here you can see the output

svm_type c_svc
kernel_type precomputed
nr_class 2
total_sv 3
rho -1.53951
label 1 2
nr_sv 2 1
SV
0.4126650675419768 0:1
0.03174528241667363 0:3
-0.4444103499586504 0:2

It is important to note that with precomputed kernels you cannot omit the zero entries like you can with all other kernels. They must be explicitly included.

似最初 2024-09-02 10:34:31

我相信 scikit-learn 的 libSVM 的 python 绑定应该可以解决这个问题。

请参阅文档 http://scikit-learn.sourceforge.net/ module/svm.html#kernel-functions ,了解更多信息。

I believe that the scikit-learn's python binding of libSVM should address the problem.

See the documentation at http://scikit-learn.sourceforge.net/modules/svm.html#kernel-functions , for more information.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文