top of page

Fuzzy Matching en Microsoft Fabric: La solución elegante cuando tus datos "casi" coinciden

Actualizado: 2 abr 2025

El dilema de los datos dispares: Cuando "igual" no significa "idƩntico"


¿Alguna vez te has encontrado frente a dos conjuntos de datos que deberían encajar perfectamente, pero simplemente no lo hacen? Imagina este escenario: tienes datos de clientes de dos sistemas diferentes. En uno aparece "Ana Torres García, El Ejido" y en el otro "Ana Torres, Ejido". Para ti es evidente que se trata de la misma persona, pero para tu sistema son entidades completamente distintas. Este es el tipo de problema que puede convertir un proyecto de integración de datos aparentemente sencillo en un dolor de cabeza monumental... a menos que conozcas el poder del fuzzy matching


¿Qué es exactamente el Fuzzy Matching?


A diferencia de las comparaciones exactas (donde "Almería" y "Almeria" son tratadas como diferentes), el fuzzy matching evalúa la similitud entre textos, asignando un porcentaje que indica cuÔn parecidos son. Es como si le dieras a tu sistema la capacidad de decir: "Estos textos son un 95% iguales, probablemente se refieren a lo mismo." En este artículo, te mostraré cómo implementar esta poderosa técnica en Microsoft Fabric para unificar datos que representan la misma información, pero que han sido registrados con ligeras variaciones.


Nuestro caso prƔctico: Dos listas de contactos que no coinciden


Para este tutorial, trabajaremos con dos archivos CSV que contienen información sobre los mismos contactos, pero estructurados de manera diferente:



Nombre

Primer Apellido

Segundo Apellido

Lugar de Nacimiento

MarĆ­a

GonzƔlez

PƩrez

AlmerĆ­a

Juan

MartĆ­nez

López

Roquetas de Mar

Ana

Torres

GarcĆ­a

El Ejido

Pedro

HernƔdez

SƔnchez

Adra

LucĆ­a

FernƔdez

DĆ­az

VĆ­car

Carlos

López

Ruiz

NĆ­jar

SofĆ­a

PƩrez

Torres

HuƩrcal-Overa

Miguel

Ɓlvarez

Gómez

Vera

Elena

SƔnchez

Moreno

Berja

JosƩ

Ruiz

Castro

Carboneras

Tabla 1. Datos del primer archivo CSV

Mientras que en el segundo origen los datos en el csv son los que siguen:



Nombre contacto

Ciudad

Marƭa GonzƔlez

AlmerĆ­a

Juan MartĆ­nez

Roquetas

Ana Torres

Ejido

Pedro HernƔndez

Adra

Lucƭa FernƔndez

VĆ­car

Carlos López

NĆ­jar

Sofƭa PƩrez

HuƩrcal

Miguel Ɓlvarez

Vera

Elena SƔnchez

Berja

JosƩ Ruiz

Carboneras

Tabla 2. Datos del segundo archivo CSV

Como puedes observar, no solo la estructura es diferente, sino que la información misma presenta variaciones: - "Roquetas de Mar" vs "Roquetas" - "El Ejido" vs "Ejido" - "Almería" vs "Almeria" (sin tilde) AdemÔs, no existe un identificador único (como un ID de cliente) que permita relacionar ambas fuentes de manera confiable. Es aquí donde el fuzzy matching se convierte en nuestro mejor aliado.

Preparando el entorno en Microsoft Fabric


Antes de sumergirnos en el código, necesitamos configurar nuestro entorno de trabajo en Microsoft Fabric:


Paso 1: Crear un Lakehouse


El Lakehouse nos permitirĆ” almacenar y procesar nuestros archivos CSV de manera eficiente: 1. Accede a tu workspace de Fabric 2. Selecciona "Crear" → "Lakehouse" en la sección "Almacenar datos" 3. Asigna un nombre descriptivo y haz clic en "Crear"


Paso 2: Cargar los archivos CSV


Una vez creado el Lakehouse: 1. Haz clic en "Cargar archivos" 2. Selecciona tus archivos CSV 3. Verifica que los archivos aparezcan en la carpeta "Files" de tu Lakehouse


Paso 3: Crear un Notebook


Para ejecutar nuestro anÔlisis: 1. Vuelve a "Crear" y esta vez selecciona "Notebook" en la sección "AnÔlisis y entrenamiento de datos" 2. Asegúrate de que el lenguaje seleccionado sea "PySpark (Python)" 3. Conecta el notebook a tu Lakehouse desde la opción "Agregar orígenes de datos" ”Y ya estamos listos para empezar a escribir código!


El código: Haciendo magia con Fuzzy Matching


