SVM уравнения из пакета e1071 R? - PullRequest
17 голосов
/ 12 сентября 2011

Я заинтересован в тестировании производительности 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?

1 Ответ

39 голосов
/ 15 октября 2011

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
...
...