我正在尝试使用 kernlab 用于支持向量机 (SVM) 的 R 包。对于我非常简单的示例,我有两条训练数据。A和B。

(A 和 B 的类型 matrix - 它们是图的邻接矩阵。)

所以我写了一个函数,它接受 A+B 并生成一个内核矩阵。

> km
         [,1]     [,2]
[1,] 14.33333 18.47368
[2,] 18.47368 38.96053

现在我用 kernlabksvm 函数来生成我的预测模型。现在,我只是想让这该死的事情发挥作用 - 我不担心训练错误等。

所以, 问题1: :我是否正确生成了模型?合理吗?

# y are my classes. In this case, A is in class "1" and B is in class "-1"
> y
[1]  1 -1

> model2 =  ksvm(km, y, type="C-svc", kernel = "matrix");
> model2
Support Vector Machine object of class "ksvm" 

SV type: C-svc  (classification) 
 parameter : cost C = 1 

[1] " Kernel matrix used as input."

Number of Support Vectors : 2 

Objective Function Value : -0.1224 
Training error : 0 

到目前为止,一切都很好。我们创建了自定义内核矩阵,然后使用该矩阵创建了 ksvm 模型。我们的训练数据标记为“1”和“-1”。

现在来预测一下:

> A
     [,1] [,2] [,3]
[1,]    0    1    1
[2,]    1    0    1
[3,]    0    0    0

> predict(model2, A)
Error in as.matrix(Z) : object 'Z' not found

呃哦。这没关系。确实有点期待。“预测”需要某种向量,而不是矩阵。

那么让我们尝试一些事情:

> predict(model2, c(1))
Error in as.matrix(Z) : object 'Z' not found
> predict(model2, c(1,1))
Error in as.matrix(Z) : object 'Z' not found
> predict(model2, c(1,1,1))
Error in as.matrix(Z) : object 'Z' not found
> predict(model2, c(1,1,1,1))
Error in as.matrix(Z) : object 'Z' not found
> predict(model2, km)
Error in as.matrix(Z) : object 'Z' not found

上面的一些测试是无意义的,但这就是我的观点:无论我做什么,我都无法让 Predict() 查看我的数据并进行预测。标量不起作用,向量不起作用。2x2 矩阵不起作用,3x3 矩阵也不起作用。

我在这里做错了什么?

(一旦我弄清楚 ksvm 想要, ,然后我可以确保我的测试数据能够以理智/合理/数学上合理的方式符合该格式。)

有帮助吗?

解决方案

如果你认为有关如何支持向量机可能"使用"核矩阵,你会看到你真的不能做到这样你正在尝试(如你所见:-)

我实际上挣扎一下这个当我第一次是使用kernlab+核矩阵...巧合的是,它也是对图仁!

无论如何,我们首先认识到,由于SVM不知道如何计算核心功能,它需要有这些价值观已经计算出之间的新的(试验)的实例和实例,它挑选出为支持向量在培训期间的步骤。

因此,只需要计算的核矩阵 所有 你的例子在一起。你会后来的火车上一些和测试的其他人通过消除行+列从核矩阵在适当的时候。让我告诉你的代码。

我们可以使用示例的代码 ksvm 文件载入我们工作空间与一些数据:

library(kernlab)
example(ksvm)

你需要击中返回的几(2)次为了让我们的绘图绘制,以及让的例子完成的,但是你现在应该有一个内核矩阵在你的工作空间所谓 K.我们需要恢复 y 矢量,它应该使用其标(因为它已经践踏了由其它代码中的例子):

y <- matrix(c(rep(1,60),rep(-1,60)))

现在,选择一个子集的实例以用于测试

holdout <- sample(1:ncol(K), 10)

从这一点上,我要:

  1. 创建一个培训核矩阵名 trainK 从原始 K 核矩阵。
  2. 创建一个SVM模型从我的培训组 trainK
  3. 使用支持向量找到从该模型来建立一个试验核矩阵 testK ...这是奇怪的一部分。如果你看看中的代码 kernlab 看看它是如何使用所支持的矢量指数中,你会看到的它为什么正在这样做的方式。它可能能够这样做的另一种方式,但是我没有看到任何文件/上的例子 预测 有一个核矩阵,使我这样做是"硬盘的方式"在这里。
  4. 使用SVM预测这些特点和报告的准确度

这里的代码:

trainK <- as.kernelMatrix(K[-holdout,-holdout])  # 1
m <- ksvm(trainK, y[-holdout], kernel='matrix')  # 2
testK <- as.kernelMatrix(K[holdout, -holdout][,SVindex(m), drop=F]) # 3
preds <- predict(m, testK)  # 4
sum(sign(preds) == sign(y[holdout])) / length(holdout) # == 1 (perfect!)

这应该只是关于这样做。祝你好运!

答复下面的评论

什么不K[-维持,-维持]的意思吗?(什么是"-"意思呢?)

想象一下,你有一个向量 x, 和你想要检索的因素1、3和5,你会做的:

x.sub <- x[c(1,3,5)]

如果你想要找回一切 x 除了 单元1、3和5,你会做的:

x.sub <- x[-c(1,3,5)]

所以 K[-holdout,-holdout] 回报所有的行列 K 除了 行我们想要维持.

什么是的论点,你的作为。kernelMatrix-特别是[,SVindex(m),下降=F]的参数(这特别奇怪,因为它看起来像整个支架是一个矩阵指数的K?)

是啊,我的内联的两个命令进一:

