Kiko Correoso

Análisis de componentes principales con python

Esta entrada también se podría haber llamado:
‘Reducción de la dimensión’
‘Comprimiendo imágenes usando análisis de componentes principales y python’
Para la siguiente entrada se ha usado python 2.7.2, numpy 1.6.1, matplotlib 1.1.0 y sklearn 0.10

El análisis de componentes principales (PCA, por sus siglas en inglés, Principal Component Analysis) es una técnica que trata de reducir el número de dimensiones (número de variables) de un conjunto de datos intentando, a su vez, conservar la mayor cantidad de información. Es una técnica extremadamente útil como análisis exploratorio de datos (exploratory data analysis, pongo algunos términos en inglés porque a veces pueden resultar extraños en castellano), cuando se tiene demasiada información (muchas dimensiones, variables) y no se puede analizar correctamente la información. Se ha usado de forma exitosa para encontrar patrones, determinar ‘outliers’, compresión de imágenes,… Más adelante se explicará brevemente el proceso matemático que hay detrás.
Para el presente artículo vamos a usar el PCA para obtener imágenes comprimidas. Vamos a trabajar con una imagen monocromática extraída de la galería de AdeRussell en flickr. (con licencia cc 2.0) La imagen en cuestión es la siguiente:

Martin Luther King Memorial and the Washington Monument por AdeRussell

Martin Luther King Memorial and the Washington Monument por AdeRussell


Primero la guardaremos en nuestro equipo usando la biblioteca urllib2 disponible en la biblioteca estándar de vuestra instalación de python:
[sourcecode language=”python”]
import urllib2
## Leemos la imagen desde la url
url = ‘http://farm9.staticflickr.com/8312/8059125132_bed732fcc8_z.jpg’
kk = urllib2.urlopen(url).read()
## Guardamos la imagen en el directorio donde nos encontremos
## con el nombre ‘king.jpg’
imagen = open(‘king.jpg’, ‘wb’)
imagen.write(kk)
imagen.close()
[/sourcecode]
La imagen está en formato jpg, la vamos a leer usando matplotlib y vamos a guardar la información en una matriz 2D (tenemos tres canales (r,g,b) que son iguales (imagen en escala de grises) por lo que solo vamos a usar uno de ellos).
[sourcecode language=”python”]
import numpy as np
import matplotlib.pyplot as plt
## Leemos la imagen como un numpy array
kk = plt.imread(‘king.jpg’)
## Si hacemos kk.shape vemos que existen
## tres canales en la imagen (r, g, b)
## Pero como es una imagen en escala de grises
## Los tres canales tienen la misma información
## por lo que nos podemos quedar con un solo canal
plt.subplot(221)
plt.title(‘canal 1’)
plt.imshow(kk[:,:,0])
plt.subplot(222)
plt.title(‘canal 2’)
plt.imshow(kk[:,:,1])
plt.subplot(223)
plt.title(‘canal 3’)
plt.imshow(kk[:,:,2])
## Vemos que la imagen está rotada, hacemos uso de np.flipud
## http://docs.scipy.org/doc/numpy/reference/generated/numpy.flipud.html
plt.subplot(224)
plt.title(‘canal 1 rotado en BN’)
plt.imshow(np.flipud(kk[:,:,0]), cmap=plt.cm.Greys_r)
plt.show()
## Finalmente, nos quedamos con una única dimensión
## Los tres canales rgb son iguales (escala de grises)
matriz = np.flipud(kk[:,:,0])
[/sourcecode]
Bueno, ahora ya tenemos nuestra imagen como la queremos para poder empezar a trabajar con ella.
¿Cómo se obtienen las componentes principales?
Leer más »Análisis de componentes principales con python

Lanzando proyectiles (con ayuda de vpython)

La mayoría de vosotros habréis resuelto el típico problema del lanzamiento de un proyectil que describe una trayectoria parabólica. Las ecuaciones que describen el movimiento son:

  • Vector posición

$latex x = v_{0x} t + x_0$
$latex y = -frac{1}{2} g t^{2} + v_{0y} t + y_0$

  • Vector velocidad

