Come verificare se una parola è una parola inglese con Python?


134

Voglio controllare in un programma Python se una parola è nel dizionario inglese.

Credo che l'interfaccia wordl di nltk potrebbe essere la strada da percorrere, ma non ho idea di come usarla per un compito così semplice.

def is_english_word(word):
    pass # how to I implement is_english_word?

is_english_word(token.lower())

In futuro, potrei voler verificare se la forma singolare di una parola è nel dizionario (ad esempio, proprietà -> proprietà -> parola inglese). Come lo raggiungerei?

Risposte:


215

Per (molto) più potenza e flessibilità, utilizzare una libreria di controllo ortografico dedicata come PyEnchant. C'è un tutorial o potresti semplicemente immergerti direttamente:

>>> import enchant
>>> d = enchant.Dict("en_US")
>>> d.check("Hello")
True
>>> d.check("Helo")
False
>>> d.suggest("Helo")
['He lo', 'He-lo', 'Hello', 'Helot', 'Help', 'Halo', 'Hell', 'Held', 'Helm', 'Hero', "He'll"]
>>>

PyEnchantviene fornito con alcuni dizionari (en_GB, en_US, de_DE, fr_FR), ma è possibile utilizzare uno di quelli OpenOffice se si desidera più lingue.

Sembra che ci sia una libreria di pluralizzazione chiamata inflect, ma non ho idea se sia buono.


2
Grazie, non sapevo di PyEnchant ed è davvero molto più utile per il tipo di controlli che voglio fare.
Barthelemy,

Non riconosce <helo>? Non una parola comune, ma conosco <helo> come abbreviazione di <helicopter> e non conosco <Helot>. Volevo solo sottolineare che la soluzione non è adatta a tutti e che un progetto diverso potrebbe richiedere dizionari diversi o un approccio completamente diverso.
dmh

15
Il pacchetto è praticamente impossibile da installare per me. Super frustrante.
Monica Heddneck,

