Pregunta

Estoy tratando de utilizar el paquete R kernlab hacer máquinas de vectores soporte (SVM). Para mi ejemplo muy sencillo, tengo dos piezas de datos de entrenamiento. A y B.

(A y B son de tipo matrix -. Que son matrices de adyacencia para gráficos)

Así que escribí una función que toma A + B y genera una matriz kernel.

> km
         [,1]     [,2]
[1,] 14.33333 18.47368
[2,] 18.47368 38.96053

Ahora uso la función de kernlab ksvm para generar mi modelo predictivo. En este momento, sólo estoy tratando de conseguir la maldita cosa a trabajar -. No estoy preocupado por error de entrenamiento, etc.

Por lo tanto, Pregunta 1 : ¿Estoy generando mi modelo correctamente? Razonablemente?

# y are my classes. In this case, A is in class "1" and B is in class "-1"
> y
[1]  1 -1

> model2 =  ksvm(km, y, type="C-svc", kernel = "matrix");
> model2
Support Vector Machine object of class "ksvm" 

SV type: C-svc  (classification) 
 parameter : cost C = 1 

[1] " Kernel matrix used as input."

Number of Support Vectors : 2 

Objective Function Value : -0.1224 
Training error : 0 

Hasta aquí todo bien. Hemos creado nuestra matriz de núcleo a medida, y luego creamos un modelo ksvm usando esa matriz. Hemos llamado a nuestros datos de entrenamiento como "1" y "-1".

Ahora predecir:

> A
     [,1] [,2] [,3]
[1,]    0    1    1
[2,]    1    0    1
[3,]    0    0    0

> predict(model2, A)
Error in as.matrix(Z) : object 'Z' not found

Uh-oh. Esto está bien. Tipo de espera, de verdad. "Predecir" quiere algún tipo de vector, no una matriz.

Así que vamos a probar algunas cosas:

> predict(model2, c(1))
Error in as.matrix(Z) : object 'Z' not found
> predict(model2, c(1,1))
Error in as.matrix(Z) : object 'Z' not found
> predict(model2, c(1,1,1))
Error in as.matrix(Z) : object 'Z' not found
> predict(model2, c(1,1,1,1))
Error in as.matrix(Z) : object 'Z' not found
> predict(model2, km)
Error in as.matrix(Z) : object 'Z' not found

Algunas de las pruebas anteriores son sin sentido, pero eso es mi punto: no importa lo que hago, simplemente no puedo conseguir predecir () para mirar mis datos y hacer una predicción. Escalares no funcionan, los vectores no funcionan. Una matriz de 2x2 no funciona, ni una matriz de 3x3.

¿Qué estoy haciendo mal aquí?

(Una vez que descubra lo ksvm quiere , entonces yo puedo asegurar que mis datos de prueba pueden ajustarse a ese formato de una manera sana / razonable / matemáticamente sonido.)

¿Fue útil?

Solución

Si se piensa en cómo la máquina de vectores de soporte puede "utilizar" la matriz del núcleo, verá que realmente no se puede hacer esto en la forma en que estamos tratando (como se ha visto: -)

De hecho, me ha costado un poco con esta la primera vez que estaba usando una matriz kernlab + kernel ... casualmente, también era para los núcleos de gráficos!

De todos modos, vamos a primero se dan cuenta de que, dado que la SVM no sabe cómo calcular su función de núcleo, que tiene que tener estos valores ya calculados entre sus nuevos ejemplos (de prueba), y los ejemplos se escoge como los vectores de soporte durante la etapa de formación.

Por lo tanto, tendrá que calcular la matriz de núcleo para todos de sus ejemplos juntos. Vas a entrenar después de unos y de prueba en los demás mediante la eliminación de filas + columnas de la matriz del núcleo cuando sea apropiado. Te voy a enseñar con el código.

Podemos utilizar el código de ejemplo en la documentación ksvm para cargar nuestro espacio de trabajo con algunos datos:

library(kernlab)
example(ksvm)

Tendrá que pulsar Intro unos pocos (2) veces con el fin de permitir que las parcelas dibujar, y dejar que el acabado ejemplo, pero ahora debería tener una matriz de núcleo en su espacio de trabajo denominado K. Vamos a tener que recuperar el vector y que debería utilizar para sus etiquetas (como lo ha sido pisoteado por otro código en el ejemplo):

y <- matrix(c(rep(1,60),rep(-1,60)))