$latex v_x = v_{0x}$ con $latex v_{0x} = v_0 cos alpha$
$latex v_y = -g t + v_{0y}$ con $latex v_{0y} = v_0 sin alpha$
Hoy vamos a intentar resolverlo de forma gráfica con la ayuda de python y vpython. La biblioteca vpython une python con una librería gráfica 3D de forma que, como vamos a ver, hacer animaciones 3D sencillas se convierte en un juego.
[sourcecode language=”python”]
import visual as vs
import numpy as np
## valores iniciales (modifícalos bajo tu responsabilidad)
v0 = 20 ## v en m/s
alfa = 60 ## ángulo en grados
vel_fotogramas = 10  ## la velocidad del video
## Constantes
g = 9.81 ## Aceleración de la gravedad
## ecuaciones
v0x = v0 * np.cos(np.deg2rad(alfa))
v0z = v0 * np.sin(np.deg2rad(alfa))
t_total = 2 * v0z / g
x_final = v0x * t_total
## Empezamos con visual python (vpython)
## Creamos el ‘suelo’
suelo = vs.box(pos = (x_final/2., -1, 0),
size = (x_final, 1, 10), color = vs.color.green)
## Creamos el ‘cañón’
canyon = vs.cylinder(pos = (0, 0, 0),
axis = (2 * np.cos(np.deg2rad(alfa)), 2 * np.sin(np.deg2rad(alfa)), 0))
## Creamos el proyectil y una línea que dejará la estela del proyectil
bola = vs.sphere(pos = (0, 0, 0))
bola.trail = vs.curve(color=bola.color)
## Creamos la flecha que indica la dirección del movimiento (vector velocidad)
flecha = vs.arrow(pos = (0, 0, 0),
axis = (v0x, v0z, 0), color = vs.color.yellow)
## texto (ponemos etiquetas para informar de la posición del proyectil)
labelx = vs.label(pos = bola.pos, text= ‘posicion x = 0 m’, xoffset=1,
yoffset=80, space=bola.radius, font=’sans’, box = False,
height = 10)
labely = vs.label(pos = bola.pos, text= ‘posicion y = 0 m’, xoffset=1,
yoffset=40, space=bola.radius, font=’sans’, box = False,
height = 10)
## Animamos todo el cotarro!!!
t = 0
while t <= t_total:
bola.pos = (v0x * t, v0z * t – 0.5 * g * t**2, 0)
flecha.pos = (v0x * t, v0z * t – 0.5 * g * t**2, 0)
flecha.axis = (v0x, v0z – g * t, 0)
bola.trail.append(pos=bola.pos)
labelx.pos = bola.pos
labelx.text = ‘posicion x = %s m’ % str(v0x * t)
labely.pos = bola.pos
labely.text = ‘posicion y = %s m’ % str(v0z * t – 0.5 * g * t**2)
t = t + t_total / 100.
vs.rate(vel_fotogramas)
[/sourcecode]
Voy a explicar brevemente lo que hace el código:
Leer más »Lanzando proyectiles (con ayuda de vpython)

Matrópolis

