我一直在网上搜索约3个小时,但我找不到解决方案了。我想给libsvm提供一个预先计算的内核并对数据集进行分类,但是:
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帮助和预先计算的内核的例子都非常感激。
首先,内核和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中预先计算的内核的文档实际上非常好......
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的东西。
scikit-learn在处理自定义内核时隐藏了libsvm的大部分细节。您可以将任意函数作为内核传递,它将为您计算克矩阵或传递内核的预先计算的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/stable/auto_examples/svm/plot_custom_kernel.html
这是一个简单的两个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 在thrid条目上0:3
一个可能的原因是libsvm返回与输出文件中的向量一致的值alpha_i,但是对于预先计算的内核,不显示向量(这可能是真正巨大的)而是显示与该向量一起使用的索引0:n使您的输出更容易与您的输入相匹配。特别是因为输出的顺序不同,所以按类别分组。因此,在读取输入文件时能够将libsvm的输出与您自己的输入匹配以获得那些0:n值非常有用。在这里你可以看到输出
svm_type c_svc kernel_type预先计算好 nr_class 2 total_sv 3 rho -1.53951 标签1 2 nr_sv 2 1 SV 0.4126650675419768 0:1 0.03174528241667363 0:3 -0.4444103499586504 0:2
重要的是要注意,对于预先计算的内核,您不能像所有其他内核一样省略零条目。必须明确包括它们。
我相信scikit-learn的libSVM的python绑定应该解决这个问题。
有关更多信息,请参阅http://scikit-learn.sourceforge.net/modules/svm.html#kernel-functions上的文档。