miércoles, 26 de noviembre de 2008

Support Vector Machine

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.

martes, 11 de noviembre de 2008

Matematicas con python

Ok basta de palabrería vamos ha ver algunas cosas de buena programación con python, antes que nada me gustaria platicarles hacerca de mi ultimo descubrimiento, se trata de sympy.

Sympy es una librería para calculo simbolico (cas), -¿qué es eso del calculo simbólico?, -a pues es una maravilla, se trata de un muy completo ambiente que puede hacer operaciones matemáticas entre números reales y símbolos. por ejemplo se pueden hacer operaciones como 2*a+4*a=6a, -¿y bien y esto tan sencillo para que puede servir?. A pues nos habre todo un mundo de posibilidades de calculo, por que este principio no solo aplica a la aritmética, sympy puede hacer operaciones de matrices, integración simbólica, algebra lineal, entre otras operaciones tal como lo haríamos en el cuaderno que llevamos a clases, además de las bondades del lenguaje de programación python.

Para mostrar algo de las posibilidades ilimitadas de cálculo de sympy voy a mostrar parte del código de un clasificador bayesiano, que es una técnica de reconocimiento de patrones, elaborado como tarea para la asignatura de inteligencia artificial en el Itesi.


#Como primera parte aquí tenemos dos vectores con par de puntos (x,y), que nos representan dos patrones linealmente separables:
w1 = [[2, 6], [3, 4], [3, 8], [4, 6]]
w2 = [[1, -2], [3, 0], [3, -4], [5, -2]]

#Ahora procederemos ha hacer algunas operaciones algebraicas y de matrices para separar la clase w1

#nótese que en la línea de abajo se dan de alta algunas variables simbólicas
vars = var('x y')
size = len(vars)

#este es un procedimiento para a calcular la media de un vector
#hasta aquí es solo código python
def mean(vector, dim):
mean = [0,0]
for i in range(0,dim):
for j in vector:
mean[i] += j[i]
mean[i]/=len(vector)
return mean

m1 = mean(w1, size)

#lo interesante viene a continuación, se trata de la conversión entre vectores y matrices
#y sus consecuentes operaciones
def matriz_sigma_inversa(vector, mean):
array_mtx = range(0,len(vector))
sum_mtx = zeros(len(mean))
for i in array_mtx:
array_mtx[i] = Matrix(vector[i]) - Matrix(mean)
sum_mtx += (array_mtx[i] * array_mtx[i].transpose())
return (sum_mtx * 1/len(vector)).inv()

#es aquí donde se realizan las operaciones simbólicas entre números y literales "x", "y"
def matriz_vector_mean(mean, literals):
return Matrix(literals) - Matrix(mean)

#wow podria ser esto mas facil!!!
mtx_sig_w1 = matriz_sigma_inversa(w1, m1)
mtx_med_w1 = matriz_vector_mean(m1, vars)
mtx_tran_w1 = matriz_vector_mean(m1, vars).transpose()
det_w1 = mtx_sig_w1.det()

#ahora tenemos la ecuación de la clase w1, hacer esto para la clase w2
gw1 = (mtx_tran_w1 * mtx_sig_w1 * mtx_med_w1 * -1/2)[0] + (ln(det_w1)*-1/2 + ln(0.5)).evalf()

#igualamos ha cero la ecuación
bayes = gw1-gw2

#y finalmente despejamos "y", lo cual nos dará como resultado una ecuación cuadrática
#que al ser graficado nos mostrara el hiperplano que separa alas clases w1 de w2
solve(bayes, y)

Bien eso es fácil, no son muchas operaciones pero imaginemos un vector de tres dimensiones con muchos mas puntos para graficar, esto si que llevaría mucho tiempo hacer a la antigua.


Ahora veamos la grafica con gnuplot de un espacio vectorial de tres dimenciones.

Por supuesto que esto se puede hacer todo desde python, ya hablaremos de la maravilla de gnuplot en otra ocacion.
.



jueves, 2 de octubre de 2008

Y la tecnologia nos hara mejores!

Como geek no puedo negar mi fascinación por la tecnología y los medios de comunicación electrónicos y defiendo mucho como estos nos llevaran a una mejor sociedad, dado que se dice que vivimos en la era de la información y la comunicación, la cuestión que aqui se plantea es que ¿en que momento entramos a esta era de la humanidad? si ya desde hace mucho que nos organizamos como sociedad para poder mandar un correo escrito o que nos volvimos mas sofisticados con la invención del teléfono y la radio, pero es realmente aquí, que con estos medios de comunicación masiva es que llegamos ha esta era, yo no creo que sea asi de sencillo, por que es muy fácil sugestionar mediaticamente a un grupo de personas, los medios pueden fácilmente influenciar las tendencias de mercadeo o peor aun una campaña política, no digo que esto sea malo, pero lo cierto es que al final siempre sera la opinión de una persona que puede ser desde quien se encarga de redactar los tabloides de un noticiero o uno de los llamados expertos de marketing, etc. Y esto nos obliga a formar un criterio a partir desde la perspectiva de quien posea los medios.

Pienso que entramos a la era de la información y la comunicación a partir de que tomamos los medios en nuestras manos, a partir de que podemos entrar al "youtube" y teclear la palabra "acteal" y vimos la versión del indígena chiapaneco que se salvo de ser masacrado y no la version editada de cinco minutos de un noticiero, por que como han de saber el tiempo en televisión cuesta mucho, vimos también como es que un simple celular con cámara ayudo a condenar un crimen de odio racial, por que con un teléfono se filmo a un policía que atacaba a una mujer afroamericana en los estados unidos y este fue llevado a la corte. Pero debemos ser responsables con este nuevo poder y condenar su uso para promover el odio y la intolerancia como paso con el ataque a un grupo social llamado los "emos".

Nadie podra censurar estos foros, habra algunos goviernos que les encantaria controlar lo que la gente publica, pero si el servidor no esta en su pais, simplemente no pueden hecerlo y si lo estubiera simplemente se cambia de pais el servidor, ni siquiera los estados unidos han podido hecer esto.