En primer lugar, deben de instalarse las librerías que se requieran y no disponga el kernel sobre el que se ejecuta el notebook de forma predeterminada. En este caso, se añadirÔ la librería fuzzywuzzy que proporciona los algoritmos de comparación aproximada:


!pip install fuzzywuzzy

Requirement already satisfied: fuzzywuzzy in /home/trusted-service-user/cluster-env/trident_env/lib/python3.11/site-packages (0.18.0)

A continuación, se cargan las librerías a utilizar: - PySpark.sql.functions para importar funciones que facilitan el procesamiento de los dataframes. - Fuzzywuzzy para realizar la comparación de los datos y obtener porcentajes de equidad.


from pyspark.sql.functions import concat_ws, lower, trim, udf
from fuzzywuzzy import fuzz

Llegó el momento de leer los datos, para lo que se necesita conocer la ruta en la que se encuentran. Dado que se ha conectado el lakehouse al notebook y se utilizarÔ PySpark se puede aprovechar la ruta relativa que ofrece el archivo. Para ello, navegar a la sección Files, clicar sobre el icono de tres puntos (···) asociado al archivo y obtener la ruta relativa para Spark.

ruta_jugadores1 = 'Files/datos_1.csv'
ruta_jugadores2 = 'Files/datos_2.csv'


df1 = spark.read.option("header", "true").csv(ruta_jugadores1)
df2 = spark.read.option("header", "true").csv(ruta_jugadores2)

A continuación, se va a hacer un preprocesamiento de los datos en el que se transformarÔn en un formato uniforme de manera que la comparación sea lo mÔs eficaz posible:


# Combinar nombre y lugar en una sola cadena
combined_expr1 = concat_ws(" ", df1["Nombre"], df1["Primer Apellido"], df1["Segundo Apellido"], df1["Lugar de Nacimiento"])
combined_expr2 = concat_ws(" ", df2["Nombre contacto"], df2["Ciudad"])

# Generar dataframe combinado de cada origen de datos habiendo convertido todo a minĆŗsculas y limpiando espacios en blanco
df1_combined = df1.withColumn("Combined", lower(trim(combined_expr1)))
df2_combined = df2.withColumn("Combined", lower(trim(combined_expr2)))

En este punto es necesario aclarar qué son lo que se conoce por las siglas UDF dentro del ecosistema de PySpark. Las UDF (User-Defined Functions, o Funciones Definidas por el Usuario) son una característica que permite definir funciones personalizadas en Python y aplicarlas a columnas de un DataFrame de Spark. En este caso, se usan para calcular la similitud entre cadenas con la librería fuzzywuzzy, ya que Spark no tiene una función nativa para fuzzy matching. Aquí es donde realmente brilla nuestra solución. Utilizaremos una udf para calcular la similitud entre las cadenas combinadas:

# Definir UDF para similitud combinada
fuzzy_combined_udf = udf(lambda x, y: fuzz.token_sort_ratio(x, y), IntegerType())

# Cruzar y calcular similitud
matched_df = df1_combined.crossJoin(df2_combined).withColumn(
    "Similarity", fuzzy_combined_udf(df1_combined["Combined"], df2_combined["Combined"])
)

# Filtrar por umbral del 70%
resultado = matched_df.filter(matched_df["Similarity"] > 70).orderBy("Similarity", ascending=False)

# Mostrar resultados
display(resultado)

¿Qué estÔ pasando aquí exactamente? 1. Creamos una función (fuzzy_combined_udf) que utiliza el algoritmo token_sort_ratio para comparar dos cadenas de texto 2. Realizamos un "cross join" para comparar cada fila del primer conjunto con cada fila del segundo 3. Calculamos el porcentaje de similitud para cada par 4. Filtramos aquellos pares que superen el 70% de similitud 5. Ordenamos los resultados por similitud descendente El algoritmo token_sort_ratio es especialmente útil porque considera las palabras como "tokens" independientemente de su orden, lo que permite manejar casos como "Juan Martínez López" vs "Martínez Juan". Con la ejecución del código se obtienen los resultados de la tabla siguiente:



Nombre

Primer Apellido

Segundo Apellido

Lugar de nacimiento

Similarity

Combined

Nombre contacto

Ciudad

Combined

LucĆ­a

FernƔndez

DĆ­az

VĆ­car

90

lucƭa fernƔndez dƭaz vƭcar

Lucƭa FernƔndez

VĆ­car

lucƭa fernƔndez vƭcar

Miguel

Ɓlvarez

Gómez

Vera

88

miguel Ôvarez gómez vera

Miguel Ɓlvarez

Vera

miguel Ɣlvarez vera

MarĆ­a

GonzƔlez

PƩrez

AlmerĆ­a

86

marƭa gonzƔlez pƩrez vera

Marƭa GonzƔlez

Almeria

