Domanda

Ho un database pieno di record con caratteri asiatici (cinese, giapponese e coreano) accanto a quelli con record con caratteri latini (inglese, francese, tu lo chiami) e voglio eseguire ricerche full-text su di essi.

MySQL dice:

  

Lingue ideografiche come il cinese   e il giapponese non ha parola   Delimitatori. Pertanto, il FULLTEXT   il parser non può determinare dove le parole   iniziare e finire in questi e altri simili   le lingue. Le implicazioni di questo   e alcune soluzioni alternative per il problema   sono descritti nella sezione 11.8,   "Funzioni di ricerca full-text".

La Sezione 11.8 in realtà non offre soluzioni alternative né menziona il problema.

Quindi, come ordineresti una ricerca di un singolo carattere cinese in un database di caratteri misti ? % LIKE% funzionerebbe, ma non ha i voti di pertinenza eleganti. Devo solo contare le volte in cui un personaggio appare nel record e classificarlo in base a quello? Apprezzo qualsiasi consiglio tu abbia. Grazie!

È stato utile?

Soluzione

Dipende dalla dimensione del set di dati. Se stiamo parlando di centinaia di migliaia di righe, probabilmente darei un'occhiata a una delle eccellenti soluzioni di ricerca full text indipendenti disponibili. In realtà non ho mai avuto a che fare con questo problema mysqlf, quindi non sono sicuro di quali soluzioni includano il supporto per le lingue asiatiche.

So comunque che lucene sfoggia un analizzatore per cinese, giapponese e coreano, quindi la mia ipotesi è che che ha una sorta di supporto per quello che stai facendo. Quello che faccio di solito quando devo integrare lucene con php è che implemento lucene come socket server e mi connetto da php.

Se il set di dati è abbastanza piccolo, potrebbe essere un'opzione per implementare il proprio approccio ad hoc. Esistono due parti di questo problema: recupero dei documenti da classificare e classificazione effettiva. Esistono diversi modi per eseguire il recupero. Uno potrebbe essere LIKE, se il tuo set di dati è sufficientemente piccolo. Un altro potrebbe essere quello di implementare il proprio schema di indicizzazione basato su disco, sebbene ciò sia piuttosto complesso e dispendioso in termini di tempo. È inoltre possibile utilizzare MySQL come percorso intermedio, come descritto di seguito.

Per implementare uno schema di indicizzazione usando MySQL, dovresti creare alcune tabelle con la seguente struttura:

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)

Quindi elaborerei ogni documento e inserivo una riga nella tabella document_token per ciascun personaggio (token) in un documento. Il campo token_unicode conterrebbe la sequenza unicode intera utilizzata per fare riferimento a questo carattere. Il campo token_docfrequency contiene un numero intero corrispondente al numero di volte in cui il documento contiene il token, mentre il campo token_globalfrequency contiene il numero totale di volte in cui il termine viene utilizzato, in tutti i documenti.

Ciò ti consentirebbe di effettuare ricerche rapide per i token:

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

(l'approccio sindacale è un hack che consente a mysql di utilizzare gli indici per tutte le selezioni e molto probabilmente sarà più veloce della query corrispondente utilizzando una singola selezione e più o più istruzioni)

Questo ci lascia con la classifica di pertinenza come il problema rimanente, che è quello che hai veramente chiesto. :) Questo può essere fatto con risultati piuttosto positivi utilizzando il Vector Space Model (VSM) .

Dopo aver fatto una ricerca, la prima cosa che dovresti fare è calcolare tf-idf punteggio per questo token. Questo viene fatto usando la formula:

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

Calcola prima questo punteggio per ogni termine nella query di ricerca e archivia il risultato in una hashmap o qualcosa di simile. Questo è il tuo primo vettore, chiamato v_1. Quindi passare al primo documento. Calcola anche il punteggio tf-idf per ogni termine nel documento e memorizzalo come v_2. Ora puoi calcolare un punteggio per questo documento usando similiarità del coseno :

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

Il risultato è un valore che può essere utilizzato per classificare il documento. Continua e fallo per ogni documento. Li ordina in ordine decrescente. Il primo documento nell'elenco sarà il più pertinente.

Tutto ciò potrebbe sembrare un po 'complicato, ma se hai una conoscenza di base dell'algebra lineare, potresti probabilmente produrre una soluzione funzionante in poche ore. Tuttavia, se possibile, utilizzare una soluzione esistente come lucene.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top