Support vector machine es una técnica avanzada de IA para el reconocimiento de patrones basada en funciones kernel.
Bien y eso que!, bueno, bueno vamos a ver como se hace un svm para el proceso de aprendizaje supervisado de una compuerta xor. Puesto que en internet se encuentra mucha información acerca del tema, no voy a reparar en detalles, como lo serian los optimizadores de lagrange y las funciones kernel y todo el principio matemático(matrices, derivadas, sistemas de ecuaciones, etc), ya que mi objetivo es mostar una manera rápida de construir un svm con python y sympy, sin complicados procedimientos matemáticos, claro que también se puede hacer en matlab, pero bueno no nos gustan las cajas negras y por eso no lo hacemos en matlab.
Primero vamos a derivar manualmente, respecto de a1, a2, a3, a4:
a1 + a2 + a3 + a4 + a1*a4 + a2*a4 + a3*a4 - a1*a2 - a1*a3 - a2*a3 - 9*a1^2/2 - 9*a2^2/2 - 9*a3^2/2 - 9*a4^2/2
Y luego solucionamos el sistema de ecuaciones.
No, es una broma!, para eso tenemos las rutinas proporcionadas por sympy para no quebrarnos la cabeza.
Bien veamos el codigo.
from sympy import *
xor = [[-1,-1],[-1,1],[1,-1],[1,1]]
signos = [-1,1,1,-1]
literals = var('a1 a2 a3 a4')
equis = var('x1 x2')
alfa = []
for i in range(len(xor)):
alfa.append(signos[i] * literals[i])
alfas = Matrix(alfa)
k = zeros(len(xor))
for i in range(len(xor)):
for j in range(len(xor)):
k[i,j] = (1+(Matrix(xor[j]).transpose() * Matrix(xor[i]))[0])**2
ecuation = (alfas.transpose() * k * alfas)[0] * -1/2
for i in literals:
ecuation += i
siseq = diff(ecuation, literals)
solution = solve(siseq, literals)
def kernel(list):
nlist=[]
for i in list:
nlist.append([1, i[0]**2, i[0]*i[1]*sqrt(2), i[1]**2, i[0]*sqrt(2), i[1]*sqrt(2)])
return nlist
kersol = kernel(xor)
w = Matrix([0,0,0,0,0,0])
for i in range(len(xor)):
w += signos[i]*Matrix(kersol[i]) * solution[literals[i]]
compxor = Matrix(kernel([equis])[0]).transpose() * w
#entonces compxor nos debe dar como resultado -x1*x2 y es asi como se comporta una compuerta xor, donde x1 y x2 son la entradas, mas que ovio verdad.

Aquí vemos una imagen que nos representa dos clases ya separadas, esta imagen la tome de la aplicacion en linea: http://svm.dcs.rhbnc.ac.uk/pagesnew/GPat.shtml. Espero que este siempre disponible en línea, si no ya hare mi propia aplicación para graficar los resultados de la svm.
Bien y eso que!, bueno, bueno vamos a ver como se hace un svm para el proceso de aprendizaje supervisado de una compuerta xor. Puesto que en internet se encuentra mucha información acerca del tema, no voy a reparar en detalles, como lo serian los optimizadores de lagrange y las funciones kernel y todo el principio matemático(matrices, derivadas, sistemas de ecuaciones, etc), ya que mi objetivo es mostar una manera rápida de construir un svm con python y sympy, sin complicados procedimientos matemáticos, claro que también se puede hacer en matlab, pero bueno no nos gustan las cajas negras y por eso no lo hacemos en matlab.
Primero vamos a derivar manualmente, respecto de a1, a2, a3, a4:
a1 + a2 + a3 + a4 + a1*a4 + a2*a4 + a3*a4 - a1*a2 - a1*a3 - a2*a3 - 9*a1^2/2 - 9*a2^2/2 - 9*a3^2/2 - 9*a4^2/2
Y luego solucionamos el sistema de ecuaciones.
No, es una broma!, para eso tenemos las rutinas proporcionadas por sympy para no quebrarnos la cabeza.
Bien veamos el codigo.
from sympy import *
xor = [[-1,-1],[-1,1],[1,-1],[1,1]]
signos = [-1,1,1,-1]
literals = var('a1 a2 a3 a4')
equis = var('x1 x2')
alfa = []
for i in range(len(xor)):
alfa.append(signos[i] * literals[i])
alfas = Matrix(alfa)
k = zeros(len(xor))
for i in range(len(xor)):
for j in range(len(xor)):
k[i,j] = (1+(Matrix(xor[j]).transpose() * Matrix(xor[i]))[0])**2
ecuation = (alfas.transpose() * k * alfas)[0] * -1/2
for i in literals:
ecuation += i
siseq = diff(ecuation, literals)
solution = solve(siseq, literals)
def kernel(list):
nlist=[]
for i in list:
nlist.append([1, i[0]**2, i[0]*i[1]*sqrt(2), i[1]**2, i[0]*sqrt(2), i[1]*sqrt(2)])
return nlist
kersol = kernel(xor)
w = Matrix([0,0,0,0,0,0])
for i in range(len(xor)):
w += signos[i]*Matrix(kersol[i]) * solution[literals[i]]
compxor = Matrix(kernel([equis])[0]).transpose() * w
#entonces compxor nos debe dar como resultado -x1*x2 y es asi como se comporta una compuerta xor, donde x1 y x2 son la entradas, mas que ovio verdad.
Aquí vemos una imagen que nos representa dos clases ya separadas, esta imagen la tome de la aplicacion en linea: http://svm.dcs.rhbnc.ac.uk/pagesnew/GPat.shtml. Espero que este siempre disponible en línea, si no ya hare mi propia aplicación para graficar los resultados de la svm.
Soy neófito en Phyton... ¿Algo similar para C++?
ResponderEliminarDigo, para matrices está el Numerical Recipies, pero todo un CAS?
Pos supuesto que si te recomiendo giac/Xcas, es totomente c++
ResponderEliminar