2010-08-10 20 views
6

Sorprendentemente non sono stato in grado di trovare nessun altro in questo modo, ma sicuramente qualcuno lo ha. Sto lavorando a un progetto Python che attualmente richiede il controllo ortografico di circa 16 mila parole. Purtroppo il numero di parole aumenterà. In questo momento sto tirando le parole da Mongo, scorrendo attraverso di loro, e poi ortografandole con pygamhant. Ho rimosso mongo come potenziale collo di bottiglia afferrando prima tutti i miei oggetti da lì. Questo mi lascia con circa 20 minuti per elaborare attraverso 16k parole, che è ovviamente più lungo di quanto voglio spendere. Questo mi lascia con un paio di idee/domande:Controllo ortografico in scala "grande" in Python

  1. Ovviamente potevo sfruttare la filettatura o qualche forma di parallelismo. Anche se lo taglio in 4 pezzi, guardo ancora a circa 5 minuti assumendo un picco di prestazioni.

  2. C'è un modo per dire che cosa biblioteca ortografia Incanta sta usando sotto pyenchant? Il sito Web di Enchant sembra implicare che utilizzerà tutte le librerie/dizionari di ortografia disponibili durante il controllo ortografico. Se è così, allora sono potenzialmente in grado di eseguire ogni parola attraverso tre-quattro dadi di sillabazione. Questo potrebbe essere il mio problema qui, ma sto avendo difficoltà a dimostrare che è il caso. Anche se lo è, la mia opzione è davvero quella di disinstallare altre librerie? Sembra sfortunato.

Quindi, tutte le idee su come posso spremere almeno un po 'più di prestazioni da questo? Sto bene tagliando questo in compiti paralleli, ma mi piacerebbe ancora ottenere il pezzo principale di esso per essere un po 'più veloce prima di me.

Edit: Scusa, il distacco prima di caffè del mattino ... Incanta genera un elenco di suggerimenti per me, se una parola è scritta in modo errato. Sembrerebbe essere dove trascorro la maggior parte del mio tempo in questa porzione di elaborazione.

+2

20 minuti per soli 16 mila parole suona come un tempo terribilmente lungo. Potresti caricare le tue parole in un dizionario Python e fare una ricerca su ciascuna di esse? Questo richiederà certamente meno di 20 minuti. (Probabilmente anche meno di 20 minuti per scrivere.) – ggg

+1

Stai utilizzando tutta la potenza di Enchant, o semplicemente controllando se una parola è scritta correttamente (cioè in un dizionario precedentemente noto)? In quest'ultimo caso, fai ciò che dice 'ggg' e crea il tuo correttore ortografico. – katrielalex

+2

Non pensare nemmeno alla parallelizzazione; Ho appena controllato 100k parole contro un dizionario di 60k in meno tempo di quello che ho impiegato per me per premere invio. Hai bisogno di un algoritmo migliore. – msw

risposta

5

Penso siamo d'accordo che il collo di bottiglia delle prestazioni qui è Incanta; per questa dimensione del set di dati è quasi istantaneo eseguire un valore booleano isSpeltCorrectly. Quindi, perché non:

  1. Costruire un set in memoria di parole correttamente, farro, utilizzando i dizionari che Incanta fornisca, o andare a prendere il proprio (ad esempio OpenOffice's).

    Facoltativamente, uniquify parole del documento, dicono mettendoli in un set. Questo probabilmente non ti salverà molto.

  2. Controllare se ogni parola è nel set o no. Questo è veloce, perché è solo una ricerca set. (Probabilmente O(log N) dove N è il numero di parole? Assumendo set secchi di hash e fa una ricerca binaria ... un guru Python mi può correggere qui.)

  3. Se non lo è, allora chiedere Incanta a raccomandare una parola per questo. Questo è necessariamente lento.

Questo presuppone che la maggior parte delle parole sia scritta correttamente; se non lo sono, dovrai essere più intelligente.

+0

Fino a 6 minuti andando su questa rotta. È ancora lungo, ma è meglio. Si può trovare solo un sacco di cattiva ortografia durante la scansione del Web :) – f4nt

+0

Si potrebbe anche provare a parallelizzare le ricerche Enchant, magari anche con un processo separato in esecuzione come interfaccia per Enchant per gestire la memorizzazione nella cache. – katrielalex

+0

@ f4nt Sto colpendo anche questo problema. Cosa hai usato come fonte per le parole del dizionario? Qualche altra specifica che puoi condividere sulla tua soluzione? – tw1742

1

Forse un modo migliore di fare questo sarebbe per comprimere il documento, in quanto ciò eliminerebbe tutte le istanze ripetizione di parole, che in realtà solo bisogno di controllo ortografico volta. Lo suggerisco solo perché probabilmente sarebbe più veloce della scrittura del tuo cercatore di parole unico.

La versione compressa dovrebbe avere riferimenti alle parole univoche, da qualche parte nel suo file, potrebbe essere necessario cercare in che modo sono strutturate.

È quindi possibile eseguire il controllo ortografico di tutte le parole univoche. Spero che tu non li controlli con singole query SQL o qualcosa del genere, dovresti caricare un dizionario sotto forma di albero nella tua memoria e quindi controllare le parole contro quello.

Una volta fatto, basta decomprimerlo e hey presto è tutto controllato ortograficamente. Questa dovrebbe essere una soluzione abbastanza veloce.

O forse non è necessario passare attraverso l'intero processo di zipping se il controllo ortografico è veramente veloce come suggeriscono i commenti, il che indicherebbe un'implementazione errata.

+0

Ehm, non sono sicuro di aver capito. Intendi comprimere il documento e analizzare il file zip binario? Sei sicuro che funzioni? – katrielalex

+0

L'unico modo ragionevole per fare questo lavoro sarebbe quello di creare un albero di Huffman in cui i lessemi fossero parole intere. Questo calcolo equivale alla risposta di Katrielalex. Qualsiasi altra compressione che operava a livello di sotto-parola sarebbe follemente complicata, ma non aggiungerà utilità. – msw

2

Vorrei utilizzare un correttore ortografico di stile Peter Norvig. Ho scritto un post completo su questo.

http://blog.mattalcock.com/2012/12/5/python-spell-checker/

Ecco un frammento di codice che guarda a possibili modifiche della parola da controllare.

def edits1(word): 
    s = [(word[:i], word[i:]) for i in range(len(word) + 1)] 
    deletes = [a + b[1:] for a, b in s if b] 
    transposes = [a + b[1] + b[0] + b[2:] for a, b in s if len(b)>1] 
    replaces = [a + c + b[1:] for a, b in s for c in alphabet if b] 
    inserts = [a + c + b  for a, b in s for c in alphabet] 
    return set(deletes + transposes + replaces + inserts) 

Si dovrebbe eseguire iterazioni tuo crescente file di dati di parole per controllare in modo estremamente rapido con questo codice per controllare. Vedere il post completo per ulteriori informazioni:

http://blog.mattalcock.com/2012/12/5/python-spell-checker/