11

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

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

  • 在 libsvm 文档中,指出:

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

            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)
    

我所说?没有进一步的细节。我可以按顺序分配ID吗?

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

4

4 回答 4

17

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

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

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

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

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

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

假设原始训练数据有三个四特征实例
并且测试数据有一个实例:

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

如果使用线性核,我们有以下
新的训练/测试集:

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 的东西。

于 2010-03-19T10:07:27.003 回答
8

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

对于第一个,语法是:

   >>> 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/stable/auto_examples/svm/plot_custom_kernel.html

于 2010-12-16T08:39:28.163 回答
4

这是一个简单的 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 precomputed
nr_class 2
total_sv 3
rho -1.53​​951
label 1 2
nr_sv 2 1
SV
0.4126650675419768 0:1
0.03174528241667363 0:3
-0.4444103499586504 0:2

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

于 2010-09-13T20:35:40.307 回答
3

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

有关详细信息,请参阅http://scikit-learn.sourceforge.net/modules/svm.html#kernel-functions上的文档。

于 2010-09-11T14:42:23.703 回答