domingo, 20 de enero de 2013

Métricas del grafo de hash tags

Tutorial de Grafos
Anterior        Índice       

El programa que extrae la información usando la API de Twitter está usando exploración aleatoria. Es decir, selecciona aleatoriamente el siguiente hash tag a solicitar. Este enfoque resulta muy práctico y nos permite descubrir muchos hash tags. Por ejemplo, después de haber ejecutado el programa algunas horas, este ha visitado alrededor de 3,000 nodos pero ha descubierto alrededor de 150,000. Esto nos da un grafo bastante incompleto, lo cual puede ser frustrante al momento de ejecutar algoritmos como el de encontrar la ruta más corta, ya que es muy probable que si seleccionamos dos nodos al azar sólo haya una ruta entre ellos. Lo ideal sería poder visitar la mayoría de los nodos que conocemos; el problema es que el realizar las peticiones de tweets es una operación costosa.

Por ello es que decidí modificar el programa para visitar sólo aquellos hash tags que luzcan más “relevantes”. La definición de relevancia es un tanto arbitraria y la definí intuitivamente. Obtuve algunas métricas con los nodos que he visitado hasta el momento para obtener un parámetro que no fuera del todo subjetivo.

NOTA: las siguientes conclusiones están basadas en los aproximadamente 3,000 hash tags que visite usando el programa descrito en secciones anteriores. Por lo que estás conclusiones pueden ser incompletas e incluso incorrectas, pero son un buen inicio para los propósitos de este tutorial.

El término hash tag y nodo son equivalentes en la siguiente discusión.

La primer métrica es el número de vecinos de un nodo: en promedio tienen 133 vecinos. En la siguiente gráfica observamos que más del 40% de los nodos tienen 90 o más vecinos. Esto concuerda con nuestros resultados (sólo 3,000 visitados pero ya llevamos 150.000 descubiertos); es decir, el universo de nodos descubiertos crece muy rápidamente conforme vamos visitando más nodos.

Es interesante ver como hay también un buen porcentaje de nodos con muy pocos vecinos, tal vez esto se deba a hash tags esporádicos.

Bueno, regresando a la pregunta de qué es un nodo relevante, decidí ver la fortaleza entre dos hash tags, y esto es simplemente cuantas veces aparece un hash tag en la búsqueda de otro. Por ejemplo, cuando buscamos #Toluca, de los 400 tweets obtenidos, el hash tag #futbol apareció 20 veces; en este caso digo que la fortaleza de #Toluca a #futbol es 20.

La siguiente gráfica muestra la distribución de las fortalezas de los enlaces. Noten como el 70% de los enlaces sólo tienen fortaleza 1, pareciera que la mayoría de las relaciones entre hash tags son esporádicas. Sin embargo, existe un porcentaje considerable de enlaces con fortaleza igual o mayor a 9.

Precisamente está es la métrica que utilicé para decidir que nodos visitar. Sólo visitaremos aquellos nodos que estén muy conectados a alguno de los nodos que hayamos visitado. Obviamente hay que cuidar no ser muy restrictivo que lleguemos al punto de no encontrar más nodos. Para ello obtuve la siguiente gráfica donde podemos ver que aproximadamente la mitad de los nodos están conectados a por lo menos otro nodo con fortaleza 9 o mayor. Lo cual es un buen indicador que aún cuando estamos reduciendo el espacio de búsqueda, seguiremos encontrando nuevos nodos.

Primero probé con enlaces de fortaleza 4, pero aún así el número de nodos conocidos crecía muy rápidamente. Así que ajuste este valor a 10.

El código lo pueden encontrar aquí. El archivo tweets_old.zip contiene la información usada para las métricas. El archivo tweet_graph.py calcula y despliega las métricas. Tweet_search.py es el programa de extracción de tweets con las modificaciones mencionadas.

Tutorial de Grafos
Anterior        Índice       

sábado, 12 de enero de 2013

Creación del grafo de hash tags

Tutorial de Grafos
Anterior        Índice        Siguiente

Ahora que ya tenemos datos podemos empezar a crear nuestro grafo. Existen dos formas principales de representar un grafo: matriz de adyacencia o lista de adyacencia. Aquí usaremos una lista de adyacencia, en particular, usaremos un diccionario de adyacencia.

El programa twitter_graph.py contiene un ciclo doble donde construye el grafo. Después entra a un cliclo donde podemos teclear un hash tag y despliega los 10 hash tags vecinos más frecuentes.

Nuestro grafo lo representamos con un diccionario de diccionarios. En el diccionario externo las llaves son los nodos del grafo y los valores son los vecinos de este nodo. Siendo más precisos, un valor es otro diccionario, donde las llaves son los vecinos y los valores representan el número de veces que un hash tag apareció.

Veamos un ejemplo de la variable que apunta al grafo en el programa usando los resultados de la imagen anterior.

  • graph["#cozumel"]
    : contiene los vecinos del hash tag #cozumel.
  • graph["#cozumel"]["#cancun"]
    : regresa el número de veces que #cancun apareció en la búsqueda de #cozumel, en este caso 10 veces.

Vale la pena mencionar dos funciones de los diccionarios en python que ayudan a hacer código más compacto. El siguiente fragmento de código agrega el hash tag al grafo en caso de ser necesario.

if hash_tag not in graph: 
  graph[hash_tag] = dict() 
links = graph[hash_tag]

Esto es equivalente a usar la función setdefault, la cual regresa el valor asociado con la llave (primer parámetro), en caso de no existir, inserta la llave con el segundo parámetro en el diccionario y por último regresa ese nuevo valor.

links = graph.setdefault(hash_tag, dict()) 

El siguiente código inicializa e incrementa el número de ocurrencias de un vecino.

if neighbor not in links: 
  links[neighbor] = 1 
else: 
  links[neighbor] = links[neighbor] + 1

Esto se puede reemplazar por la siguiente línea de código:

links[neighbor] = links.get(neighbor,0) + 1

La función get regresa el valor asociado con la llave o en caso de no existir regresa el segundo parámetro.

El código lo pueden encontrar aquí. Para ejecutarlo sólo recibe la carpeta donde están guardados los tweets:

python twitter_graph.py ./tweets

También incluí un archivo zip que contiene alrededor de 3,000 hash tags consultados, sólo tienen que descomprimir este archivo. AVISO: algunos de los hash tags pueden resultar ofensivos, pero eso es lo que encontró el programa.

En el siguiente post veremos algunas métricas de este grafo.

Tutorial de Grafos
Anterior        Índice        Siguiente