在R中对SVM(e1071)进行性能分析

5
我刚接触R和SVM,并试图从e1071软件包中剖析svm函数。然而,我找不到任何大型数据集,可以让我通过改变输入数据的大小来得到良好的剖析结果范围。有人知道如何使用svm吗?我应该使用哪个数据集?是否有一些特定的参数可以使svm更加高效?
我贴出了一些用于测试性能的命令。也许这是最有用和最容易理解我在这里尝试的内容:
#loading libraries
library(class)
library(e1071)
#I've been using golubEsets (more examples availables)
library(golubEsets)

#get the data: matrix 7129x38
data(Golub_Train)
n <- exprs(Golub_Train)

#duplicate rows(to make the dataset larger)
n<-rbind(n,n)

#take training samples as a vector
samplelabels <- as.vector(Golub_Train@phenoData@data$ALL.AML)

#calculate svm and profile it
Rprof('svm.out')
svmmodel1 <- svm(x=t(n), y=samplelabels, type='C', kernel="radial", cross=10)
Rprof(NULL)

我一直在增加数据集的行和列来复制数据,但是我到达了内存限制,导致 svm 没有更多余地来工作了...


2
复制训练点并不会使问题更加困难。由于大多数SVM需要整个数据集适合主内存,所以最终会遇到内存错误是有道理的。 - karenu
那么,我该如何使用适当的大数据集进行尝试呢?你知道我可以使用哪个例子吗? - Manolete
1
是的,如果您看到我的答案,我列出了许多可用的数据集。此外,您应该进行参数调整以找到最佳参数,当您搜索给您最高准确度的参数时,您会发现有些参数需要更长时间来训练。请查看libsvm作者的实用指南:http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CFYQFjAA&url=http%3A%2F%2Fwww.csie.ntu.edu.tw%2F~cjlin%2Fpapers%2Fguide%2Fguide.pdf&ei=WtLhT46NO-jw0gG30pHVAw&usg=AFQjCNFol0McRktHC6gsBxKXqQMvmQUFeg - karenu
1
你可以尝试使用GuessCompx包,它在数据的逐渐增大的子集上运行算法来估计其复杂度和总运行时间。从这里获取:https://github.com/agenis/GuessCompx - agenis
1个回答

8

关于“让SVM更加努力工作”的问题——一个更复杂的模型、更高的维度和更大、更密集的数据集会让SVM更加努力工作。

SVM性能下降的情况包括:

  • 数据集大小增加(数据点数量增加)
  • 稀疏度降低(零值减少)
  • 维度增加(属性数量增加)
  • 使用非线性核函数(核参数可能导致核函数评估更加复杂)

改变参数

是否有参数可以使SVM运行时间更长?当然,参数会影响您得到的解的质量,并且可能没有任何意义。

使用C-SVM,改变C将导致不同的运行时间。(nu-SVM中的类似参数为nu)如果数据集是相对可分的,则使C变小会导致运行时间更长,因为SVM将允许更多的训练点成为支持向量。如果数据集不太可分,则使C变大会导致更长的运行时间,因为您实际上是告诉SVM您想要一个紧密地拟合数据的窄边界解,这将在数据不容易分离时需要更长时间计算。

通常在进行参数搜索时,您会发现有些参数会增加计算时间,但并不会显著提高准确性。其他参数是内核参数,如果您改变它们以增加计算内核的复杂性,那么SVM运行时间自然会增加。线性内核简单且速度最快;非线性内核当然需要更长时间。某些参数可能不会增加内核的计算复杂性,但会强制使用更复杂的模型,这可能会使SVM花费更长时间来找到最佳解决方案。
使用的数据集: UCI机器学习库是一个很好的数据集来源。 MNIST手写识别数据集是一个很好的选择 - 您可以随机选择子集来创建越来越大的数据集。请记住,链接中的数据包含所有数字,SVM当然是二进制的,因此您必须将数据减少到只有两个数字或执行某种多类SVM。
你可以轻松地生成数据集。要生成线性数据集,随机选择一个法向量到超平面,然后生成数据点并确定其在超平面的哪一侧以进行标记。添加一些随机性,以允许在超平面一定距离内的点有时被标记为不同的类别。通过增加类别之间的重叠来增加复杂度。或者生成一些正态分布点的簇,标记为1或-1,使得它们在边缘处重叠。经典的非线性示例是棋盘格。按照棋盘格的模式生成点并进行标记。为了增加难度,可以增加方块数、增加维度和增加数据点数。当然,对于这种情况,您将需要使用非线性核函数。

karenu 输入矩阵怎么办?我真的很难理解何时以及为什么需要对其进行转置。我看到了几个不同的例子,每个例子都在做不同的事情。我怎样才能知道何时需要对输入矩阵应用t()函数呢? - Manolete

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接