Estoy tratando de construir un SVM a partir de datos de entrenamiento donde un grupo está representado más que el otro. Sin embargo, los grupos estarán igualmente representados en los datos de la prueba eventual. Por lo tanto, me gustaría usar el class.weights
parámetro de la e1071
interfaz del paquete R libsvm
para equilibrar la influencia de los dos grupos en los datos de entrenamiento.
Como no estaba seguro de cómo se deberían especificar exactamente estos pesos, configuré una pequeña prueba:
- Genere algunos datos nulos (características aleatorias; relación 2: 1 entre etiquetas de grupo)
- Ajuste un svm con el
class.weights
conjunto de parámetros. - Predecir un conjunto de nuevos conjuntos de datos nulos y ver las proporciones de clase.
- Replica todo el proceso muchas veces para diferentes conjuntos de entrenamiento nulo.
Aquí está el código R que estoy usando:
nullSVM <- function(n.var, n.obs) {
# Simulate null training data
vars = matrix(rnorm(n.var*n.obs), nrow=n.obs)
labels = rep(c('a', 'a', 'b'), length.out=n.obs)
data = data.frame(group=labels, vars)
# Fit SVM
fit = svm(group ~ ., data=data, class.weights=c(a=0.5, b=1))
# Calculate the average fraction of 'a' we would predict from null test data
mean(replicate(50, table(predict(fit, data.frame(matrix(rnorm(n.var*n.obs), nrow=n.obs))))[1])) / n.obs
}
library(e1071)
set.seed(12345)
mean(replicate(50, nullSVM(50, 300)))
De todo esto esperaba una salida ~ 0.5, sin embargo, eso no es lo que obtuve:
> mean(replicate(50, nullSVM(50, 300)))
[1] 0.6429987
El class.weights
parametro está trabajando, especie de , ya que el menor peso que a
, cuanto más bajo es representado en esta simulación (y si omite class.weights
vuelve cercano a 1) ... pero yo no entiendo por qué el simple uso de pesos de 1: 2 ( para datos de entrenamiento que son 2: 1) no me lleva al 50%.
Si no entiendo los SVM, ¿alguien puede explicar este punto? (o enviar algunas referencias?)
Si lo estoy haciendo mal, ¿alguien puede decirme la forma correcta de usar el class.weights
parámetro?
¿Podría ser posiblemente un error? (Creo que no, ya que entiendo que este software y el libsvm subyacente son bastante maduros)
fuente
Respuestas:
Creo que puede depender de los valores de C y la cantidad de patrones que tenga. El SVM intenta encontrar el margen máximo discriminante, por lo que si tiene datos escasos, es posible que el SVM encuentre la solución de margen duro sin que ninguno de los multiplicadores de Lagrange alcance sus límites superiores (en cuyo caso, la proporción de penalizaciones para cada la clase es esencialmente irrelevante ya que los valores de holgura son pequeños o cero. Intente aumentar el número de patrones de entrenamiento y vea si eso tiene un efecto (ya que eso hace que sea menos probable que la solución de margen duro se pueda encontrar dentro de las restricciones de la caja) .
Más importante aún, los valores óptimos de C dependen de los datos, no solo puede establecerlos en algunos valores predeterminados, sino optimizarlos minimizando el error de omisión o algún límite de generalización. Si tiene clases desequilibradas, puede fijar la relación de valores para cada clase y optimizar la penalización promedio sobre todos los patrones.
fuente
caret
paquete o latune()
función incorporada para el ajuste de parámetros del modelo, por lo que me gusta especialmente su segunda idea sobre cómo lidiar con esto en la práctica ajustando el esquema de remuestreo para favorecer a la clase minoritaria. Muy apreciado.en el entrenamiento, svm encuentra vectores de soporte para hacer un límite discriminativo y cuando hay suficientes vectores de soporte para todos los datos de clases para hacerlo, no sería un problema. En la precisión de los resultados del conjunto de pruebas, debe tener en cuenta la cantidad de datos de igualdad para todas las clases en el mundo real y para obtener resultados reales, debe manipular los datos y considerarlos adecuadamente en una situación real.
fuente