Ответ 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
Табулируйте фактические метки классов против предсказаний модели:
> 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
...