来自e1071 R软件包的SVM方程?

18

我对测试SVM性能以将多个个体分类为四组/类别感兴趣。当使用MATLAB中的svmtrain LibSVM函数时,我可以得到用于根据此方程式的值在4个组之间分类这些个体的三个方程式。一种方案可能如下:

                All individuals (N)*
                      |
 Group 1 (n1) <--- equation 1 --->  (N-n1)
                                      |
                   (N-n1-n2) <--- equation 2 ---> Group 2 (n2)
                      |
Group 3 (n3) <--- equation 3 ---> Group 4(n4)

*N = n1+n2+n3+n4

使用e1071 R软件包中的svm函数有没有办法获得这些方程式?

1个回答

42

e1071 中的 svm 采用“一对一”策略进行多类分类(即所有对之间的二元分类,然后投票)。因此,为了处理这种层次结构,您可能需要手动执行一系列二元分类器,例如组1对全部,然后是组2对剩下的等等。此外,基本的svm函数不调整超参数,因此您通常希望使用包装器(如e1071中的tune或优秀的caret包中的train)。

无论如何,在R中分类新个体时,您不必手动将数字插入方程式中。相反,您使用通用函数predict,该函数具有适用于不同模型(如SVM)的方法。对于此类模型对象,您通常还可以使用通用函数plotsummary。以下是使用线性SVM的基本想法示例:

require(e1071)

# Subset the iris dataset to only 2 labels and 2 features
iris.part = subset(iris, Species != 'setosa')
iris.part$Species = factor(iris.part$Species)
iris.part = iris.part[, c(1,2,5)]

# Fit svm model
fit = svm(Species ~ ., data=iris.part, type='C-classification', kernel='linear')

# Make a plot of the model
dev.new(width=5, height=5)
plot(fit, iris.part)

# Tabulate actual labels vs. fitted labels
pred = predict(fit, iris.part)
table(Actual=iris.part$Species, Fitted=pred)

# Obtain feature weights
w = t(fit$coefs) %*% fit$SV

# Calculate decision values manually
iris.scaled = scale(iris.part[,-3], fit$x.scale[[1]], fit$x.scale[[2]]) 
t(w %*% t(as.matrix(iris.scaled))) - fit$rho

# Should equal...
fit$decision.values

enter image description here

制表实际类标签与模型预测:

> table(Actual=iris.part$Species, Fitted=pred)
            Fitted
Actual       versicolor virginica
  versicolor         38        12
  virginica          15        35

svm模型对象中提取特征权重(用于特征选择等)。在这里,Sepal.Length显然更有用。
> t(fit$coefs) %*% fit$SV
     Sepal.Length Sepal.Width
[1,]    -1.060146  -0.2664518

为了理解决策值的来源,我们可以手动计算它们,即特征权重和预处理后的特征向量的点积减去截距偏移项rho。(“预处理”指的是可能经过居中/缩放和/或核变换,如果使用RBF SVM等)
> t(w %*% t(as.matrix(iris.scaled))) - fit$rho
         [,1]
51 -1.3997066
52 -0.4402254
53 -1.1596819
54  1.7199970
55 -0.2796942
56  0.9996141
...

这应该等于内部计算的结果:

> head(fit$decision.values)
   versicolor/virginica
51           -1.3997066
52           -0.4402254
53           -1.1596819
54            1.7199970
55           -0.2796942
56            0.9996141
...

谢谢你的回答,约翰。我想知道这些方程式的原因是为了评估在分类我的事件时,哪些参数更重要。 - Manuel Ramón
2
@ManuelRamón 啊,明白了。这些被称为线性SVM的“权重”。请参见上面的编辑,了解如何从svm模型对象中计算。祝你好运! - John Colby
1
你的例子只有两个类别(versicolor和virginica),并且你得到了一个包含两个系数的向量,每个系数对应于用于分类鸢尾花数据的变量之一。如果我有N个类别,那么我从with(fit, t(coefs) %*% SV)中得到N-1个向量。每个向量的意义是什么? - Manuel Ramón
1
哦,我明白了...你决定一开始就使用多类模式。我知道你的意思——如果在完整的“鸢尾花”数据上运行,“coefs”只有两列,而我本来期望有3列。“rho”有3个值,“decision.values”也有3列(用于3个一对一二元分类器)。请参见上面手动计算决策值的方法,但到目前为止,我无法从这2个“coefs”集合和3个“rho”值的任何组合中复现存储在“decision.values”中的内容。我现在被卡住了... - John Colby
这些符号是什么意思?是负权重支持一类,正权重支持另一类吗? - Bit Manipulator
显示剩余2条评论

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