testK <- as.kernelMatrix(K[holdout, -holdout][,SVindex(m), drop=F])

现在你已经训练的模型,要给它一个新的核矩阵与你的测试的例子。 K[holdout,] 会给你唯一的行其对应于培训的例子 K, 和所有的列 K.

SVindex(m) 给你的指标支持向量从你的 原始的 培训矩阵--请记住,这些行/cols有 holdout 删除。因此,对于那些列指数是正确的(ie。参照正确的sv列),我必须首先消除的 holdout 列。

无论如何,这也许是更清楚的:

testK <- K[holdout, -holdout]
testK <- testK[,SVindex(m), drop=FALSE]

现在 testK 只有行我们的 测试实例 和列应支持向量。 testK[1,1] 会有价值的核心功能的计算之间你的第一个试验例子,第一个支持向量。 testK[1,2] 将具有核心功能价值之间的第1次测试例以及第二,支持向量,等等。

更新(2014-01-30)为回答评论@wrahool

它已经有一段时间,因为我已经打了这个,所以资料 kernlab::ksvm 有点生锈的,但原则上,这应该是正确的:-)...这里云:

点是什么 testK <- K[holdout, -holdout] -不是你卸下列相对应的测试设置的?

是的。简短的回答是,如果你想要 predict 使用核矩阵,你必须提供的一个矩阵,该矩阵的维度 rows 通过 support vectors.每个矩阵的行(新例子你想要预测上)的数值列根本价值的核矩阵评估之间,例如,支持向量。

呼叫 SVindex(m) 返回索引的支持向量中给出的尺寸 原始的 培训的数据。

因此,首先做 testK <- K[holdout, -holdout] 给我一个 testK 矩阵的行为的例子,我想预测,并列从同一实例(维)该模型的培训。

我还列的子集 testK 通过 SVindex(m) 只给我列(现在)相对应,我支持向量。我不做第一个 [, -holdout] 选择、指标的返回 SVindex(m) 可能不符合正确的例子(除非所有 N 你的测试的实例是最后一个 N 列的矩阵)。

此外,究竟下降=FALSE条件做什么?

这一点的防御性的编码,以确保后索引操作执行,对象是返回的相同类型作为目的,是编制索引。

在R,如果你指标只有一个层面2D(或更高的(?)) 对象,你是返回的一个目的较低层面。我不想通过一个 numeric 矢量成 predict 因为它希望有一个 matrix

例如

x <- matrix(rnorm(50), nrow=10)

class(x)
[1] "matrix"

dim(x)
[1] 10  5

y <- x[, 1]

class(y)
[1] "numeric"

dim(y)
NULL

同样会发生 data.frames,等等。

其他提示

首先我没用过 内核实验室 很多。但只要看看文档,我确实看到了工作示例 predict.ksvm() 方法。复制和粘贴,并忽略屏幕上的打印:

 ## example using the promotergene data set
 data(promotergene)

 ## create test and training set
 ind <- sample(1:dim(promotergene)[1],20)
 genetrain <- promotergene[-ind, ]
 genetest <- promotergene[ind, ]

 ## train a support vector machine
 gene <-  ksvm(Class~.,data=genetrain,kernel="rbfdot",\
               kpar=list(sigma=0.015),C=70,cross=4,prob.model=TRUE)

 ## predict gene type probabilities on the test set
 genetype <- predict(gene,genetest,type="probabilities")

这看起来很直接:使用随机抽样生成训练集 genetrain 及其补语 genetest, ,然后通过拟合 ksvm 并致电 predict() 使用拟合的方法,以及匹配格式的新数据。这是非常标准的。

您可能会发现 插入符 Max Kuhn 的包很有用。它为各种回归、分类和机器学习方法和包提供了通用的评估和测试框架,包括 内核实验室, ,并包含几个小插图加上一个 JSS论文.

史蒂夫Lianoglou是正确的。

在kernlab是有点有线,和预测时它要求每个试验例和支持向量之间的输入内核矩阵。你需要自己找到这个矩阵。

例如,在测试矩阵[n×m个],其中n为试验样品,且m的数量是在学习模型的支持向量的数量(SVindex(模型)的序列中的排序)。

实施例的代码

trmat <- as.kernelMatrix(kernels[trainidx,trainidx])
tsmat <- as.kernelMatrix(kernels[testidx,trainidx])

#training
model = ksvm(x=trmat, y=trlabels, type = "C-svc", C = 1)

#testing
thistsmat = as.kernelMatrix(tsmat[,SVindex(model)])
tsprediction = predict(model, thistsmat, type = "decision")

内核是输入内核矩阵。 trainidx和testidx是用于训练和测试的ID。

自己从溶液中的元素构建的标签。使用此备用预测方法,其需要ksvm模型(M)和数据在原始训练格式(d)

predict.alt <- function(m, d){
  sign(d[, m@SVindex] %*% m@coef[[1]] - m@b)
}

K是用于训练kernelMatrix。对于验证的缘故,如果你在训练数据运行predict.alt你会发现,备用预测方法切换值由一起返回ksvm拟合值。天然预测的行为以意想不到的方式:

aux <- data.frame(fit=kout@fitted, native=predict(kout, K), alt=predict.alt(m=kout, d=as.matrix(K))) 
sample_n(aux, 10)
    fit  native alt
1     0       0  -1
100   1       0   1
218   1       0   1
200   1       0   1
182   1       0   1
87    0       0  -1
183   1       0   1
174   1       0   1
94    1       0   1
165   1       0   1
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top