我刚开始学习R和SVM,现在正在尝试对e1071
包中的svm
函数进行性能分析。然而,我找不到任何大型数据集来让我根据输入数据大小的变化获得一个好的性能分析结果范围。有人知道如何使用svm
吗?我应该使用哪个数据集?有没有什么特定的参数可以让svm
运行得更辛苦?
我复制了一些我用来测试性能的命令。或许这些命令最有用,也更容易理解我在这里尝试做什么:
#加载库
library(class)
library(e1071)
#我一直在使用golubEsets(有更多可用的例子)
library(golubEsets)
#获取数据:7129x38的矩阵
data(Golub_Train)
n <- exprs(Golub_Train)
#复制行(使数据集更大)
n<-rbind(n,n)
#将训练样本作为向量
samplelabels <- as.vector(Golub_Train@phenoData@data$ALL.AML)
#计算svm并进行性能分析
Rprof('svm.out')
svmmodel1 <- svm(x=t(n), y=samplelabels, type='C', kernel="radial", cross=10)
Rprof(NULL)
我通过复制行和列来不断增加数据集的大小,但结果是达到了内存的极限,而不是让svm
运行得更辛苦…
回答:
关于“让SVM运行得更辛苦” – 让SVM运行得更辛苦的方法是使用一个更复杂的模型,这个模型不容易分离,维度更高,数据集更大、更密集。
SVM性能下降的情况包括:
- 数据集大小增加(数据点的数量)
- 稀疏性减少(零的数量减少)
- 维度增加(属性的数量)
- 使用非线性核(核参数可以使核的计算更加复杂)
调整参数
有没有可以改变的参数来让SVM运行得更久。当然,这些参数会影响你得到的解决方案的质量,可能使用这些参数没有意义。
使用C-SVM,改变C值会导致不同的运行时间。(在nu-SVM中类似的参数是nu)如果数据集是可以合理分离的,减小C值会导致更长的运行时间,因为SVM会允许更多的训练点成为支持向量。如果数据集不是很容易分离,增大C值会导致更长的运行时间,因为你实际上是在告诉SVM你想要一个窄边界的解决方案,这个解决方案紧密贴合数据,当数据不容易分离时,这将需要更长的时间来计算。
通常在进行参数搜索时,你会发现有些参数会增加计算时间,但准确性没有显著提高。
其他参数是核参数,如果你改变它们以增加计算核的复杂性,那么SVM的运行时间自然会增加。线性核简单且运行速度最快;非线性核当然会花费更长时间。有些参数可能不会增加核的计算复杂性,但会强制使用一个更复杂的模型,这可能会让SVM花费更长时间来找到最优解。
可用的数据集:
UCI机器学习库是一个很好的数据集来源。
MNIST手写识别数据集是一个很好的选择 – 你可以随机选择数据的子集来创建越来越大的数据集。请记住,链接中的数据包含所有数字,SVM当然是二元的,所以你必须将数据减少到只有两个数字,或者进行某种多类SVM。
你也可以很容易地生成数据集。要生成一个线性数据集,随机选择一个超平面的法向量,然后生成一个数据点,并确定它落在超平面的哪一边来标记它。添加一些随机性,允许在一定距离内的点有时被标记为不同类别。通过增加类别之间的重叠来增加复杂性。或者生成一些正常分布点的簇,标记为1或-1,使得分布在边缘处重叠。经典的非线性例子是棋盘格。生成点并以棋盘格模式标记它们。要使其更难,可以增加方格的数量,增加维度和增加数据点的数量。当然,你必须使用非线性核来处理这种情况。