Pregunta

Tengo una base de datos llena de registros llenos de caracteres asiáticos (chino, japonés y coreano) junto con aquellos con registros llenos de caracteres latinos (inglés, francés, lo que sea), y quiero realizar búsquedas de texto completo en ellos.

MySQL dice:

  

Idiomas ideográficos como el chino   y los japoneses no tienen palabra   delimitadores Por lo tanto, el FULLTEXT   el analizador no puede determinar donde las palabras   comenzar y terminar en estos y otros tales   idiomas Las implicaciones de esto.   y algunas soluciones para el problema   se describen en la Sección 11.8,   "Funciones de búsqueda de texto completo".

La Sección 11.8 en realidad no ofrece soluciones alternativas, ni siquiera menciona el problema.

Entonces, ¿cómo clasificaría la búsqueda de un solo carácter chino en una base de datos de caracteres mixtos ? % LIKE% funcionaría, pero no tiene las calificaciones de relevancia ingeniosas. ¿Debo contar las veces que aparece un personaje en el registro y clasificarlo por eso? Agradezco cualquier consejo que tenga. ¡Gracias!

¿Fue útil?

Solución

Depende del tamaño del conjunto de datos. Si estamos hablando de cientos de miles de filas, probablemente eche un vistazo a una de las excelentes soluciones de búsqueda de texto completo independientes disponibles. En realidad, nunca tuve que lidiar con este problema mysqlf, por lo que no estoy seguro de qué soluciones incluyen soporte para idiomas asiáticos.

Sin embargo, sé que lucene tiene un analizador para chino, japonés y coreano, así que supongo que tiene algún tipo de apoyo para lo que estás haciendo. Lo que normalmente hago cuando necesito integrar lucene con php es que implemento lucene como un servidor de socket y me conecto desde php.

Si el conjunto de datos es lo suficientemente pequeño, podría ser una opción para implementar su propio enfoque ad-hoc. Este problema tiene dos partes: la recuperación de los documentos que deben clasificarse y la clasificación real. Hay varias maneras de hacer la recuperación. Uno podría ser usar LIKE, si su conjunto de datos es lo suficientemente pequeño. Otro podría ser rodar su propio esquema de indexación basado en disco, aunque esto sería bastante complejo y requeriría mucho tiempo. También puede usar MySQL como ruta intermedia, como se describe a continuación.

Para implementar un esquema de indexación usando MySQL, tendría que crear algunas tablas con la siguiente estructura:

document
  document_id
  document_text
  document_tokencount

document_token
  document_id
  token_id
  token_docfrequency
  index (token_id, document_id)

token
  token_id
  token_unicode
  token_globalfrequency
  index (token_unicode)

Luego procesaría cada documento e insertaría una fila en la tabla document_token para cada carácter (token) en un documento. El campo token_unicode contendría la secuencia entera de unicode utilizada para referirse a este carácter. El campo token_docfrequency contiene un número entero que corresponde al número de veces que el documento contiene el token, mientras que el campo token_globalfrequency contiene el número total de veces que se usa el término, en todos los documentos.

Esto le permitiría realizar búsquedas rápidas de tokens:

SELECT * FROM document_token WHERE token_id = 1
UNION
SELECT * FROM document_token WHERE token_id = 2
UNION
SELECT * FROM document_token WHERE token_id = 3

(el enfoque de unión es un truco que permite a mysql utilizar índices para todas las selecciones, y lo más probable es que sea más rápido que la consulta correspondiente con una única selección y varias declaraciones)

Esto nos deja con la clasificación de relevancia como el problema restante, que es lo que realmente pidió. :) Esto se puede hacer con resultados bastante buenos utilizando el Modelo de espacio vectorial (VSM) .

Después de hacer una búsqueda, lo primero que deberías hacer es calcular el tf-idf puntuación para este token. Esto se hace usando la fórmula:

tf-idf = tf(t,d) / tf(d) * log(D / d(t))

where:
tf(t,d) = token frequency in current document
tf(d) = total number of tokens in current document
D = total number of documents
d(t) = number of document that contains the token

Calcule primero esta puntuación para cada término en la consulta de búsqueda y almacene el resultado en un hashmap o algo similar. Este es tu primer vector, llamado v_1. Luego proceda al primer documento. Calcule también el puntaje tf-idf para cada término en el documento y guárdelo como v_2. Ahora puede calcular una puntuación para este documento utilizando similitud de coseno :

score = arccos(v_1 * v_2 / (|v_1| * |v_2|))

El resultado es un valor que se puede usar para clasificar el documento. Continúe y haga esto para cada documento. Los clasifican en orden descendente. El primer documento de la lista será el más relevante.

Todo esto puede parecer un poco complicado, pero si tiene algún conocimiento básico del álgebra lineal, probablemente podría producir una solución de trabajo en unas pocas horas. Aún así, si es posible, use una solución existente como lucene.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top