Ahora, escoger un subconjunto de ejemplos a utilizar para probar

holdout <- sample(1:ncol(K), 10)

A partir de ahora, voy a:

  1. Crear una matriz de formación de núcleo denominado trainK de la matriz del núcleo original de K.
  2. Crear un modelo SVM de mi conjunto de entrenamiento trainK
  3. Utilice los vectores de soporte se encuentran en el modelo para crear una matriz testK pruebas del núcleo ... esta es la parte extraña. Si nos fijamos en el código en kernlab para ver cómo se utiliza los índices de vectores de soporte, verá por qué se está haciendo de esta manera. Podría ser posible hacer esto de otra manera, pero yo no vi ninguna documentación / ejemplos de predecir con una matriz de núcleo, por lo que estoy haciendo "por las malas" aquí.
  4. Utilice la SVM para predecir sobre estas funciones e informar exactitud

Aquí está el código:

trainK <- as.kernelMatrix(K[-holdout,-holdout])  # 1
m <- ksvm(trainK, y[-holdout], kernel='matrix')  # 2
testK <- as.kernelMatrix(K[holdout, -holdout][,SVindex(m), drop=F]) # 3
preds <- predict(m, testK)  # 4
sum(sign(preds) == sign(y[holdout])) / length(holdout) # == 1 (perfect!)

Esto debería sólo de hacerlo. Buena suerte!

Respuestas a comentar a continuación

  

¿qué K [-holdout, -holdout] significa? (Lo que hace el "-" significa)

Imagine que tiene un x vector, y desea recuperar los elementos 1, 3 y 5 de la misma, que haría:

x.sub <- x[c(1,3,5)]

Si desea recuperar todo, desde x excepto los elementos 1, 3 y 5, que haría:

x.sub <- x[-c(1,3,5)]

Así K[-holdout,-holdout] devuelve todas las filas y columnas de K excepto para las filas que queremos retención.

  

¿Cuáles son los argumentos de su as.kernelMatrix - especialmente el [, SVindex (m), la caída = F] argumento

Sí, lo inlined dos comandos en una sola:

testK <- as.kernelMatrix(K[holdout, -holdout][,SVindex(m), drop=F])

Ahora que ha entrenado el modelo, que desea darle una nueva matriz de núcleo con sus ejemplos de prueba. K[holdout,] le daría sólo las filas que corresponden a los ejemplos de entrenamiento en K, y todas las columnas de K.

SVindex(m) le da los índices de sus vectores de soporte de su matriz original de entrenamiento - recuerde, las filas / cols han holdout eliminado. Así que para aquellos índices de columna para ser correctos (es decir. Referenciar la columna de la correcta sv), debo eliminar primero las columnas holdout.

De todos modos, tal vez esto es más claro:

testK <- K[holdout, -holdout]
testK <- testK[,SVindex(m), drop=FALSE]

Ahora testK solamente tiene las filas de nuestros ejemplos de prueba y las columnas que corresponden alos vectores de soporte. testK[1,1] tendrá el valor de la función del núcleo calculada entre el primer ejemplo de prueba, y el primer vector de apoyo. testK[1,2] tendrá el valor de la función kernel entre su ejemplo de pruebas primero y el segundo vector de soporte, etc.

Actualización (01/30/2014) para contestar comentario de @wrahool

Ha sido un tiempo desde que he jugado con esto, así que los detalles de kernlab::ksvm son un poco oxidado, pero en principio esto debería ser correcta :-) ... aquí va:

  

¿cuál es el punto de testK <- K[holdout, -holdout] -? ¿No quitando las columnas que corresponden al equipo de prueba

Sí. La respuesta corta es que si quieres predict utilizando una matriz de núcleo, que tiene que suministrar la una matriz que es de la dimensión rows por support vectors. Para cada fila de la matriz (el nuevo ejemplo, usted quiere predecir en) los valores de las columnas son simplemente el valor de la matriz del núcleo evaluado entre ese ejemplo y el vector de apoyo.

La llamada a SVindex(m) devuelve el índice de los vectores de soporte dadas en la dimensión de la ORIGINAL de datos de entrenamiento.

Por lo tanto, yo primero haciendo testK <- K[holdout, -holdout] da una matriz testK con las filas de los ejemplos que queremos predecir el, y las columnas son de los mismos ejemplos (dimensión) del modelo fue entrenado en.

