e1071 libsvm 有问题吗?

机器算法验证 r 机器学习 支持向量机 libsvm e1071
2022-03-19 09:07:25

我有一个包含两个重叠类的数据集,每个类中有七个点,点在二维空间中。在 R 中,我svme1071包中运行,为这些类构建一个分离的超平面。我正在使用以下命令:

svm(x, y, scale = FALSE, type = 'C-classification', kernel = 'linear', cost = 50000)

其中x包含我的数据点并y包含它们的标签。该命令返回一个 svm-object,我用它来计算参数w(法线向量)和b(截距)分离超平面。

下图(a)显示了我的点和svm命令返回的超平面(我们称这个超平面为最优)。带符号 O 的蓝点表示空间原点,虚线表示边距,圈出的是非零点ξ(松弛变量)。

图 (b) 显示了另一个超平面,它是最优平面乘以 5 (b_new = b_optimal - 5) 的平行平移。不难看出,对于这个超平面,目标函数

0.5||w||2+costξi
(通过 C 分类 svm 最小化)将具有比图 (a) 中所示的最优超平面更低的值。那么这个功能看起来有问题svm吗?还是我在某个地方犯了错误?

在此处输入图像描述

下面是我在这个实验中使用的 R 代码。

library(e1071)

get_obj_func_info <- function(w, b, c_par, x, y) {
    xi <- rep(0, nrow(x))

    for (i in 1:nrow(x)) {
        xi[i] <- 1 - as.numeric(as.character(y[i]))*(sum(w*x[i,]) + b)
        if (xi[i] < 0) xi[i] <- 0
    }

    return(list(obj_func_value = 0.5*sqrt(sum(w * w)) + c_par*sum(xi), 
                    sum_xi = sum(xi), xi = xi))
}

x <- structure(c(41.8226593092589, 56.1773406907411, 63.3546813814822, 
66.4912298720281, 72.1002963174962, 77.649309469458, 29.0963054665561, 
38.6260575252066, 44.2351239706747, 53.7648760293253, 31.5087701279719, 
24.3314294372308, 21.9189647758150, 68.9036945334439, 26.2543850639859, 
43.7456149360141, 52.4912298720281, 20.6453186185178, 45.313889181287, 
29.7830021158501, 33.0396571934088, 17.9008386892901, 42.5694092520593, 
27.4305907479407, 49.3546813814822, 40.6090664454681, 24.2940422573947, 
36.9603428065912), .Dim = c(14L, 2L))

y <- structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L), .Label = c("-1", "1"), class = "factor")

a <- svm(x, y, scale = FALSE, type = 'C-classification', kernel = 'linear', cost = 50000)

w <- t(a$coefs) %*% a$SV;
b <- -a$rho;

obj_func_str1 <- get_obj_func_info(w, b, 50000, x, y)
obj_func_str2 <- get_obj_func_info(w, b - 5, 50000, x, y)
2个回答

在 libsvm FAQ 中提到,算法“内部”使用的标签可能与您的不同。这有时会反转模型“系数”的符号。

例如,如果您有标签y=[1,+1,+1,1,...], 然后是第一个标签y,即“-1”,将被分类为+1用于运行 libsvm,显然,您的“+1”将被归类为1算法里面。

回想一下,返回的 svm 模型中的系数确实是αnyn所以你的计算w由于符号的反转,矢量将受到影响y的。

请参阅问题“为什么预测标签和决策值的符号有时会颠倒?” 在这里

我在 MATLAB 中使用 LIBSVM 遇到了同样的问题。为了测试它,我创建了一个非常简单的 2D 线性可分数据集,它恰好沿一个轴平移到 -100 左右。使用 LIBSVM 训练线性 svm 会产生一个超平面,其截距仍然在零附近(因此错误率自然是 50%)。标准化数据(减去平均值)有所帮助,尽管生成的 svm 仍然不能完美地执行......令人困惑。似乎 LIBSVM 只是围绕轴旋转超平面而不平移它。也许您应该尝试从数据中减去平均值,但 LIBSVM 会以这种方式运行似乎很奇怪。也许我们错过了一些东西。

值得一提的是,内置的 MATLAB 函数svmtrain生成了一个准确率 100% 的分类器,无需标准化。