Analizando los telegramas de las PASO 2017

Como sabrán, la cámara electoral nos pone a disposición un sitio Web con una API muy copada para poder analizar los resultados de la votación y encontrar anomalías. Bueno, en realidad no. Pero, por lo menos los datos están en HTML sin demasiada complejidad.


Como hacemos para encontrar casos como este, obviamente incorrectos, en la base de telegramas, sin una API o un export de la base de datos?

Bueno, podemos ir al maravilloso mundo de los scrapers, con Python y Scrapy, se come, se educa y... Bueno quizás estoy exagerando pero anda muy bien. No los voy a aburrir con los detalles, el scraper se conecta a http://resultados.gob.ar/99/resu/content/telegramas/Itelegramas.htm, se baja todo a json y lo hace en aprox 1-2h con una conexión de 100mb.

El scraper esta en https://github.com/sicarul/resultados_elecciones2017_scraper y la ultima bajada a json que hice esta en http://elecciones.sicarul.com/resultados_08_14_2017T22_27.json.gz

Y ahora, ¿como analizamos este monstruo de 95166 mesas?

En mi caso, me gusta trabajar el análisis de datos con el excelente software estadístico R, con su interfaz mas popular, el R Studio.

Así que cargamos los datos en dos tablas, mesas y votos, el primero tiene una fila por cada mesa, y el segundo una fila por cada combinacion de mesa, partido y lista, indicando cuantos votaron en esta mesa por esa lista del partido.

provincia seccion circuito mesa estado impugnados nulos_concejales nulos_senadores_nacionales nulos_senadores_provinciales nulos_diputados_nacionales nulos_diputados_provinciales blanco_concejales blanco_senadores_nacionales blanco_senadores_provinciales blanco_diputados_nacionales blanco_diputados_provinciales recurridos_concejales recurridos_senadores_nacionales recurridos_senadores_provinciales recurridos_diputados_nacionales recurridos_diputados_provinciales mesa_id
1 Buenos Aires Adolfo Alsina 0001 00001 Grabada 0 0 0 0 0 25 26 31 36 0 0 0 0 1
2 Buenos Aires Adolfo Alsina 0001 00002 Grabada 0 8 8 8 8 12 3 11 13 0 0 0 0 2
3 Buenos Aires Adolfo Alsina 0001 00003 Grabada 0 0 0 0 0 18 16 25 29 0 0 0 0 3
4 Buenos Aires Adolfo Alsina 0001 00004 Grabada 0 2 4 4 2 19 14 17 25 0 0 0 0 4
5 Buenos Aires Adolfo Alsina 0001 00005 Grabada 0 0 0 0 0 24 20 29 33 1 1 1 1 5

Cuando el tipo de votos no aplica para la mesa, y se cargo asi en el sistema, dejamos las columnas en nulo (NA en R), asi las podemos diferenciar de "0 votos".

Por otro lado, cargamos la tabla votos:

provincia seccion circuito mesa estado partido lista diputados_nacionales diputados_provinciales senadores_nacionales senadores_provinciales concejales mesa_id
1 Santa Fe San Martín 0169 07900 Grabada FEDERAL DIGNIDAD CIUDADANA 0 91134
2 Santa Fe San Martín 0169 07900 Grabada FEDERAL RECREO SOCIAL 0 91134
3 Santa Fe San Martín 0169 07900 Grabada NACIONALISTA CONSTITUCIONAL - UNIR UNION PARA RENOVAR SANTA FE 0 91134
4 Santa Fe San Martín 0169 07900 Grabada UNION CELESTE Y BLANCO UNIDOS POR SANTA FE 1 91134
5 Santa Fe San Martín 0169 07900 Grabada MOVIMIENTO INDEPENDIENTE RENOVADOR DESARROLLO AGRO INDUSTRIAL 0 91134

Aclaracion: La mesa_id es solo un id inventado en la transformacion de datos que es unico por combinacion de provincia+seccion+circuito+mesa, ya que los numeros de mesa se pueden repetir en distintos circuitos.

