2009-05-19 9 views
12

Tengo un pequeño problema con la aplicación de datos básicos que estoy escribiendo actualmente. Tengo dos modelos diferentes, contextos y tiendas permanentes. Una es para los datos de mi aplicación, la otra es para un sitio web con información relevante para mí.Coincidencia de una cadena aproximada en un almacén de datos centrales

La mayoría de las veces, comparo exactamente un registro de mi aplicación con otro registro de la otra fuente. A veces, sin embargo, tengo que recurrir a la coincidencia de cadenas difusas para vincular los dos registros. Estoy tratando de hacer coincidir los títulos de las canciones. Mi título local podría ser el (compuesta) "The French Idealist is in your pensée" y el título de la canción remoto podría ser "01 - 10 - French idealist in in you're pensee, The (dub remix, feat. DJ Objective-C)"

que busco desbordamiento de pila, Google, la documentación de cacao, y no puedo encontrar ninguna respuesta clara sobre cómo hacer una coincidencia aproximada en estos casos. Mis cadenas pueden comenzar con cualquier cosa, tener un montón de caracteres especiales, generalmente terminan con caracteres aleatorios o ser ignorados.

Regexp no funciona, ni NSPredica, Soundex no funciona bien con nombres extranjeros, y tal vez el Levenshtein no será suficiente (¿o no?).

Estoy buscando un título en un conjunto de una docena de posibles coincidencias, pero tengo que hacer esta operación bastante. 100% de precisión no es el objetivo.

Estaba pensando en eliminar las palabras ignoradas, extrayendo las palabras clave (en este ejemplo, "french, idealist, pensée"), concatenarlas, y luego usar la distancia Levenshtein (las palabras del título de la canción deben estar en el mismo orden)

En mi caso especial, ¿funcionaría? ¿Cuál es el estándar de la industria con respecto a este problema (no puedo ser el único en el mundo que desea unir nombres de canciones ligeramente diferentes) ¿Pueden ayudarme Core Data, Cocoa u Objective-C?

Muchas gracias.

Respuesta

3

Quiere que su búsqueda sea diacrítica para que coincida con el 'é' en el pensée y 'e' en pensee. Usted obtiene esto agregando el [d] después del atributo. De la misma manera:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(songTitle like[cd] %@)", yourSongSubstring];
La 'c' en [cd] es para la insensibilidad de mayúsculas y minúsculas.

Dado que su cadena podría aparecer en cualquier orden en la cadena que está buscando, podría tokenizar la cadena de búsqueda ([... componentsByString: @ ""]) y luego crear un predicado como

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(songTitle like[cd] %@) and (songTitle like[cd] %@)", songToken1, songToken2];
Esa sintaxis para combinar predicados anteriores estar fuera, yendo de la memoria.

+0

Bueno, primero probé una variación de esto y cuando analizo datos del mundo real, no funciona del todo. La mayoría de las veces, el problema no es los diacríticos o el caso sino las diferencias sutilmente deletreadas (como en "Backstreet girl" vs. "Back Street Girl"). Esta solución también depende en gran medida del paso anterior, la tokenización, que es realmente difícil para el dominio "palabras que podrían aparecer en el título de una canción" – damdamdam

2

Creo que la herramienta que desea utilizar aquí es SearchKit. Lo digo como si acabara de hacer su trabajo fácil ... no lo he hecho, pero debería tener las herramientas que necesita para tener éxito aquí. LNC todavía está ofreciendo su SearchKit Podcast gratis (muy agradable).

Cada pista sería un documento en este caso, y tendría que encontrar una buena forma de indexarlas con un identificador que pueda usarse para encontrarlas. A continuación, puede cargarlos con metadatos y buscarlos. Quizás poner el título "en" el documento sería útil aquí para facilitar el uso de la búsqueda de similitudes (kSKSearchOptionFindSimilar). Eso puede o no funcionar realmente bien.

La pregunta que ha hecho es buena, pero ciertamente no existe un estándar industrial porque cualquiera que resuelva este problema (es decir, cualquier motor de búsqueda importante) mantiene sus algoritmos en secreto. Es este un problema difícil; nadie está listo para dar su respuesta.

+0

SearchKit. Me olvidé completamente de esta API. Miré muy duro al documento, vi usos inmediatos en mi aplicación, pero creo que es demasiado complicado solo para aproximar una coincidencia entre una cadena y otra cuerda. – damdamdam

1

Considera q-grams, que son subcadenas de longitud q (Gravano et al., 2001).

Puede, para dos cadenas s1 y s2, determinar para cada q-gramo de s1 el q-gramo correspondiente de s2 con la menor distancia de edición. Luego agrega todas esas distancias y terminas con una métrica que es muy robusta a la permutación de palabras y caracteres adicionales.

En general, q debe adaptarse a su dominio problemático (experimente con q = 3, 4, 5 ...).

Cuestiones relacionadas