Person holding a compass in s forest

Busquedas Difusas: Función SOUNDEX

La función SOUNDEX es un algoritmo fonético que sirve principalmente para filtran o indexar nombres de acuerdo a la forma en que se pronuncian en inglés. El algoritmo es bastante maduro, por no decir viejo, ya que tiene más de 100 años. SOUNDEX tiene la ventaja de que esta implementados en prácticamente todas las bases de datos relacionales y alguna base de datos no relacionales. El algoritmo genera un código de 4 caracteres que inicia con una letra seguido de 3 dígitos.

Primer ejemplo de uso de SOUNDEX

SELECT Nombre
     , SOUNDEX(Nombre) AS SoundexIdx
FROM (VALUES
('Javier'),
('Jaever'),
('Juvier'),
('Javeir'),
('Javvier'),
('Jeffrey'),
('Xavier')
) AS Nombres(Nombre);

Con el ejemplo puedes notar que el algoritmo trata de agrupar bajo el mismo código diferentes sonidos que ingles suenan parecido a Javier, pero no Xavier. El resultado de la consulta es:

NombreSoundexIdx
JavierJ160
JaeverJ160
JuvierJ160
JaveirJ160
JavvierJ160
JeffreyJ160
XavierX160

Como sigue la fonética inglesa (y tampoco es muy avanzado), no necesariamente se ajusta al español o castellano, pero aun así podemos usarlo como una aproximación.

Consultas para analisis/agrupación

Si quieres darle un uso mas avanzado, puedes por ejemplo extraer del INE (Instituto Nacional de Estadística/España) los nombres mas frecuentes de los recién nacidos. Puedes bajar las versiones hasta el 2018 de INE Nombres Recién Nacidos. Con eso puedes crear la siguiente consulta:

SELECT *
, SOUNDEX(Nombre) AS SoundexIdx
FROM (VALUES
('HUGO', 3800, 'NIÑOS'),
('LUCAS', 3617, 'NIÑOS'),
...
('NURIA', 307, 'NIÑAS'),
('YASMIN', 304, 'NIÑAS'),
('MALAK', 298, 'NIÑAS')
) AS Nombres(Nombre, Nacimientos, Sexo)
ORDER BY Nacimientos;

Esta consulta puede servir para agrupar los datos y usando alguna herramienta analítica pueden visualizarse familias de nombres relacionados. Usando el TreeMap de Tableu, por ejemplo:

Aplicado al padrón electoral del Costa Rica, poco menos de 3.4 Millones de filas, la siguiente consulta genera el siguiente mapa.

     SELECT Nombre, SOUNDEX(Nombre) AS SKey
        , COUNT(*) AS NCount
        , SUM(COUNT(*)) 
            OVER(PARTITION BY SOUNDEX(Nombre) ORDER BY COUNT(*)
            ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
            )  AS SCount
     FROM dbo.Padron
     GROUP BY Nombre
     HAVING COUNT(*)>1000
     ORDER BY 4 DESC, 2,3 DESC,1;

La concentración de nombres compuestos en Costa Rica que usan Maria y Jose es altísima, por eso los valores M600 y J200 tienen 139,028 y 89,274 filas respectivamente, aunque es probable que en años recientes esto haya cambiado.

Soundex como Filtro

Pero lo cierto es que el uso de esta función rara vez es analítico, sino más bien para filtrar o indexar nombres. Por ejemplo, el siguiente código agrega una columna al padrón electoral y un índice:

ALTER TABLE dbo.Padron
	ADD SoundexNombre AS SOUNDEX(Nombre) PERSISTED
-- 42 Seg.

CREATE NONCLUSTERED INDEX IDX_SoundexPadron
	ON dbo.Padron(SoundexNombre)
INCLUDE (Nombre);

La ventaja de este índice es que una consulta como la siguiente:

SELECT TOP 10 Nombre, COUNT() 
FROM dbo.Padron 
WHERE SOUNDEX(Nombre)='J160' 
GROUP BY NOMBRE ORDER BY COUNT() DESC;

Se beneficia del índice, aun cuando no haga uso directo de la columna SoundexNombre, produce un plan bastante mas eficiente. La mayoría del costo esta en la agregación de los datos y en Sort para el Top.

En futuros posteos voy a hablar de alternativas del Soundex, particularmente el algoritmo Metaphone y luego moverme a temas más específicos de búsquedas difusas.

Una respuesta a «Busquedas Difusas: Función SOUNDEX»

  1. […] Por otra parte, Metaphone introduce una mayor complejidad y algo de pérdida en desempeño. La versión original del algoritmo fue escrita en 1990 por Lawrence Philips y fue mejorada por él mismo en el año 2000. Esta versión es la llamada “Double Metaphone” que es la versión más popular del algoritmo. Sobre la función SOUNDEX hice un posteo reciente: Búsquedas Difusas: Función SOUNDEX. […]

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *