2012-10-06 9 views
12

Estoy trabajando en una aplicación que intenta hacer coincidir un conjunto de entrada de nombres de entidades potencialmente "desordenados" para "limpiar" nombres de entidades en una lista de referencia. He estado trabajando con la distancia de edición y otros algoritmos de coincidencia difusa comunes, pero me pregunto si hay mejores enfoques que permitan la ponderación de términos, de modo que los términos comunes tengan menos peso en la coincidencia difusa.coincidencia de cadenas difusas con los pesos del término

Considere este ejemplo, utilizando la biblioteca difflib de Python. Estoy trabajando con nombres de organizaciones, que tienen muchos componentes estandarizados en común y, por lo tanto, no se pueden usar para diferenciar entre entidades.

from difflib import SequenceMatcher 
e1a = SequenceMatcher(None, "ZOECON RESEARCH INSTITUTE", 
          "LONDON RESEARCH INSTITUTE") 
print e1a.ratio() 
0.88 

e1b = SequenceMatcher(None, "ZOECON", "LONDON") 
print e1b.ratio() 
0.333333333333 

e2a = SequenceMatcher(None, "WORLDWIDE SEMICONDUCTOR MANUFACTURING CORP", 
          "TAIWAN SEMICONDUCTOR MANUFACTURING CORP") 
print e2a.ratio() 
0.83950617284 

e2b = SequenceMatcher(None, "WORLDWIDE", 
          "TAIWAN") 
print e2b.ratio() 
0.133333333333 

Ambos ejemplos puntuar alto en la cadena completa, porque RESEARCH, INSTITUTE, SEMICONDUCTOR, MANUFACTURING y CORP son de alta frecuencia, los términos genéricos en muchos nombres de organizaciones. Estoy buscando ideas sobre cómo integrar frecuencias de términos en la coincidencia de cadenas difusas (no necesariamente usando difflib), de modo que las puntuaciones no están tan influenciadas por términos comunes, y los resultados pueden parecerse más a "e1b" y "e1b". e2b "ejemplos.

que se dan cuenta de que sólo podía hacer una gran lista de "frecuentes término" y excluir a los de la comparación, pero me gustaría utilizar frecuencias si es posible porque incluso palabras comunes añaden alguna información, y también el punto de corte para cualquier lista, por supuesto, también sería arbitraria.

+2

[Whoosh] (https://bitbucket.org/mchaput/whoosh/wiki/Home) parece interesante, particularmente su ['scoring'] (http://packages.python.org/Whoosh/api/scoring. html) módulo y [whoosh.reading.TermInfo] (http://packages.python.org/Whoosh/api/reading.html?highlight=frequency#whoosh.reading.TermInfo) 'doc_frequency()' y 'peso() ' –

+1

¿Tiene acceso al corpus completo de nombres para el partido difuso? Si es así, puede usar tf-idf para entrenar un modelo de coincidencia difusa. –

+0

Puedes dividir las cuerdas y calcular la diferencia en cada pieza. Esto te ayudaría en algunas situaciones en las que tienes casi los mismos nombres pero con solo una diferencia de palabras. Pero esto probablemente no es lo suficientemente robusto para lo que quieres hacer. – Bakuriu

Respuesta

2

Aquí es una idea extraña para usted:

comprimir su entrada y diff que.

Puede usar, p. Huffman o dictionary coder para comprimir su entrada, que se ocupa automáticamente de los términos comunes. Puede que no le vaya tan bien para los errores tipográficos, en su ejemplo, Londres es probablemente una palabra relativamente común, mientras que misspelt Lundon no lo es en absoluto, y la diferencia entre los términos comprimidos es mucho mayor que entre los términos en bruto.

1

En mi opinión, una solución general nunca coincidirá con su idea de similitud. Tan pronto como tengas algún conocimiento implícito sobre tus datos, tienes que poner eso de alguna manera en el código. Que inmediatamente descalifica una solución fija existente.

Quizás deberías haberle visto en http://nltk.org/ para tener una idea de algunas técnicas de PNL. No nos dice lo suficiente sobre sus datos, pero un etiquetador de POS puede ayudar a identificar términos más y menos relevantes. Las bases de datos disponibles con nombres de ciudades, países, ... pueden ayudar a limpiar los datos antes de procesarlos más.

Hay muchas herramientas disponibles, pero para obtener resultados de alta calidad, necesitará una solución personalizada para sus datos y su caso de uso.

+0

Estoy satisfecho con una solución específica para la aplicación. Mis datos son solo nombres de entidades, desafortunadamente, sin ningún contexto. Me gusta la idea del etiquetado POS, pero me temo que, dado que tengo solo los nombres, algo así como el 95% de lo que devuelve el etiquetador será de NNP. – rjf

+0

Los etiquetadores de POS no están restringidos a las etiquetas "predeterminadas". Puede etiquetar un ejemplo, configurar sus propias etiquetas (CIUDAD, NOMBRE, TIPO, ...) y entrenar a un etiquetador usando esa información. Hay más opciones de las que puedo escribir aquí y para dar más pistas, tendría que "jugar" con sus datos. Lo siento. – Achim

2

¿qué hay de dividir cada cadena en una lista de palabras, y ejecutar su comparación en cada palabra para obtener una lista que contiene los puntajes de las coincidencias de palabras. entonces usted puede promediar los puntajes, encontrar el partido indirecto más bajo/más alto o parciales ...

le da la posibilidad de agregar su propio peso.

, por supuesto, necesitarás manejar compensaciones como ...

"la empresa londres para el cuero"

y

"Compañía de Londres para el cuero"

1

sólo estoy proponiendo otro enfoque diferente. Como mencionó que los nombres de las entidades provienen de una lista de referencia, me pregunto si tiene información de contexto adicional, como nombres de coautores, títulos de productos/papel, dirección w/city, state, country?

Si tiene un contexto útil como el anterior, puede crear un gráfico de entidades a partir de las relaciones entre ellas. Relaciones podrían ser, por ejemplo:

Author-paper relation 
Co-author relation 
author-institute relation 
institute-city relation 
.... 

Entonces es el momento de usar un enfoque resolución entidad basada en la gráfica se describe en detalle en:

El enfoque tiene un muy buen desempeño en el dominio del papel de coautor.

Cuestiones relacionadas