support - Diseño de un Kernel para una máquina de vectores de soporte(XOR)
support vector regression (4)
P: "¿Cómo se diseña una función del núcleo para un problema de aprendizaje?"
A: "Muy cuidado"
Probar a los sospechosos habituales (lineal, polinomial, RBF) y usar el que mejor funcione es un buen consejo para alguien que intenta obtener el modelo predictivo más preciso posible. Por lo que vale la pena, es una crítica común a los SVM que parecen tener muchos parámetros que necesita ajustar empíricamente. Así que al menos no estás solo.
Si realmente desea diseñar un kernel para un problema específico, tiene razón, es un problema de aprendizaje automático en sí mismo. Se llama el ''problema de selección de modelo''. El mismo no soy exactamente un experto aquí, pero la mejor fuente de información sobre los métodos del kernel para mí fue el libro '' Procesos gaussianos '' de Rasumussen y Williams (está disponible gratuitamente en línea), especialmente los capítulos 4 y 5. Lo siento. No puedo decir mucho más que "leer este enorme libro lleno de matemáticas", pero es un problema complicado y hacen un muy buen trabajo explicándolo.
La cuestión de mi pregunta es "¿cómo se diseña una función del núcleo para un problema de aprendizaje?"
Como resumen, estoy leyendo libros sobre máquinas de vectores de soporte y máquinas de kernel, y donde miro, los autores dan ejemplos de kernels (kernels polinomiales homogéneos y no homogéneos, kernels gaussianos y alusiones a kernels basados en texto, por nombrar algunos) , pero todos proporcionan imágenes de los resultados sin especificar el kernel, o afirman vagamente que "se puede construir un kernel eficiente". Me interesa el proceso que se lleva a cabo cuando uno diseña un núcleo para un nuevo problema.
Probablemente el ejemplo más fácil sea aprender XOR, un conjunto de datos no lineal más pequeño (4 puntos) como incrustado en el plano real. ¿Cómo se podría crear un núcleo natural (y no trivial) para separar linealmente estos datos?
Como un ejemplo más complejo (ver Cristianini, Introducción a las SVM, figura 6.2), ¿cómo se diseñaría un núcleo para aprender un patrón de tablero de ajedrez? Cristianini afirma que la imagen se derivó "utilizando núcleos gaussianos", pero parece que utiliza múltiples, y se combinan y modifican de una manera no especificada.
Si esta pregunta es demasiado amplia para responder aquí, apreciaría una referencia a la construcción de una de estas funciones del núcleo, aunque preferiría que el ejemplo fuera algo simple.
(Para cualquier persona que no esté familiarizada con el uso de las funciones del núcleo en Aprendizaje automático, los núcleos simplemente asignan los vectores de entrada (puntos de datos que conforman el conjunto de datos) a un espacio de mayor dimensión, también conocido como "Espacio de funciones". El SVM encuentra un separando el hiperplano con el margen máximo (distancia entre el hiperplano y los vectores de soporte) en este espacio transformado.)
Bueno, comience con los núcleos que se sabe que funcionan con los clasificadores SVM para resolver el problema de interés. En este caso, sabemos que el kernel RBF (función de base radial) con un SVM entrenado, separa XOR limpiamente. Puedes escribir una función RBF en Python de esta manera:
def RBF():
return NP.exp(-gamma * NP.abs(x - y)**2)
En el que gamma es 1 / número de entidades (columnas en el conjunto de datos), y x, y son un par cartesiano.
(Un módulo de función de base radial también está en scipy.interpolate.Rbf )
En segundo lugar, si lo que está buscando no es solo usar las funciones del kernel disponibles para resolver los problemas de clasificación / regresión, sino que desea construir las suyas propias, sugeriría primero estudiar cómo la elección de la función del kernel y los parámetros dentro de esas funciones afectan el rendimiento del clasificador. . El pequeño grupo de funciones del kernel de uso común con SVM / SVC, es el mejor lugar para comenzar. Este grupo se compone de (aparte de RBF):
kernel lineal
polinomio
sigmoideo
Estoy buscando un trabajo del núcleo polinomial a través de ejemplos y me encontré con este post. Un par de cosas que podrían ayudarlo si todavía está buscando es este kit de herramientas (http://www2.fml.tuebingen.mpg.de/raetsch/projects/shogun) que utiliza el aprendizaje múltiple del kernel, donde puede elegir una amplia selección de Los métodos del kernel y luego el aprendizaje elegirán el mejor para el problema, para que no tenga que hacerlo.
Un método más tradicional y más fácil para su elección de kernel es utilizar la validación cruzada con diferentes métodos de kernel para encontrar el mejor.
Espero que esto le ayude a usted o a alguien más a leer sobre los métodos del núcleo.
Mi enfoque sería estudiar los datos: ¿cómo separaría los puntos en el problema XOR? Cuando empecé a estudiar acerca de ML en general, y SVM en particular, eso es lo que hice, tomé el problema del juguete, lo dibujé a mano y traté de separar las clases.
Cuando observé el problema XOR la primera vez, se me ocurrió que ambos puntos morados (abajo, a la izquierda) tienen X e Y del mismo signo, en un caso negativo en un positivo, mientras que ambos puntos verdes tienen X e Y de signos opuestos. Por lo tanto, la suma al cuadrado de X e Y sería 0 (o muy pequeña con un poco de ruido en el problema inicial) para los puntos verdes, y 2 (o casi 2) para los púrpuras. Por lo tanto, agregar una tercera coordenada Z = np.sqrt(np.square(X + Y))
separará bien los dos conjuntos:
En una nota al margen, Z
no es una formulación muy diferente de rbf de doug si considera que np.sqrt(np.square(X + Y))
es esencialmente lo mismo que np.abs(X + Y)
en este caso.
No tengo acceso al artículo de Crisitanini, pero abordaría ese problema también de manera similar, comenzando con una versión de juguete (por cierto, código de tablero de ajedrez gracias a nada menos que a ):
Una posible intuición aquí es que la suma de los índices de fila y columna para los cuadrados negros sería siempre par, mientras que para los cuadrados blancos sería siempre impar, por lo que agregar como tercera dimensión algo como (row_index + col_index) % 2
sería suficiente. Truco en esta sencilla versión. En un conjunto de datos de tablero de ajedrez más grande y complejo, como este que encontré en la web:
las cosas no son tan simples, pero tal vez uno podría hacer una agrupación en cascada para encontrar las ubicaciones medias de X e Y de los 16 agrupamientos (quizás utilizando el agrupamiento de medoides ), y luego aplicar una versión del "truco del kernel de módulo".
Con el descargo de responsabilidad de que no he trabajado con una tonelada de problemas de clasificación, hasta ahora he encontrado que al crear una versión de juguete de una versión compleja, generalmente he adquirido una intuición "numérica" en cuanto al tipo de solución que podría funcionar. .
Finalmente, como se publicó en un comentario a la respuesta de doug, no encuentro nada malo en un enfoque empírico como el suyo , estudiando el rendimiento de todos los kernels posibles al pasarlos a la búsqueda de cuadrículas en la validación cruzada anidada con el mismo algoritmo (SVC) y cambiando sólo el núcleo. Puede agregar a este enfoque trazando los márgenes respectivos en los espacios de características transformados: por ejemplo, para rbf, usando la ecuación sugerida por Doug (y la rutina de Sebastian Raschka para trazar las regiones de decisión - celda 13 aquí ).
ACTUALIZACIÓN del 27/17 de octubre En una conversación en mi canal flojo, otro geofísico me preguntó sobre el caso en el que la compuerta XOR está diseñada como 0s y 1s en lugar de -1s y 1s (este último es similar a un problema clásico en geofísica de exploración , de ahí mi ejemplo de juguete inicial).
Si tuviera que abordar la compuerta XOR con 0s y 1s, y no tuviera disponible el conocimiento sobre el kernel rbf, en este caso también me sentaría a discutir el problema en términos de las coordenadas de esos problemas y vería si Podría llegar a una transformación.
Mi primera observación aquí fue que los Os se sientan en la línea x=y
, las X en la línea x=-y
, por lo que la diferencia xy
sería 0 (o pequeña con un poco de ruido) en el caso, +/- 1 en el otro, respectivamente. El valor absoluto se ocuparía del signo, por lo tanto, Z = np.abs(XY)
funcionaría. Que, por cierto, es muy similar a rbf = np.exp(-gamma * np.abs(x - y)**2)
(otra razón para aumentar su respuesta); y, de hecho, su rbf es una solución más general, que funciona en todos los casos XOR.