代码之家  ›  专栏  ›  技术社区  ›  poundifdef

帮助在r中使用kernlab的svm的predict()?

  •  6
  • poundifdef  · 技术社区  · 15 年前

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

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

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

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

    现在我用 克兰伯 ksvm 函数生成预测模型。现在,我只是想让该死的东西工作-我不担心训练错误,等等。

    所以, 问题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 欲望 ,然后我可以确保我的测试数据能够以一种理智/合理/数学上合理的方式符合该格式。)

    4 回复  |  直到 9 年前
        1
  •  21
  •   Steve Lianoglou    10 年前

    如果你考虑支持向量机如何“使用”内核矩阵,你会发现你不能以你正在尝试的方式真正做到这一点(如你所见:—)

    当我第一次使用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模型 特里克
    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 除了 为了我们要维持的争吵。

    您的as.kernelmatrix的参数是什么?尤其是[,svindex(m),drop=f]参数(这是特别奇怪的,因为它看起来整个括号都是k的矩阵索引?)

    是的,我把两个命令输入到一个命令中:

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

    既然您已经训练了模型,那么您需要用您的测试示例给它一个新的内核矩阵。 K[holdout,] 只会给出与中的培训示例相对应的行 K 以及 K .

    SVindex(m) 为您提供支持向量的索引 起初的 训练矩阵——记住,这些行/列 holdout 远离的。因此,为了使这些列索引正确(即引用正确的SV列),我必须首先删除 滞留 柱。

    不管怎样,也许这更清楚了:

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

    现在 泰斯克 只有我们的行 测试示例 以及与支持向量相对应的列。 testK[1,1] 将在第一个测试示例和第一个支持向量之间计算内核函数的值。 testK[1,2] 将在第一个测试示例和第二个支持向量等之间具有内核函数值。

    更新(2014-01-30)以回复@wrahool的评论

    我已经有一段时间没玩过了,所以 kernlab::ksvm 有点生锈,但原则上应该是正确的。下面是:

    有什么意义 testK <- K[holdout, -holdout] -是否删除了与测试集对应的列?

    对。简而言之,如果你想 predict 使用一个核矩阵,你必须提供一个维度的矩阵 rows 通过 support vectors . 对于矩阵的每一行(要预测的新示例),列中的值只是该示例和支持向量之间计算的内核矩阵的值。

    呼唤 向量指数(m) 返回在 起初的 培训数据。

    所以,先做 testk<-k[保持,-保持] 给我一个 泰斯克 矩阵中包含了我要预测的示例行,而列则来自于训练模型的相同示例(维度)。

    我进一步将 泰斯克 通过 向量指数(m) 只给我与我的支持向量相对应的列。我不是第一次做的吗 [, -holdout] 选择,返回的索引 向量指数(m) 可能不符合正确的示例(除非 N 您的测试示例中最后一个 n 矩阵的列)。

    另外,drop=false条件究竟有什么作用?

    这是一种防御性的编码,以确保在执行索引操作之后,返回的对象与被索引的对象具有相同的类型。

    在R中,如果只索引二维(或更高的(?)的一个维度)对象,则返回一个较低维度的对象。我不想通过 numeric 向量转化为 预测 因为它想要一个 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.frame S等。

        2
  •  2
  •   Dirk is no longer here    15 年前

    首先,我没有用 kernlab 很多。但简单地看一下文档,我确实看到了 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() 方法使用fit和匹配格式的新数据。这是非常标准的。

    你可以找到 caret 由马克斯库恩包装有用。它为各种回归、分类和机器学习方法和包提供了一个通用的评估和测试框架,包括 克兰伯 ,并包含多个小插曲和一个 JSS paper .

        3
  •  1
  •   user1165814    10 年前

    Steve Lianoglu是对的。

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

    例如,一个测试矩阵[n x 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。

        4
  •  0
  •   user3349904    9 年前

    根据解决方案的元素自己构建标签。使用这种替代的预测方法,它采用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
    
    推荐文章