8

Sto pensando di scrivere un programma per raccogliere per me le frasi più comuni in un grande volume del testo. Se il problema fosse stato ridotto alla sola ricerca di parole, sarebbe stato semplice archiviare ogni nuova parola in una mappa di hash e quindi aumentare il conteggio su ciascuna occorrenza. Ma con le frasi, memorizzare ogni permutazione di una frase come una chiave sembra impossibile.Algoritmo efficiente per trovare le frasi più comuni in un grande volume di testo

Fondamentalmente il problema è ridotto a capire come estrarre ogni frase possibile da un testo sufficientemente grande. Il conteggio delle frasi e l'ordinamento in base al numero di occorrenze diventano banali.

+0

Forse potresti guardare qualcosa come un trie? Dove un nodo memorizza anche le sue occorrenze e un percorso lungo il trie forma una frase? – AndyG

+0

Considerando l'ultimo paragrafo come la vera domanda, forse il tuo problema è solo definire cosa sia una frase. Se questa è la domanda, considera uno strumento di elaborazione del linguaggio naturale come NLTK. In quel contesto, un oggetto che estrae frasi è chiamato "chunker". – naitoon

+1

Quanto dura una frase? L'algoritmo è praticamente lo stesso sia che si tratti di frasi di una sola parola o di frasi di 10 parole. L'unica differenza è la quantità di dati che devi elaborare. –

risposta

8

Presumo che si stiano cercando modelli comuni di parole consecutive che compaiono nello stesso ordine (ad esempio "la cima del mondo" non sarebbe contata come la stessa frase "cima di un mondo" o "il mondo di cima" ").

Se è così allora mi sento di raccomandare il seguente approccio lineare-tempo:

  1. dividere il testo in parole e rimuovere le cose che non si considera significativo (cioè rimuovere maiuscole, la punteggiatura, interruzioni di parola, ecc)
  2. Converti il ​​tuo testo in un array di interi (un intero per parola unica) (ad esempio ogni istanza di "cat" diventa 1, ogni "cane" diventa 2) Questo può essere fatto in tempo lineare usando un dizionario basato su hash per memorizzare le conversioni da parole a numeri. Se la parola non è nel dizionario, allora assegna un nuovo id.
  3. Costruire un suffisso-array per l'array di numeri interi (questo è un elenco ordinato di tutti i suffissi del vostro array e può essere costruito da tempo lineare - ad esempio utilizzando l'algoritmo e il codice C here)
  4. Costruire la più lunga comuni matrice di prefissi per l'array di suffissi. (Questo può essere fatto anche in tempo lineare, ad esempio usando questo C code) Questo array LCP fornisce il numero di parole comuni all'inizio di ogni suffisso tra coppie consecutive nell'array di suffissi.

Ora sei in grado di raccogliere le tue frasi comuni.

Non è abbastanza chiaro come si desidera determinare la fine di una frase. Una possibilità è semplicemente raccogliere tutte le sequenze di 4 parole che si ripetono.
Questo può essere fatto in tempo lineare lavorando attraverso l'array di suffissi guardando i punti in cui l'array di prefissi più lungo è> = 4. Ogni sequenza di indici x nell'intervallo [start + 1 ... start + len] dove il LCP [x]> = 4 (per tutti tranne l'ultimo valore di x) corrisponde a una frase che viene ripetuta len volte. La frase stessa è data dalle prime 4 parole di, ad esempio, suffisso start + 1.

Si noti che questo approccio potrebbe individuare le frasi che attraversano la fine della frase. Potresti preferire di convertire alcuni segni di punteggiatura come gli arresti completi in numeri interi univoci per impedirlo.

+0

Mi piace l'idea di parole univoche, questa è una buona cosa.Dopodiché, costruire un suffisso ** ordinato ** in tempo lineare sembra uno sforzo impossibile in generale, poiché l'ordinamento è linearitmico (a meno che non manchi qualcosa di ovvio). Inoltre, penso che tu stia rispondendo alla domanda sbagliata. La domanda riguarda la frase più comune, non la frase più lunga comune. – naitoon

+0

1) Sono d'accordo sul fatto che la domanda sia la frase più comune. La mia risposta è di trovare len che dà il numero di volte in cui ogni frase di un certo numero di parole si ripete. 2) Il metodo di tempo lineare per la costruzione dell'array di suffissi fa uso di ordinamento digitale per evitare di richiedere il tempo di nlogn per l'ordinamento. –

+0

L'ordinamento digitale è lineare nel caso peggiore solo se la lunghezza dei tasti è 'O (1)'. Stai ordinando i tasti 'n' (i suffissi), ognuno di essi al massimo' n'. Le chiavi sono tutte diverse, la loro lunghezza è almeno 'log (n)', e quindi la complessità di quell'ordinamento radix non può essere inferiore alla linearitmica. – naitoon

Problemi correlati