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.
.



No hay comentarios:

Publicar un comentario