【问题标题】:Weights from linear SVM model (in R)?来自线性 SVM 模型的权重(在 R 中)?
【发布时间】:2010-12-26 07:42:29
【问题描述】:

使用kernlab,我用如下代码训练了一个模型:

my.model <- ksvm(result ~ f1+f2+f3, data=gold, kernel="vanilladot")

由于它是一个线性模型,我更喜欢在运行时将分数计算为特征值的简单加权和,而不是使用完整的 SVM 机制。我怎样才能将模型转换成这样的东西(这里是一些虚构的权重):

> c(.bias=-2.7, f1=0.35, f2=-0.24, f3=2.31)
.bias    f1    f2    f3 
-2.70  0.35 -0.24  2.31 

.bias 是偏置项,其余是特征权重?

编辑:

这是一些示例数据。

gold <- structure(list(result = c(-1, -1, -1, -1, -1, -1, -1, -1, -1, 
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), f1 = c(0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 
1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1), f2 = c(13.4138113499447, 
13.2216999857095, 12.964145772169, 13.1975227965938, 13.1031520152764, 
13.59351759447, 13.1031520152764, 13.2700658838026, 12.964145772169, 
13.1975227965938, 12.964145772169, 13.59351759447, 13.59351759447, 
13.0897162110721, 13.364151238365, 12.9483051847806, 12.964145772169, 
12.964145772169, 12.964145772169, 12.9483051847806, 13.0937231331592, 
13.5362700880482, 13.3654209223623, 13.4356400945176, 13.59351759447, 
13.2659406408724, 13.4228886221088, 13.5103065354936, 13.5642812689161, 
13.3224757352068, 13.1779418771704, 13.5601730479315, 13.5457299603578, 
13.3729010596517, 13.4823595997866, 13.0965264603473, 13.2710281801434, 
13.4489887206797, 13.5132372154748, 13.5196188787197), f3 = c(0, 
1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 
0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0)), .Names = c("result", 
"f1", "f2", "f3"), class = "data.frame", row.names = c(NA, 40L
))

【问题讨论】:

  • 提供一个可重复的小例子总是有用的......

标签: r svm


【解决方案1】:

要获得偏差,只需使用全为零的特征向量评估模型。要获得第一个特征的系数,请使用第一个位置为“1”且其他位置为零的特征向量评估模型 - 然后减去您已经知道的偏差。恐怕我不知道 R 语法,但从概念上讲你想要这样的东西:

bias = my.model.eval([0, 0, 0])
f1 = my.model.eval([1, 0, 0]) - bias
f2 = my.model.eval([0, 1, 0]) - bias
f3 = my.model.eval([0, 0, 1]) - bias

要测试您是否正确执行,您可以尝试以下操作:

assert(bias + f1 + f2 + f3 == my.model.eval([1, 1, 1]))

【讨论】:

    【解决方案2】:

    如果我没记错的话,我想你是在问如何提取 SVM 的 W 向量,其中 W 定义为:

    W = \sum_i y_i * \alpha_i * example_i
    

    呃:不知道在这里写方程的最佳方法,但这只是权重*支持向量的总和。计算 W 后,您可以提取所需特征的“权重”。

    假设这是正确的,你会:

    1. 获取作为支持向量的数据索引
    2. 获取它们的权重(alpha)
    3. 计算W

    kernlab 将支持向量索引及其值存储在一个列表中(因此它也适用于多类问题),无论如何,任何使用列表操作都只是为了获取真实数据(您会看到alphaalphaindex 返回的列表只是 1,如果你只是有一个 2 类问题,我假设你这样做)。

    my.model <- ksvm(result ~ f1+f2+f3, data=gold, kernel="vanilladot", type="C-svc")
    alpha.idxs <- alphaindex(my.model)[[1]]  # Indices of SVs in original data
    alphas <- alpha(my.model)[[1]]
    y.sv <- gold$result[alpha.idxs]
    # for unscaled data
    sv.matrix <- as.matrix(gold[alpha.idxs, c('f1', 'f2', 'f3')])
    weight.vector <- (y.sv * alphas) %*% sv.matrix
    bias <- b(my.model)
    

    kernlab 实际上在做它的事情之前首先缩放你的数据。你可以像这样得到(缩放的)权重(我猜,偏差应该是 0(?))

    weight.vector <- (y.sv * alphas) %*% xmatrix(my.model)[[1]]
    

    如果我理解了你的问题,这应该会得到你想要的。

    【讨论】:

    • 不能让它工作。使用基于向量的评估方法和上面的示例数据,我得到偏差=-39.97968,权重=(0.274949,3.014561,-0.02817000)。我可以在几个例子中使用 predict() 来确认这一点。但是,当我尝试您的直接提取方法时,我得到偏差=-0.1310986,权重=(4.048555、325.5573、7.994651)。请注意, alphaindex() & alpha() 实际上似乎不返回列表,而是返回向量。
    • 嗨。抱歉,现在无法查看此问题...我只是想发表评论,因为我修复了代码中的一两个错字(顺便说一句,如果您没有明确设置类型,则默认为进行回归)。 ..老实说,我只是认为存在一些缩放问题。另外,如果你再次运行它,使用这两种方法时 f3 的权重应该是 0。
    • 是的,我确定这也是缩放问题,但我似乎找不到正确缩放的方法。
    猜你喜欢
    • 2019-10-24
    • 2012-03-16
    • 2016-03-09
    • 2012-06-19
    • 1970-01-01
    • 2018-07-06
    • 2014-11-28
    • 2019-01-21
    • 1970-01-01
    相关资源
    最近更新 更多