miércoles, 31 de octubre de 2012

3° Entrega - Agrupamiento

Introducción 
En esta práctica realizaremos un sistema adaptativo el cual relacionaremos con técnicas de sistemas inteligentes, hemos elegido la técnica de agrupamiento, la cual consiste en separar los elementos en grupos, los elementos de esos grupos deben de ser lo más similares posibles entre ellos.
Realizaremos un algoritmo clásico de agrupamiento, el algoritmo K-means. 

Objetivo 
Nuestro objetivo es aprender a utilizar la técnica de agrupamiento del algoritmo K-means, en el cual la idea principal es dar a el centroide de cada grupo ciertos vectores, los cuales serán comparados con los vectores de los animales que usaremos en esta práctica. Analizaremos cuales son los animales que son idénticos o similares a los centroides y ese centroide agrupará a los animales de la misma especie. El resultado que pretendemos obtener es que al analizar cada punto (animal) y compararlos con los centroides, se pueda agrupar cada especie con su centroide correspondiente, teniendo este las mismas características de la especie. 

Justificación 
En clase se vio este tema y llamó nuestra atención. A los integrantes del equipo se nos facilitó el aprendizaje de este algoritmo, por consiguiente decidimos realizar esta técnica en nuestra práctica.
Estuvimos investigando y nos pareció interesante conocer más sobre este tema ya que hay muchas áreas en las cuales se puede aplicar esta técnica.
La única diferencia en nuestro programa a lo visto en clase es que las especies de animales y centroides tienen ciertos vectores (características) ya establecidos, así que el centroide agrupará a la especie que tenga las mismas características que él, no como lo visto en clase que el centroide agrupaba a los puntos más cercanos a él.

Desarrollo
En un inicio estábamos confundidos con respecto al agrupamiento de las especies que queríamos realizar, pero pudimos aclarar las dudas. Empezamos en primer lugar a generar ideas, anotar lo que se nos ocurría que podía servir para el programa, después de tener la idea algo clara de como sería el código, pensamos en que animales usaríamos para agrupar, decidimos que serían cuyos, perros y serpientes, buscamos algunas imágenes que pudieran servir, las convertimos a .png y cambiamos su tamaño para que se viera bien en el programa. Seguido de esto empezamos con la codificación, primero poniendo cada imagen con un botón o tecla distinta, los cuyos se insertan con el mouse (click izquierdo), los perros con la tecla "P" y las serpientes con la letra "S". A cada animal le dimos sus características basadas en 0's y 1's, al igual que los centroides.
Tuvimos que hacer modificaciones en el código debido a que las listas en las cuales estaban incluidas las coordenadas de los animales y sus vectores, causaban ciertos problemas, pero con un poco de paciencia se pudieron resolver.
Aplicamos la formula del k-means que es la sumatoria de los puntos que son iguales al centroide, sumamos las x's y las dividimos entre el total de estas, hicimos lo mismo con las y's, así pudimos agrupar a las distintas especies.
Al final se nos ocurrió unir el centroide con las especies agrupadas para poder apreciar mejor cual era el grupo que se había formado con el centroide.

Código
# usr/bin/python

import pygame
import time
import random

ancho = 1000
alto = 700

#         Mamifero - Domestico - Carnivoro - Grande - Cola - Colmillos
# Cuyo       1           1           0          0       0        0        [1, 1, 0, 0, 0, 0]
# Perro      1           1           1          1       1        1        [1, 1, 1, 1, 1, 1]
# Serpientes 0           0           1          0       1        1        [0, 0, 1, 0, 1, 1]

