libreria - ¿Ecuaciones SVM del paquete e1071 R?
paquete r e1071 (1)
Estoy interesado en probar el rendimiento de SVM para clasificar a varios individuos en cuatro grupos / clases. Al usar la función svmtrain LibSVM de MATLAB, puedo obtener las tres ecuaciones utilizadas para clasificar a esos individuos entre los 4 grupos, según los valores de esta ecuación. Un esquema podría ser el siguiente:
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
¿Hay alguna forma de obtener estas ecuaciones usando la función svm en el paquete e1071 R?
svm
en e1071
usa la estrategia "uno contra uno" para la clasificación multiclase (es decir, la clasificación binaria entre todos los pares, seguida de la votación). Entonces, para manejar esta configuración jerárquica, es probable que necesite hacer una serie de clasificadores binarios de forma manual, como el grupo 1 frente a todos, luego el grupo 2 frente a lo que queda, etc. así que normalmente querrá usar un envoltorio como tune
en e1071
, o train
en el excelente paquete de caret
.
De todos modos, para clasificar a nuevos individuos en R, no tiene que insertar números en una ecuación manualmente. Más bien, utiliza la función genérica de predict
, que tiene métodos para diferentes modelos como SVM. Para objetos de modelo como este, también puede usar el plot
y summary
funciones genéricas. Aquí hay un ejemplo de la idea básica utilizando un SVM lineal:
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
Tabular las etiquetas de clase reales frente a las predicciones del modelo:
> table(Actual=iris.part$Species, Fitted=pred)
Fitted
Actual versicolor virginica
versicolor 38 12
virginica 15 35
Extraiga los pesos de las características del objeto modelo svm
(para la selección de características, etc.). Aquí, Sepal.Length
es obviamente más útil.
> t(fit$coefs) %*% fit$SV
Sepal.Length Sepal.Width
[1,] -1.060146 -0.2664518
Para entender de dónde provienen los valores de decisión, podemos calcularlos manualmente como el producto de puntos de los pesos de las características y los vectores de características preprocesados, menos el intercepto del rho
. (Preprocesado significa posiblemente centrado / escalado y / o kernel transformado si se utiliza RBF SVM, etc.)
> 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
...
Esto debería ser igual a lo que se calcula internamente:
> head(fit$decision.values)
versicolor/virginica
51 -1.3997066
52 -0.4402254
53 -1.1596819
54 1.7199970
55 -0.2796942
56 0.9996141
...