Para simplificar el análisis, decidi solo analizar los diputados nacionales, que es el denominador mas comun por lo que vi.

Teniendo todos estos datos cargados, lo primero que vi es que hay mesas con muy pocos votos, como estos:

Tambien hay mesas con estado "Incidencia definitiva", estas mesas son las que entiendo no se cargaron porque el data entry de INDRA decidio que no se podia resolver (Los que estuve viendo suelen ser telegramas ilegibles o vacios) ejemplo:

Las incidencias las filtro porque no tiene sentido analizarlas, aunque si puede servir contarlas, 847 de las 95166 mesas que descarge vinieron con incidencias, un 0.89%.

Tambien excluyo las mesas mayor o igual a 09001, ya que estas son mesas de extranjeros y no pueden votar por cargos nacionales, solo locales, por lo cual no tiene sentido al analizar diputados nacionales.

Las mesas con menos de 20 votos las identifico y las separo del análisis, considerando que es injusto comparar los porcentajes con mesas con cerca de 300 votantes. Así encuentro mesas anomalas como estas (En total son 307):

Provincia Seccion Circuito Mesa Total de votos a diputados nacionales
1 Chaco Libertad 0035 01050 2
2 Santa Fe San Lorenzo 0417 07365 7
3 Buenos Aires Hipólito Yrigoyen 0742A 00024 15
4 Mendoza Santa Rosa 0101A 03466 9
5 Córdoba Tulumba 0362 08332 9
6 Buenos Aires Trenque Lauquén 0960 00099 14
7 Entre Ríos San Salvador 0315 03252 6
8 Entre Ríos Colón 0281 02972 18
9 Santa Fe Nueve de Julio 0286 03716 15
10 Córdoba Cruz del Eje 0053 04182 5

Luego, ya sacando todas esas anomalías, no estoy seguro de que es un circuito, al hacer este análisis supuse que los circuitos son zonas donde las mesas están geograficamente cercanas entre si, dentro de la seccion, si esta suposicion es incorrecta habria que reconsiderar como hacer el análisis. Teniendo en cuenta esta suposicion, calcule para cada circuito cual es la banda de "normalidad" de votos a cada partido, sin importar la lista para suavizar un poco los resultados.

Estableci un parametro midiendo por cada circuito, cual es el promedio que recibe de votos ese partido por mesa en porcentaje, y el desvio estandar, para entender que variacion es razonable. Por lo que vi (Un poco a ojo) en general se comporta como una distribucion normal. Como detectar anomalías con esto? Decidi que una mesa con 3 desvios estandares por arriba o por abajo del promedio es anomalo y debe ser revisado. Así encontre mesas como esta, donde los numeros están pero en el lugar incorrecto, y el telegrama se cargo con estado "Grabada"

Me parece increible que no capturen estas anomalías con un simple control que cualquiera con un minimo de suspicacia podria implementar.

Revisando las anomalías agrupadas por partido y provincia, podemos ver que los que mas veces están "por debajo de lo esperado" son mesas de Cambiemos y Unidad ciudadana, seguidos por 1PAIS, PJ, IAF y FIT, los que están agrupados en OTROS suman mas que todos esos juntos, pero son demasiados partidos para visualizar comodamente. Pareceria que los votos que faltan en esos partidos, no se compensan con mesas donde "sobren", pareceria que los votos que faltan están en los "OTROS" partidos.

Sin embargo viendo los casos que vi hasta ahora, no necesariamente sea fraude sino probablemente simple incompetencia al cargar los datos o formular las actas. Haciendo "Zoom" en los OTROS que tienen mas votos que los esperados encontramos estos:

Desconozco si esto es por fraude, error en carga, un análisis malo de mi parte, etc. Pero ceo que valdria la pana revisar las mesas anomalas, las que revise hasta ahora siempre tienen algo raro.

El proyecto en github para ejecutar estos análisis en R y poder continuarlos es https://github.com/sicarul/resultados_elecciones2017_analyze