if __name__ == "__main__":
    # Declaramos la pantalla con todas sus imagenes y agregamos la imagen
    pantalla = pygame.display.set_mode((ancho, alto))
    pygame.display.set_caption("Agrupamiento")
    zacate = pygame.image.load("Zacate.jpg")
    casa_cuyo = pygame.image.load("puntoazul.png")
    casa_perro = pygame.image.load("puntorojo.png")
    casa_serpiente = pygame.image.load("puntoamarillo.png")
    pantalla.blit(zacate, (0, 0))
    pygame.display.update()
    # Declaramos los vectores de los cuyos y de los perros
    vector_cuyo = [1, 1, 0, 0, 0, 0] # Centroide cuyo
    vector_perro = [1, 1, 1, 1, 1, 1] # Centroide perro
    vector_serpiente = [0, 0, 1, 0, 1, 1] # Centroide serpiente
    posicion = []
    lista = []
    vector = []
    coordenadas = []
    cuyos_x = []
    cuyos_y = []
    perros_x = []
    perros_y = []
    serpientes_x = []
    serpientes_y = []
    x = 0

    #Pedimos cual es la cantidad de los animales que se van a agregar
    cantidad = input("Cuantos animales en total desea agregar? ")
    print cantidad
    i = cantidad 
    
    # Ciclo para poner los animalitos en su posicion
    while i > 0:
        time.sleep(0.1)
        
        # La imagen de los cuyos, de los perros y de las serpientes es aleatoria
        cuyos = random.randint(1, 6)
        if cuyos == 1:
            cuyo = pygame.image.load("cuyo1.png")
        elif cuyos == 2:
            cuyo = pygame.image.load("cuyo2.png")
        elif cuyos == 3:
            cuyo = pygame.image.load("cuyo3.png")
        elif cuyos == 4:
            cuyo = pygame.image.load("cuyo4.png")
        elif cuyos == 5:
            cuyo = pygame.image.load("cuyo5.png")
        else:
            cuyo = pygame.image.load("cuyo6.png")

        perros = random.randint(1, 6)
        #Aquí van las imagenes de los perros

        serpiente = random.randint(1, 5)
        #Aquí van las imagenes de las serpientes

       # Actividad del mouse o los botones del teclado
        for event in pygame.event.get():
            # Mouse
            if event.type == pygame.MOUSEBUTTONDOWN:
                vector = [1, 1, 0, 0, 0, 0]
                pos_x, pos_y = pygame.mouse.get_pos()
                print "presionando"
                coordenada_x = [pos_x]
                coordenada_y = [pos_y]
                # Se comparan los vectores para saber que animal es y se agregan a una lista
                if vector == vector_cuyo:
                    lista.append(vector)
                    lista.append(coordenada_x)
                    lista.append(coordenada_y)
                # Se agrega la imagen
                pantalla.blit(cuyo, (pos_x - 25, pos_y - 15))
                pygame.display.update()
                i -= 1
                print i
                print lista
                x += 1

            # Teclado 
            if event.type == pygame.KEYDOWN:

                #Perros
                if event.key == pygame.K_p:
                    vector = [1, 1, 1, 1, 1, 1]
                    pos_x, pos_y = pygame.mouse.get_pos()
                    #Se hace lo mismo que con los cuyos

                #Serpientes
                if event.key == pygame.K_s:
                    vector = [0, 0, 1, 0, 1, 1]
                    pos_x, pos_y = pygame.mouse.get_pos()
                    #Se hace lo mismo que con los cuyos 

            if event.type == pygame.QUIT:
                exit()
    
    # Separamos los diferentes valores guardados en la lista, aqui se encuentran los vectores y las coordenadas
    vectores = lista[0::3]
    coordenada_x = lista[1::3]
    coordenada_y = lista[2::3]
    print "Vectores: ", vectores
    print "Coordenada x: ", coordenada_x
    print "Coordenada y: ", coordenada_y

    an = 0
    en = 0
    iin = 0
    largo = len(vectores)
    for i in range (largo):
        if vectores[i] == vector_cuyo:
            #print "Cuyos x: ", coordenada_x[i]
            a = coordenada_x[i]
            cuyos_x.append(a)
            b = coordenada_y[i]
            cuyos_y.append(b)
            #print "Cuyos x: ", a
            #print "Cuyos y: ", coordenada_y[i]
            cuyos_x[en] = int("".join(str(x) for x in a))
            print "Cuyos_x: ", cuyos_x # Se guardan las coordenadas de x de cada uno de los cuyos
            cuyos_y[en] = int("".join(str(x) for x in b))
            print "Cuyos_y: ", cuyos_y # Se guardan las coordenadas de y de cada uno de los cuyos
            print en
            en += 1
        if vectores[i] == vector_perro:
            #Lo mismo que con los cuyos

        if vectores[i] == vector_serpiente:
            #Lo mismo que con los cuyos

    suma_cuyos_x = 0
    suma_cuyos_y = 0
    promedio_cuyo_x = 0
    promedio_cuyo_y = 0
   
    
    # Calculamos el promedio de las coordenadas en x y en y para los cuyos
    for i in range (len(cuyos_x)):
        suma_cuyos_x = suma_cuyos_x + cuyos_x[i]
        promedio_cuyo_x = suma_cuyos_x / len(cuyos_x)
        suma_cuyos_y = suma_cuyos_y + cuyos_y[i]
        promedio_cuyo_y = suma_cuyos_y / len(cuyos_y)
        
    print "Promedio cuyos x: ", promedio_cuyo_x
    print "Promedio cuyos y: ", promedio_cuyo_y

    # Calculamos el promedio de las coordenadas en x y en y para los perros
    
    
    # Calculamos el promedio de las coordenadas en x y en y para las serpientes
    
    # Se agregan las lineas que unen a los cuyos
    linea1 = []
    for j in range (len(cuyos_x)):
        linea1 = [cuyos_x[j], cuyos_y[j]]
        linea = pygame.draw.line(pantalla, (0, 5, 250), linea1, (promedio_cuyo_x, promedio_cuyo_y), 3)

    # Se agregan las lineas que unen a los perros
    
    # Se agregan las lineas que unen a las serpientes     

    # Se agregan los centroides
    pantalla.blit(casa_cuyo, (promedio_cuyo_x - 10, promedio_cuyo_y - 10))
    pantalla.blit(casa_perro, (promedio_perros_x - 10, promedio_perros_y - 10))
    pantalla.blit(casa_serpiente, (promedio_serpientes_x - 10, promedio_serpientes_y - 10))
    pygame.display.update()

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()

Resultados
Pudimos hacer que el programa mostrara una unión entre los animales similares y su respectivo centroide, cada grupo con un diferente color en las líneas que los unen al centroide. También teníamos la simple idea de usar puntos en una gráfica, pero vimos que podíamos hacerlo más atractivo y empleamos imágenes de los distintos animales.
Nos sentimos muy conformes con el programa ya que resultó ser más de lo que esperábamos.

Video

Conclusiones
Aprendimos sobre las diferentes aplicaciones donde se puede usar la técnica del agrupamiento. Gracias a las bases del agrupamiento se pueden realizar programas los cuales puedan detectar el cáncer, agrupar y clasificar diferentes elementos por sus características, entre otras.

Referencias
Página de la Dra. Sara Elena
Dibujar líneas con Pygame