¿Cómo verificar si una palabra es una palabra en inglés con Python?

134

Quiero comprobar en un programa de Python si una palabra está en el diccionario de inglés.

Creo que la interfaz nltk wordnet podría ser el camino a seguir, pero no tengo idea de cómo usarla para una tarea tan simple.

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

is_english_word(token.lower())

En el futuro, es posible que desee comprobar si la forma singular de una palabra está en el diccionario (por ejemplo, propiedades -> propiedad -> palabra en inglés). ¿Cómo lo lograría?

Barthelemy
fuente

Respuestas:

215

Para (mucho) más poder y flexibilidad, use una biblioteca dedicada de corrección ortográfica como PyEnchant. Hay un tutorial , o puedes sumergirte directamente:

>>> 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 con algunos diccionarios (en_GB, en_US, de_DE, fr_FR), pero puede usar cualquiera de los OpenOffice si desea más idiomas.

Parece que hay una biblioteca de pluralización llamada inflect, pero no tengo idea de si es buena.

Katriel
fuente
2
Gracias, no sabía sobre PyEnchant y, de hecho, es mucho más útil para el tipo de controles que quiero hacer.
Barthelemy
¿No reconoce <helo>? No es una palabra común, pero sé <helo> como abreviatura de <helicopter>, y no sé <Helot>. Solo quería señalar que la solución no es de talla única y que un proyecto diferente podría requerir diferentes diccionarios o un enfoque completamente diferente.
dmh
15
El paquete es básicamente imposible de instalar para mí. Súper frustrante
Monica Heddneck
9
Enchant no es compatible en este momento para python 64bit en windows :( github.com/rfk/pyenchant/issues/42
Ricky Boyce
9
pyenchant ya no se mantiene. pyhunspell tiene actividad más reciente. También /usr/share/dict/y /var/lib/dictpuede ser referenciado en configuraciones * nix.
pkfm
48

No funcionará bien con WordNet, porque WordNet no contiene todas las palabras en inglés. Otra posibilidad basada en NLTK sin encantar es el corpus de palabras de 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
Sadik
fuente
55
La misma mención se aplica aquí también: mucho más rápido cuando se convierte en un conjunto:set(words.words())
Iulius Curt
ten cuidado ya que necesitas singularizar las palabras para obtener los resultados correctos
famargar
2
precaución: palabras como pasta o hamburguesa no se encuentran en esta lista
Paroksh Saxena
45

Usando NLTK :

from nltk.corpus import wordnet

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

Debe consultar este artículo si tiene problemas para instalar Wordnet o si desea probar otros enfoques.

Susheel Javadi
fuente
2
Es especialmente útil para los usuarios de cygwin porque la instalación de enchant es bastante problemática.
alehro
27
WordNet no contiene todas las palabras en inglés, solo contiene un pequeño subconjunto.
justhalf
2
Además de wordnet faltan un montón de palabras comunes como 'would' y 'how', esto es notablemente más lento que la solución de kindall.
Ryan Epp
3
Además, wordnet.synsets no solo comprueba si hay una palabra en ella. Intenta lemaizar primero. Por lo tanto, convierte "saless" (no es una palabra real en inglés) en "sales".
Lyndon White
ese es un método defectuoso para hacer esto, considerando cómo funcionan los synsets. poner 'tiltes' para ver lo que estoy diciendo
RetroCode
37

Usar un conjunto para almacenar la lista de palabras porque buscarlas será más rápido:

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

Para responder a la segunda parte de la pregunta, los plurales ya estarían en una buena lista de palabras, pero si quisiera excluirlos específicamente de la lista por alguna razón, podría escribir una función para manejarla. Pero las reglas de pluralización en inglés son lo suficientemente complicadas como para incluir solo los plurales en la lista de palabras.

En cuanto a dónde encontrar listas de palabras en inglés, encontré varias buscando en Google "Lista de palabras en inglés". Aquí hay uno: http://www.sil.org/linguistics/wordlists/english/wordlist/wordsEn.txt Puede buscar en Google inglés británico o americano si desea específicamente uno de esos dialectos.

un poco
fuente
9
Si haces english_wordsun en setlugar de un list, entonces is_english_wordcorrerá mucho más rápido.
dan04
De hecho, lo rehice como un dict, pero tienes razón, un conjunto es aún mejor. Actualizado.
poco
1
También puede deshacerse .xreadlines()y simplemente iterar word_file.
FogleBird
3
Bajo ubuntu los paquetes wamericany wbritishproporcionan listas de palabras en inglés americano y británico como /usr/share/dict/*-english. La información del paquete proporciona wordlist.sourceforge.net como referencia.
intuido
1
Encuentro un repositorio de GitHub que contiene 479 mil palabras en inglés.
Haolee
6

Para una solución más rápida basada en NLTK, puede hacer un hash del conjunto de palabras para evitar una búsqueda lineal.

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
Eb Abadi
fuente
2
En lugar de un diccionario, use un conjunto
jhuang
4

Encuentro que hay 3 soluciones basadas en paquetes para resolver el problema. Son pyenchant, wordnet y corpus (autodefinidos o de ntlk). Pyenchant no se pudo instalar fácilmente en win64 con py3 . Wordnet no funciona muy bien porque su corpus no está completo. Entonces, para mí, elijo la solución respondida por @Sadik , y uso 'set (words.words ())' para acelerar.

Primero:

pip3 install nltk
python3

import nltk
nltk.download('words')

Luego:

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

print("hello" in setofwords)
>>True
Joven yang
fuente
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
grizmin
fuente
1
Esto devolverá verdadero si el texto tiene más de 3 palabras y hay menos de 4 errores (palabras no reconocidas). En general, para mi caso de uso, esas configuraciones funcionan bastante bien.
grizmin
1

Para un enfoque web semántico, puede ejecutar una consulta sparql contra WordNet en formato RDF . Básicamente, solo use el módulo urllib para emitir la solicitud GET y devolver los resultados en formato JSON, analizar usando el módulo 'json' de python. Si no es una palabra en inglés, no obtendrá resultados.

Como otra idea, puede consultar la API de Wiktionary .

Burkestar
fuente
1

Para todos los usuarios de Linux / Unix

Si su sistema operativo utiliza el kernel de Linux, hay una manera simple de obtener todas las palabras del diccionario inglés / americano. En el directorio /usr/share/dicttienes un wordsarchivo. También hay un más específico american-englishy british-englisharchivos. Contienen todas las palabras en ese idioma específico. Puedes acceder a esto en todos los lenguajes de programación, por eso pensé que querrías saber sobre esto.

Ahora, para usuarios específicos de Python, el siguiente código de Python debe asignar las palabras de la lista para que tengan el valor de cada palabra:

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

¡¡¡Espero que esto ayude!!!

Linux4Life531
fuente