Me subconjunto adicional las columnas de testK por SVindex(m) sólo dame las columnas, que (ahora) se corresponden con mis vectores de soporte. No lo había hecho la primera selección [, -holdout], los índices devueltos por SVindex(m) pueden no corresponder a los ejemplos adecuados (a menos que todos N de sus ejemplos de prueba son las últimas columnas N de su matriz).

  

Además, ¿qué hace exactamente la caída = FALSO condición de hacer?

Es un poco de codificación defensiva para asegurar que después se realiza la operación de indexación, el objeto que se devuelve es del mismo tipo que el objeto que fue indexado.

En R, si índice sólo una dimensión de una 2D (o superior (?)) Objeto, volverá un objeto de la dimensión inferior. No quiero pasar un vector numeric en predict porque quiere tener una matrix

Por ejemplo

x <- matrix(rnorm(50), nrow=10)

class(x)
[1] "matrix"

dim(x)
[1] 10  5

y <- x[, 1]

class(y)
[1] "numeric"

dim(y)
NULL

Lo mismo ocurrirá con data.frames, etc.

Otros consejos

En primer lugar, no he utilizado kernlab mucho. Sino simplemente mirar los documentos, yo veo ejemplos de trabajo para el método predict.ksvm(). Copiar y pegar, y omitiendo las impresiones de pantalla:

 ## example using the promotergene data set
 data(promotergene)

 ## create test and training set
 ind <- sample(1:dim(promotergene)[1],20)
 genetrain <- promotergene[-ind, ]
 genetest <- promotergene[ind, ]

 ## train a support vector machine
 gene <-  ksvm(Class~.,data=genetrain,kernel="rbfdot",\
               kpar=list(sigma=0.015),C=70,cross=4,prob.model=TRUE)

 ## predict gene type probabilities on the test set
 genetype <- predict(gene,genetest,type="probabilities")

Eso parece bastante mojigata: utilizar un muestreo aleatorio para generar una genetrain conjunto de entrenamiento y su genetest complemento, a continuación, ajuste a través de ksvm y una llamada a un método predict() mediante el ajuste, y los nuevos datos en un formato de juego. Esto es muy estándar.

Puede encontrar el símbolo de intercalación href="http://cran.r-project.org/package=caret" rel="nofollow noreferrer"> paquete por Max Kuhn útil. Proporciona un marco de evaluación y ensayo general para una variedad de métodos y paquetes de regresión, de clasificación y de aprendizaje automático, incluyendo kernlab , y contiene varias viñetas más un JSS papel .

Steve Lianoglou es correcto.

En kernlab que es un poco por cable, y cuando la predicción de que requiere la matriz de núcleo de entrada entre cada ejemplo de prueba y los vectores de soporte. Es necesario encontrar esta matriz a sí mismo.

Por ejemplo, una matriz de prueba [n x m], donde n es el número de muestras de ensayo y m es el número de vectores de soporte en el modelo aprendido (ordenados en la secuencia de SVindex (modelo)).

código Ejemplo

trmat <- as.kernelMatrix(kernels[trainidx,trainidx])
tsmat <- as.kernelMatrix(kernels[testidx,trainidx])

#training
model = ksvm(x=trmat, y=trlabels, type = "C-svc", C = 1)

#testing
thistsmat = as.kernelMatrix(tsmat[,SVindex(model)])
tsprediction = predict(model, thistsmat, type = "decision")

granos es la matriz del núcleo de entrada. trainidx y testidx son los identificadores de formación y de prueba.

Construir las etiquetas a sí mismo de los elementos de la solución. Utilice este método predictor alternativo que toma modelo ksvm (m) y los datos en el formato original de entrenamiento (d)

predict.alt <- function(m, d){
  sign(d[, m@SVindex] %*% m@coef[[1]] - m@b)
}

K es un kernelMatrix para la formación. Por el bien de la validación, si ejecuta predict.alt en los datos de entrenamiento se dará cuenta de que el método predictor alternativo cambia los valores junto a los valores ajustados devueltos por ksvm. El predictor nativa se comporta de una manera inesperada:

aux <- data.frame(fit=kout@fitted, native=predict(kout, K), alt=predict.alt(m=kout, d=as.matrix(K))) 
sample_n(aux, 10)
    fit  native alt
1     0       0  -1
100   1       0   1
218   1       0   1
200   1       0   1
182   1       0   1
87    0       0  -1
183   1       0   1
174   1       0   1
94    1       0   1
165   1       0   1
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top