lunes, 31 de marzo de 2014

Uniendo datos de la Wikipedia y LocaliData usando Open Refine

Wikipedia image

¿Cuántas veces habéis usado la Wikipedia para buscar datos que os interesaban? Sí, ya lo sabemos, muchas veces... Y no, hoy no os vamos a decir que la abandonéis porque tenemos todos sus datos en nuestra API... Entre otras cosas porque os estaríamos engañando...

Lo que os vamos a contar hoy es cómo utilizar datos de la Wikipedia como fuente para buscar más información en nuestra API, y así tener datos mucho más completos, procedentes de diversas fuentes. Eso sí, para poder seguir mejor este post es importante que hayáis practicado un poquito con Open Refine. Hay muy buena documentación en su website.

Así que vamos a empezar proponiéndonos la siguiente historia: "partimos de la lista de barrios de Madrid que tiene la versión española de Wikipedia, y queremos, para cada uno de ellos, saber el número de locales comerciales que tiene, así como su población, para mostrar toda esta información conjuntamente en alguna aplicación".

La verdad es que podríamos sacar esta lista de barrios directamente desde nuestra API (sí, tenemos una llamada que permite, dado un municipio como Madrid, obtener un listado de todos sus barrios)

Vamos, que podemos hacer la siguiente llamada y tener ya toda la información que necesitamos:
http://datos.localidata.com/recurso/territorio/Provincia/Madrid/Municipio/madrid/Barrio?api_key=<<API KEY>>

Y además, para obtener la información ampliada podemos usar la vista ampliada
http://datos.localidata.com/recurso/territorio/Provincia/Madrid/Municipio/madrid/Barrio?_view=ampliada&api_key=<<API KEY>>

Pero como en muchas ocasiones tenemos que comenzar con datos procedentes de alguna Web, esto es lo que vamos a aprender hoy. Vayamos paso por paso:

Paso 1. Obtener el listado de barrios de Madrid de Wikipedia y cargarlo en Open Refine

Simplemente buscando en la Web "barrios de Madrid Wikipedia" obtenemos una URL que nos proporciona un listado de barrios de Madrid.

Vamos a abrirlos en Open Refine, que previamente habremos tenido que instalar en nuestro ordenador. Normalmente, podremos acceder a Open Refine en la siguiente URL: http://127.0.0.1:3333/. A continuación creamos un proyecto y especificamos la URL de Wikipedia.

Cuando seleccionamos "Next >>" se cargará esta página de Wikipedia, y entonces tendremos que seleccionar como formato de la entrada XML y seleccionaremos la lista que contiene los barrios de Madrid como un listado, tal y como se muestra en la siguiente figura:

Una vez seleccionada la parte del código fuente HTML en la que estamos interesados, aparecerá algo parecido a lo que vemos en la siguiente figura:

Así que le podemos dar un nombre a nuestro proyecto (por ejemplo, BarriosDeMadrid) y comenzamos a trabajar con el proyecto.

Paso 2. Limpiando los datos que hemos obtenido de Wikipedia

Vamos a hacer las siguientes operaciones para limpiar estos datos:
  1. Hay varias columnas que podemos eliminar (la primera, la cuarta y la última), de tal manera que nos quedaremos sólo con las columnas del nombre del barrio y la página Wikipedia correspondiente. Para ello, seleccionamos en el menú de cada una de estas columnas la opción "Edit Column -> Remove this column".
  2. Las dos columnas que nos quedan las podemos renombrar, para que sea más sencillo tratar con ellas. Para ello, seleccionamos en el menú de cada una de estas columnas la opción "Edit Column -> Rename this column". Las vamos a llamar "Nombre" y "URL Wikipedia"
  3. También conviene quitar lo de "(Madrid)" de algunos de los barrios, para lo cual podemos seleccionar en el menú de la columna "Nombre" la opción del menú "Edit Cells -> Transform...", y realizar la transformación siguiente: value.replace("(Madrid)","").trim().
El resultado de realizar estas tres operaciones es el que se muestra en la siguiente figura:

Paso 3. Obteniendo los datos de nuestra API

Teniendo en cuenta que para obtener datos de cada uno de los barrios, las URIs de nuestra API se construyen con el siguiente patrón:
http://datos.localidata.com/recurso/territorio/Barrio/label/<<nombreBarrio>>?api_key=<<API Key>>

y que para obtener más datos del barrio (como los que estamos interesados en obtener para cada barrio) tenemos que usar la vista ampliada, deberíamos crear para cada barrio URIs del siguiente tipo:
http://datos.localidata.com/recurso/territorio/Barrio/label/<<nombreBarrio>>.json?_view=ampliada&api_key=<<API Key>>

Lo que podemos hacer es, en la columna "Nombre", seleccionar la opción de menú "Edit Column --> Add column based on this column...", y crear una nueva columna "URI LocaliData" con el siguiente valor: "http://datos.localidata.com/recurso/territorio/Barrio/label/"+escape(value,"url")+".json?_view=ampliada". Hay que tener en cuenta que aplicamos la función escape() sobre el valor del barrio para que se traten correctamente los valores con espacios en blanco, la ü de Argüelles, etc.

Como resultado de estas operaciones, obtendremos lo que aparece en la siguiente figura:

Paso 4. Ejecutando las llamadas a nuestra API

Ahora es el momento de ejecutar las llamadas a nuestra API para obtener los datos de cada uno de los barrios de Madrid. Para ello, en la columna "URI LocaliData" vamos a la opción "Edit Column --> Add Column by Fetching URLs...", que llamará a la URI correspondiente para cada una de las filas de nuestro fichero (139 de momento). Le daremos a la columna el nombre "Resultado LocaliData". Y para no saltarnos las limitaciones en el número de llamadas que cada usuario puede hacer por minuto a nuestra API, pondremos como opción de "throttle" un valor de 1000 milisegundos. La expresión a utilizar sera value+"&api_key=<<API KEY>>".

Después de un par de minutos obteniendo resultados de las 139 llamadas que se realizan a nuestra API, tendremos algo parecido a lo que se muestra a continuación.

Si facetamos sobre la columna recién obtenida, podemos ver que hemos conseguido encontrar resultados para 79 de los 139 barrios. Aunque en primer lugar debemos tener en cuenta que el número de barrios que actualmente tiene Madrid es de 128. Aunque parezca un número bajo, hay que tener en cuenta que la lista que obtuvimos en Wikipedia contenía barrios que realmente no son considerados barrios oficiales de Madrid (por ejemplo, Chueca, Ciudad Pegaso, La Rosilla, Covibar - que pertenece a Rivas-Vaciamadrid -, etc.). 

En otro post os contaremos cómo podemos mejorar ese número.

Paso 5. Obteniendo los datos de población total y número de locales a partir de los resultados en JSON

Una vez que ya tenemos todos los datos de los barrios, es el momento de encontrar los datos que estábamos buscando. Para ello, Open Refine proporciona una función para parsear JSON (parseJSON), que nos permite acceder a los datos que nuestra API ha devuelto. Concretamente, podemos crear dos columnas ("Edit Column --> Add Column based on this Column"), utilizando las siguientes dos expresiones:
  • value.parseJson().result.items[0].poblacion
  • value.parseJson().result.items[0].locales


Paso 6. A utilizar los datos...

Bueno, pues ya tenemos los datos que queríamos... Ahora ya podemos hacer lo que queramos con ellos. ¿A alguno de vosotros se le ocurre qué podemos hacer? Quizás podáis conseguir alguna idea viendo alguno de nuestros posts anteriores: con Google Maps, CartoDB, DataWrapper, etc.