marƭa gonzƔlez almeria

Carlos

López

Ruiz

NĆ­jar

86

carlos lópez ruiz níjar

Carlos López

NĆ­jar

carlos lopez nĆ­jar

Pedro

HernƔndez

SƔnchez

Adra

84

pedro hernƔndez sƔnchez adra

Pedro HernƔndez

Adra

pedro hernƔndez adra

Elena

SƔnchez

Moreno

Berja

84

elena sƔnchez moreno berja

Elena SƔnchez

Berja

elena sƔnchez berja

JosƩ

Ruiz

Castro

Carboneras

84

josƩ ruiz castro carboneras

JosƩ Ruiz

Carboneras

josƩ ruiz carboneras

Juan

MartĆ­nez

López

Roquetas de Mar

78

juan martinez lópez roquetas de mar

Juan MartĆ­nez

Roquetas

juan martĆ­nez roquetas

Ana

Torres

GarcĆ­a

El Ejido

78

ana torres garcĆ­a el ejido

Ana Torres

Ejido

ana torres ejido

SofĆ­a

PƩrez

Torres

HuƩrcal-Overa

71

sofƭa pƩrez torres huƩrcal-overa

Sofƭa PƩrez

HuƩrcal

sofƭa pƩrez huƩrcal

Tabla 3. Resultados de la comparación.

Por último, para completar la gracia de realizar un procesamiento como el mostrado hasta ahora, queda el unificar la información en un solo lugar desde el que se pueda hacer uso. Para ello, creamos una tabla en el Lakehouse relacionado:


# Seleccionar y renombrar columnas para la tabla unificada
tabla_unificada = resultado.select(
    resultado["Nombre"].alias("nombre"),
    resultado["Primer Apellido"].alias("apellido_1"),
    resultado["Segundo Apellido"].alias("apellido_2"),
    resultado["Lugar de Nacimiento"].alias("lugar_nacimiento"),
    resultado["Similarity"].alias("similaridad")
)

# Guardar como tabla en el Lakehouse
tabla_unificada.write.mode("overwrite").format("delta").saveAsTable("Clientes_Unificados")

MƔs allƔ del ejemplo bƔsico: Aplicaciones prƔcticas


Este enfoque puede extenderse a escenarios mucho mƔs complejos:


Deduplicación de bases de datos de clientes


ĀæTienes una base de datos con miles de clientes que sospechas contiene duplicados? El fuzzy matching puede ayudarte a identificar entradas como "Javier RodrĆ­guez" y "J. Rodriguez" como potencialmente el mismo cliente.


Integración de catÔlogos de productos


Cuando necesitas fusionar catƔlogos de productos de diferentes proveedores donde los nombres de productos varƭan ligeramente ("iPhone 13 Pro Max 256GB" vs "Apple iPhone 13 Pro Max (256 GB)").


Normalización de dirección geogrÔfica


Para estandarizar referencias geogrÔficas como "Calle Mayor, 5" y "C/ Mayor nº5" o "Barcelona, España" y "BCN, ES".


Mejoras y consideraciones avanzadas


Para implementaciones mÔs sofisticadas, considera: 1. Ajustar el umbral de similitud: El 70% funciona para nuestro ejemplo, pero según tus datos podrías necesitar un valor diferente. 2. Utilizar diferentes algoritmos: AdemÔs de token_sort_ratio, la biblioteca fuzzywuzzy ofrece otras funciones como partial_ratio o token_set_ratio que pueden funcionar mejor dependiendo del tipo de variaciones en tus datos. 3. Paralelizar el proceso: Para conjuntos de datos grandes, aprovecha la capacidad de Spark para distribuir el cÔlculo en varios nodos. 4. Pre-filtrado: Para optimizar rendimiento, puedes implementar un pre-filtrado que reduzca el número de comparaciones necesarias.


Conclusión: El poder de la flexibilidad


En un mundo ideal, todos los sistemas utilizarĆ­an identificadores universales y formatos de datos estandarizados. Pero en la realidad empresarial, nos enfrentamos constantemente a la heterogeneidad y las inconsistencias.


El fuzzy matching en Microsoft Fabric nos proporciona una herramienta elegante para navegar este caos de datos, permitiéndonos unificar información valiosa que de otro modo permanecería fragmentada. Esta técnica no solo ahorra tiempo en la limpieza manual de datos, sino que también desbloquea nuevas posibilidades para el anÔlisis integrado y la toma de decisiones.


La próxima vez que te enfrentes a conjuntos de datos que deberían coincidir pero no lo hacen, recuerda: a veces la solución no es forzar la exactitud, sino abrazar la similitud.


Déjame algún comentario

¡Gracias por contactar!

© 2023 by Power User 365 blog

bottom of page