Подтвердить что ты не робот

Уравнения SVM из пакета e1071 R?

Мне интересно проверить производительность SVM, чтобы классифицировать несколько человек на четыре группы/классы. При использовании функции svmtrain LibSVM от MATLAB я могу получить три уравнения, используемые для классификации этих лиц среди 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

Есть ли способ получить эти уравнения, используя функцию svm в пакете e1071 R?

4b9b3361

Ответ 1

svm в e1071 использует стратегию "один против одного" для классификации многоклассов (т.е. двоичная классификация между всеми парами, за которой следует голосование). Таким образом, чтобы справиться с этой иерархической настройкой, вам, вероятно, потребуется выполнить серию бинарных классификаторов вручную, например, группу 1 против всех, затем группу 2 по сравнению с тем, что осталось, и т.д. Кроме того, базовая функция svm не настраивает гиперпараметров, поэтому вы обычно захотите использовать обертку типа tune в e1071 или train в отличном пакете caret.

В любом случае, чтобы классифицировать новых лиц в R, вам не нужно вставлять числа в уравнение вручную. Скорее, вы используете универсальную функцию predict, которая имеет методы для разных моделей, таких как SVM. Для таких объектов модели обычно можно использовать общие функции plot и summary. Ниже приведен пример базовой идеи с использованием линейного 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
...