Aquí siempre andamos trasteando con código. Para relajar un poco el lado técnico del blog hoy os traemos una frikada que sabemos os gustará. Ya lo puso Juanlu hace unos días por nuestro twitter pero si no lo has visto aún, aquí lo tienes: “Matropolis: Científicos del mundo uníos (también… Leer más »Matrópolis

Manual de introducción a matplotlib.pyplot (IX): Miscelánea

Esto pretende ser un tutorial del módulo pyplot de la librería matplotlib. El tutorial lo dividiremos de la siguiente forma (que podrá ir cambiando a medida que vayamos avanzando).

  1. Primeros pasos
  2. Creando ventanas, manejando ventanas y configurando la sesión
  3. Configuración del gráfico
  4. Tipos de gráfico I
  5. Tipos de gráfico II
  6. Tipos de gráfico III
  7. Tipos de gráfico IV
  8. Texto y anotaciones (arrow, annotate, table, text…)
  9. Herramientas estadísticas (acorr, cohere, csd, psd, specgram, spy, xcorr, …)
  10. Eventos e interactividad (connect, disconnect, ginput, waitforbuttonpress…)
  11. Miscelánea

[Para este tutorial se ha usado python 2.7.1, ipython 0.11, numpy 1.6.1 y matplotlib 1.1.0 ]
[DISCLAIMER: Muchos de los gráficos que vamos a representar no tienen ningún sentido físico y los resultados solo pretenden mostrar el uso de la librería].
En todo momento supondremos que se ha iniciado la sesión y se ha hecho
[sourcecode language=”python”]
import matplotlib.pyplot as plt
import numpy as np
plt.ion()
[/sourcecode]
Después de dar un repaso por toda la librería, obviando algunas funciones estadísticas y eventos, vamos a acabar este tutorial viendo algunas funciones que sirven para leer y guardar imágenes.
Imaginad que queréis usar una imagen de fondo, por ejemplo vuestro nombre, o las siglas de creative commons o una foto,…, en vuestros gráficos. Para el ejemplo que vamos a ver a continuación vamos a usar la imagen que está en el siguiente enlace como fondo (guardadala en local para poder leerla).
[sourcecode language=”python”]
background = plt.imread(‘Cc.large.png’) # Leemos la imagen que queremos usar de fondo, lo que escribáis entre comillas es la ruta a la imagen
x = np.arange(background.shape[1]) # Definimos valores de x
y = np.random.rand(background.shape[0]) * background.shape[0] # Definimos valores de y
plt.plot(x, y) # Dibujamos la serie
plt.imshow(background, alpha = 0.25) # Creamos el fondo con una transparencia del 0.10 (1 es opaco y 0 es transparente)
[/sourcecode]
El resultado es el siguiente:

Con plt.imread lo que hacemos es leer una imagen y convertirla en un numpy array que más tarde podemos utilizar como queramos (en este caso, como fondo para la imagen). Con plt.imshow lo que hemos hecho es mostrar la imagen en pantalla. Por último, que sepáis que también existe plt.imsave, que permite guardar un numpy array como una imagen.
Leer más »Manual de introducción a matplotlib.pyplot (IX): Miscelánea

The amazing Spyder, man!!!

Spyder es la abreviación de Scientific PYthon Development EnviRonment. Según la documentación oficial, Spyder es un potente entorno de desarrollo interactivo para Python con edición avanzada, ‘testeo’ interactivo y capacidades de introspección y depuración (debugging) y, esto es lo que nos interesa, un entorno de computación numérica gracias al soporte de IPython y de populares librerías como numpy, scipy y matplotlib (todas conocidas ya por aquí).
Se puede instalar tanto en Linux como en Windows (y en Mac para los amantes de Alcatraz). En el siguiente enlace podéis ver documentación para la instalación y los requerimientos previos para poder instalarlo.
En un vistazo general podemos ver que es muy adaptable a nuestras necesidades (o manías) permitiendo:

  • definir accesos rápidos,
  • Gestionar el PYTHONPATH de manera visual

  • Acceso a la documentación de las librerías más importantes (Numpy, Scipy, Matplotlib,…) desde la ayuda del propio IDE
  • Acceso directo a herramientas (y documentación) Qt.
  • Configuración del coloreado de la sintáxis
  • Podemos colocar los paneles como mejor nos convenga. En general, yo lo configuro con un explorador de archivos a la izquierda, el editor a la derecha y abajo cosas útiles como consolas, el historial, y el explorador de variables:
  • Pero con el mismo ratón se puede recolocar todo de forma sencilla y se puede elegir que aparece en la pantalla desde el menú ‘view | Windows and toolbars’:

Puedes ver más pantallazos en el siguiente enlace.
El editor en sí permite resaltar código Python, C/C++ y Fortran, completado de código, permite analizar el código con pylint, depurar con pdb (o winpdb), avisos y errores en tiempo real con pyflakes,… Lo mínimo que lleva hoy en día cualquier editor potente.
Leer más »The amazing Spyder, man!!!

Manual de introducción a matplotlib.pyplot (VIII): Texto y anotaciones

Esto pretende ser un tutorial del módulo pyplot de la librería matplotlib. El tutorial lo dividiremos de la siguiente forma (que podrá ir cambiando a medida que vayamos avanzando).

  1. Primeros pasos
  2. Creando ventanas, manejando ventanas y configurando la sesión
  3. Configuración del gráfico
  4. Tipos de gráfico I
  5. Tipos de gráfico II
  6. Tipos de gráfico III
  7. Tipos de gráfico IV
  8. Texto y anotaciones (arrow, annotate, table, text…)
  9. Herramientas estadísticas (acorr, cohere, csd, psd, specgram, spy, xcorr, …)
  10. Eventos e interactividad (connect, disconnect, ginput, waitforbuttonpress…)
  11. Miscelánea

[Para este tutorial se ha usado python 2.7.1, ipython 0.11, numpy 1.6.1 y matplotlib 1.1.0 ]
[DISCLAIMER: Muchos de los gráficos que vamos a representar no tienen ningún sentido físico y los resultados solo pretenden mostrar el uso de la librería].
En todo momento supondremos que se ha iniciado la sesión y se ha hecho
[sourcecode language=”python”]
import matplotlib.pyplot as plt
import numpy as np
plt.ion()
[/sourcecode]
Hasta ahora hemos visto como configurar las ventanas, manejo de las mismas, definir áreas de gráfico, algunos tipos de gráficos… En esta ocasión nos interesa ver como podemos meter anotaciones, tablas,…, en nuestros gráficos.
A lo largo de las anteriores entregas del tutorial hemos podido ver algunas formas de tener anotaciones típicas para el título, los ejes, leyenda,… (title, suptitle, xlabel, ylabel, figtext, legend,…). En este caso vamos a revisar las posibilidades de escribir texto personalizado mediante el uso de plt.text, plt.arrow, plt.annotate y plt.table.
Leer más »Manual de introducción a matplotlib.pyplot (VIII): Texto y anotaciones