Проблема с либсвм е1071?

13

У меня есть набор данных с двумя перекрывающимися классами, семь точек в каждом классе, точки находятся в двухмерном пространстве. В R, и я бегу svmиз e1071пакета, чтобы построить разделяющую гиперплоскость для этих классов. Я использую следующую команду:

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

где xсодержит мои точки данных и yсодержит их метки. Команда возвращает svm-объект, который я использую для вычисления параметров (нормальный вектор) и (перехват) разделяющей гиперплоскости.бwb

На рисунке (а) ниже показаны мои точки и гиперплоскость, возвращаемая svmкомандой (назовем эту гиперплоскость оптимальной). Синяя точка с символом O показывает начало пространства, пунктирные линии показывают поле, обведенные кружками точки, которые имеют ненулевое значение (переменные провисания).ξ

На рисунке (б) показана другая гиперплоскость, которая представляет собой параллельную трансляцию оптимальной на 5 (b_new = b_optimal - 5). Нетрудно видеть, что для этой гиперплоскости целевая функция (которая минимизируется с помощью C-классификации svm) будет иметь меньшее значение, чем для оптимальной гиперплоскости, показанной на рисунке ( а). Так выглядит ли проблема с этой функцией? Или я где-то ошибся?

0.5||w||2+costξi
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)
Лео
источник
Вы настроили параметр стоимости?
Этьен Расин
Обратите внимание, что тег BUGS относится к байесовскому выводу с использованием выборки Гиббса, а не программным проблемам. Я удалил тег.
Sycorax говорит восстановить Monica

Ответы:

5

В FAQ по libsvm упоминается, что метки, используемые «внутри» алгоритма, могут отличаться от ваших. Иногда это поменяет знак «коэф» модели.

Например, если у вас были метки , то первая метка в , которая равна «-1», будет классифицироваться как для запуска libsvm и, очевидно, ваше «+1» будет классифицироваться как внутри алгоритма.y + 1 - 1y=[1,+1,+1,1,...]y+11

И помните, что значения в возвращенной модели svm действительно являются и поэтому ваш вычисленный вектор будет из-за обращения знака . w yαnynwy

Смотрите вопрос "Почему знак предсказанных меток и значений решений иногда меняют местами?" сюда .

TonySuarez
источник
4

Я столкнулся с той же проблемой, используя LIBSVM в MATLAB. Чтобы проверить это, я создал очень простой двумерный линейно разделяемый набор данных, который, как оказалось, транслировался вдоль одной оси примерно на -100. Обучение линейного SVM с использованием LIBSVM создало гиперплоскость, чей перехват был все еще прямо около нуля (и, таким образом, частота ошибок составляла 50%, естественно). Стандартизация данных (вычитание среднего значения) помогла, хотя полученный svm по-прежнему не работал идеально ... озадачивает. Кажется, что LIBSVM вращает только гиперплоскость вокруг оси, не перемещая ее. Возможно, вам следует попытаться вычесть среднее значение из ваших данных, но кажется странным, что LIBSVM будет вести себя таким образом. Возможно, мы что-то упустили.

Что бы это ни стоило, встроенная функция MATLAB svmtrainсоздала классификатор со 100% точностью без стандартизации.

Дейв
источник