9
Enchant non è attualmente supportato per python 64 bit su Windows :( github.com/rfk/pyenchant/issues/42
Ricky Boyce,

9
pyenchant non è più mantenuto. pyhunspell ha attività più recenti. Inoltre /usr/share/dict/e /var/lib/dictpuò essere referenziato su configurazioni * nix.
pkfm,

48

Non funzionerà bene con WordNet, perché WordNet non contiene tutte le parole inglesi. Un'altra possibilità basata su NLTK senza incantare è la parola corpus di NLTK

>>> from nltk.corpus import words
>>> "would" in words.words()
True
>>> "could" in words.words()
True
>>> "should" in words.words()
True
>>> "I" in words.words()
True
>>> "you" in words.words()
True

5
La stessa menzione vale anche qui: molto più veloce quando convertito in un set:set(words.words())
Iulius Curt

attenzione perché è necessario singolarizzare le parole per ottenere risultati corretti
famargar

2
attenzione: parole come pasta o hamburger non si trovano in questo elenco
Paroksh Saxena,

45

Utilizzando NLTK :

from nltk.corpus import wordnet

if not wordnet.synsets(word_to_test):
  #Not an English Word
else:
  #English Word

Dovresti fare riferimento a questo articolo se hai problemi con l'installazione di wordnet o vuoi provare altri approcci.


2
È particolarmente utile per gli utenti di Cygwin perché l'installazione di Enchant è piuttosto problematica.
alehro,

27
WordNet non contiene tutte le parole in inglese, ne contiene solo un piccolo sottoinsieme.
solo il

2
In cima a wordnet mancano un sacco di parole comuni come "vorrebbe" e "come" questo è notevolmente più lento della soluzione di kindall.
Ryan Epp,

3
inoltre, wordnet.synsets non controlla semplicemente se contiene una parola. Tenta di lemmaizzare prima. Quindi converte "saless" (non una vera parola inglese) in "sales".
Lyndon White,

questo è un metodo imperfetto per farlo, considerando come funzionano i synset. metti "inclinazioni" per vedere cosa sto dicendo
RetroCode

37

Utilizzare un set per memorizzare l'elenco di parole perché cercarli sarà più veloce:

with open("english_words.txt") as word_file:
    english_words = set(word.strip().lower() for word in word_file)

def is_english_word(word):
    return word.lower() in english_words

print is_english_word("ham")  # should be true if you have a good english_words.txt

Per rispondere alla seconda parte della domanda, i plurali sarebbero già in una buona lista di parole, ma se volessi escludere specificamente quelli dalla lista per qualche motivo, potresti davvero scrivere una funzione per gestirla. Ma le regole della pluralizzazione inglese sono abbastanza complicate da includere solo i plurali nell'elenco delle parole.

Per quanto riguarda dove trovare gli elenchi di parole inglesi, ne ho trovati diversi semplicemente da Google "Elenco di parole inglesi". Eccone uno: http://www.sil.org/linguistics/wordlists/english/wordlist/wordsEn.txt Potresti Google per l'inglese britannico o americano se desideri specificamente uno di quei dialetti.


9
Se fai english_wordsun setinvece di un list, allora is_english_wordcorrerà molto più veloce.
dan04,

In realtà l'ho rifatto come un dict ma hai ragione, un set è ancora meglio. Aggiornato.
kindall

1
Puoi anche abbandonare .xreadlines()e solo scorrere word_file.
FogleBird,

3
Sotto Ubuntu i pacchetti wamericane wbritishforniscono elenchi di parole in inglese americano e britannico come /usr/share/dict/*-english. Le informazioni sul pacchetto forniscono wordlist.sourceforge.net come riferimento.
intuito il

1
Trovo un repository GitHub che contiene 479k parole inglesi.
haolee,

6

Per una soluzione basata su NLTK più veloce, è possibile eseguire l'hashing dell'insieme di parole per evitare una ricerca lineare.

from nltk.corpus import words as nltk_words
def is_english_word(word):
    # creation of this dictionary would be done outside of 
    #     the function because you only need to do it once.
    dictionary = dict.fromkeys(nltk_words.words(), None)
    try:
        x = dictionary[word]
        return True
    except KeyError:
        return False

2
Invece di un dizionario, usa un set
jhuang

4

Trovo che ci siano 3 soluzioni basate su pacchetti per risolvere il problema. Sono pirotecnici, wordnet e corpus (auto-definiti o da ntlk). Pyenchant non può essere installato facilmente in win64 con py3 . Wordnet non funziona molto bene perché il suo corpus non è completo. Quindi, per me, scelgo la soluzione a cui @Sadik ha risposto e utilizzo 'set (words.words ())' per accelerare.

Primo:

pip3 install nltk
python3

import nltk
nltk.download('words')

Poi:

from nltk.corpus import words
setofwords = set(words.words())

print("hello" in setofwords)
>>True

3

Con pyEnchant.checker SpellChecker:

from enchant.checker import SpellChecker

def is_in_english(quote):
    d = SpellChecker("en_US")
    d.set_text(quote)
    errors = [err.word for err in d]
    return False if ((len(errors) > 4) or len(quote.split()) < 3) else True

print(is_in_english('“办理美国加州州立大学圣贝纳迪诺分校高仿成绩单Q/V2166384296加州州立大学圣贝纳迪诺分校学历学位认证'))
print(is_in_english('“Two things are infinite: the universe and human stupidity; and I\'m not sure about the universe.”'))

> False
> True

1
Questo tornerà vero se il testo è più lungo di 3 parole e ci sono meno di 4 errori (parole non riconosciute). In generale, nel mio caso d'uso quelle impostazioni funzionano abbastanza bene.
Grizmin,

1

Per un approccio web semantico, è possibile eseguire una query sparql su WordNet in formato RDF . Fondamentalmente basta usare il modulo urllib per inviare la richiesta GET e restituire risultati in formato JSON, analizzarlo usando il modulo 'json' di Python. Se non è una parola inglese non otterrai risultati.

Come altra idea, potresti interrogare l'API di Wikizionario .


1

Per tutti gli utenti Linux / Unix

Se il tuo sistema operativo utilizza il kernel Linux, esiste un modo semplice per ottenere tutte le parole dal dizionario inglese / americano. Nella directory /usr/share/dicthai un wordsfile. C'è anche un più specifico american-englishe british-englishfile. Questi contengono tutte le parole in quella lingua specifica. Puoi accedervi in ​​ogni linguaggio di programmazione ed è per questo che ho pensato che potresti volerlo sapere.

Ora, per utenti specifici di Python, il codice Python di seguito dovrebbe assegnare le parole dell'elenco in modo che abbiano il valore di ogni singola parola:

import re
file = open("/usr/share/dict/words", "r")
words = re.sub("[^\w]", " ",  file.read()).split()

def is_word(word):
    return word.lower() in words

is_word("tarts") ## Returns true
is_word("jwiefjiojrfiorj") ## Returns False

Spero che questo ti aiuti!!!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.