Tenemos:
- polígonos de circuitos (DINE)
- establecimientos por circuito (DINE)
- puntos de establecimientos (Educación)
Si bien no tenemos puntos de establecimientos DINE sabemos (suponemos) que están dentro del circuito. Con los puntos de establecimientos Educación, que suponemos también están dentro del circuito (ST_Contains()) nos deja deja no más de diez/veinte establecimientos de cada lado para matchear. Con un fuzzy sobre el nombre podemos resolver varios de ellos, alivianando el fuzzy match hasta encontrar algo más o menos óptimo. Los resultados de los matches pueden ir guardándose en distintas tablas, uno por cada grado de fuzzy match para luego revisar manualmente y ver cuál se ajusta mejor. Estimo que al ser una muy acotada cantidad de establecimientos por circuito podremos matchear incluso con un fuzzy muy bajo, solo necesitamos que los nombres sean remotamente parecidos o al menos el más parecido dentro de los que disponemos para ese circuito.
Hay circuitos que parecieran haber cambiado de numeración o lugar. Por ejemplo, hay unos circuitos en Gualeguaychú, Entre Ríos que fueron renumerados. Se puede hacer esta misma búsqueda fuzzy por circuito con buffer o por algún área geográfica más grande (departamento, comuna?), tengo la sospecha de que no hay muchos establecimientos con el mismo nombre dentro del departamento.
Sobre circuito 0015 de la ciudad de Buenos Aires (distrito 1). A la derecha el nombre de establecimiento Min. Educación, a la izquierda DINE.
CREATE EXTENSION fuzzystrmatch;
-- levenshtein(), lower is better
select levenshtein('ESC. TEC. Nº 01 INGENIERO OTTO KRAUSE DE 04', 'ESC.TEC.Nº1 OTTO KRAUSE'); -- 20
select levenshtein('ESC. TEC. Nº 01 INGENIERO OTTO KRAUSE DE 04', 'ESCUELA OTTO KRAUSE'); -- 27
select levenshtein('ESC. TEC. Nº 01 INGENIERO OTTO KRAUSE DE 04', 'ESC. Nº4 CNEL. ISIDORO SUÁREZ'); -- 29
select levenshtein('ESC. Nº3 SÁNCHEZ DE THOMPSON', 'MARIA SANCHEZ DE THOMPSON'); -- 9
select levenshtein('ESC. Nº4 CNEL. ISIDORO SUÁREZ', 'CORONEL ISIDORO SUAREZ'); -- 11
CREATE EXTENSION pg_trgm;
-- similarity(), higher is better
select similarity('ESC. TEC. Nº 01 INGENIERO OTTO KRAUSE DE 04', 'ESC.TEC.Nº1 OTTO KRAUSE'); -- 0.511628
select similarity('ESC. TEC. Nº 01 INGENIERO OTTO KRAUSE DE 04', 'ESCUELA OTTO KRAUSE'); -- 0.326087
select similarity('ESC. TEC. Nº 01 INGENIERO OTTO KRAUSE DE 04', 'ESC. Nº4 CNEL. ISIDORO SUÁREZ'); -- 0.131148
select similarity('ESC. Nº3 SÁNCHEZ DE THOMPSON', 'MARIA SANCHEZ DE THOMPSON'); -- 0.459459
select similarity('ESC. Nº4 CNEL. ISIDORO SUÁREZ', 'CORONEL ISIDORO SUAREZ'); -- 0.428571
CREATE EXTENSION pg_trgm;
CREATE EXTENSION fuzzystrmatch;
SELECT DISTINCT ON (ei.cod_establecimiento)
ei.nombre, ee.nombre,
similarity(ee.nombre, ei.nombre),
levenshtein(ee.nombre, ei.nombre),
difference(ee.nombre, ei.nombre),
geom
FROM circuitos c
JOIN establecimientos_educacion_2017 ee
ON ST_Contains(c.wkb_geometry, ee.geom)
-- ON ST_DWithin(ee.geom, c.wkb_geometry, 100, false)
JOIN establecimientos ei
ON ei.cod_provincia = c.indra_p
AND ei.cod_departamento = c.indra_d
AND lpad(regexp_replace(ei.cod_circuito, '[A-Z]', '','i'), 6, '0') = lpad(regexp_replace(c.circuito, '[A-Z]', '','i'), 6, '0')
WHERE
indra_p = '01' -- CABA
-- indra_p = '02' -- PBA
AND ee.nombre % ei.nombre -- i.e. similarity(ee.nombre, ei.nombre) > 0.3
-- AND similarity(ee.nombre, ei.nombre) < 0.3
ORDER BY
ei.cod_establecimiento, similarity(ee.nombre, ei.nombre) DESC
- CABA: sobre 813 establecimientos electorales se encontraron 625 con similarity > 0.3 dentro del circuito, 75% de los establecimientos.
- Buenos Aires: 3435 sobre 5550: 61.89%. No tengo una hipótesis aún de por qué hay tan pocas coincidencias.