Como verificar se uma palavra é uma palavra em inglês com Python?

134

Quero verificar em um programa Python se uma palavra está no dicionário de inglês.

Acredito que a interface nltk wordnet possa ser o caminho a seguir, mas não tenho idéia de como usá-la para uma tarefa tão simples.

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

is_english_word(token.lower())

No futuro, talvez eu queira verificar se a forma singular de uma palavra está no dicionário (por exemplo, propriedades -> propriedade -> palavra em inglês). Como eu conseguiria isso?

Barthelemy
fonte

Respostas:

215

Para (muito) mais poder e flexibilidade, use uma biblioteca dedicada de verificação ortográfica, como PyEnchant. Há um tutorial , ou você pode mergulhar direto:

>>> 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"]
>>>

PyEnchantvem com alguns dicionários (en_GB, en_US, de_DE, fr_FR), mas pode usar qualquer um dos OpenOffice se você quiser mais idiomas.

Parece haver uma biblioteca de pluralização chamada inflect, mas não tenho idéia se é bom.

Katriel
fonte
2
Obrigado, eu não conhecia o PyEnchant e é realmente muito mais útil para o tipo de verificação que quero fazer.
Barthelemy
Não reconhece <helo>? Não é uma palavra comum, mas conheço <helo> como uma abreviação de <helicopter> e não conheço <Helot>. Só queria salientar que a solução não é do tamanho único e que um projeto diferente pode exigir dicionários diferentes ou uma abordagem diferente.
DMH
15
O pacote é basicamente impossível de instalar para mim. Super frustrante.
Monica Heddneck
9
Enchant não é suportado neste momento para 64bit Python no Windows :( github.com/rfk/pyenchant/issues/42
Ricky Boyce
9
pyenchant não é mais mantido. pyhunspell tem atividade mais recente. Também /usr/share/dict/e /var/lib/dictpode ser referenciado nas configurações * nix.
Pkfm 01/03/19
48

Não funcionará bem com o WordNet, porque o WordNet não contém todas as palavras em inglês. Outra possibilidade baseada no NLTK sem encantar é o corpus de palavras do 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
fonte
5
A mesma menção se aplica aqui também: muito mais rápido quando convertido em um conjunto:set(words.words())
Iulius Curt 30/09
cuidado que você precisa para palavras individualizam para obter resultados adequados
famargar
2
cuidado: palavras como macarrão ou hambúrguer não são encontradas nesta lista
Paroksh Saxena
45

Usando o NLTK :

from nltk.corpus import wordnet

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

Você deve consultar este artigo se tiver problemas para instalar o wordnet ou quiser tentar outras abordagens.

Susheel Javadi
fonte
2
É especialmente útil para usuários cygwin porque a instalação do enchant é bastante problemática.
alehro
27
O WordNet não contém todas as palavras em inglês, apenas um pequeno subconjunto.
justhalf 28/11
2
No topo da wordnet, falta uma tonelada de palavras comuns como 'would' e 'how' isso é visivelmente mais lento que a solução de kindall.
precisa
3
além disso, o wordnet.synsets não verifica simplesmente se há uma palavra nela. Ele tenta lematizar primeiro. Por isso, converte "saless" (não uma palavra em inglês real) em "vendas".
Lyndon White
esse é um método defeituoso para fazer isso, considerando como as sincronizações funcionam. colocar 'tiltes' para ver o que estou dizendo
RetroCode
37

Usar um conjunto para armazenar a lista de palavras, pois sua busca será mais rápida:

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 à segunda parte da pergunta, os plurais já estariam em uma boa lista de palavras, mas se você quisesse especificamente excluí-los da lista por algum motivo, poderia escrever uma função para lidar com isso. Mas as regras de pluralização em inglês são complicadas o suficiente para incluir apenas os plurais na lista de palavras.

Quanto a onde encontrar listas de palavras em inglês, encontrei várias pesquisando no Google "lista de palavras em inglês". Aqui está um: http://www.sil.org/linguistics/wordlists/english/wordlist/wordsEn.txt Você pode usar o Google para inglês britânico ou americano, se quiser especificamente um desses dialetos.

kindall
fonte
9
Se você criar english_wordsum em setvez de um list, is_english_wordserá executado muito mais rápido.
Dan04 24/09/10
Na verdade, eu apenas refiz isso como um ditado, mas você está certo, um set é ainda melhor. Atualizada.
kindall 24/09/10
1
Você também pode abandonar .xreadlines()e apenas iterar word_file.
FogleBird 24/09
3
No ubuntu, os pacotes wamericane wbritishfornecem listas de palavras em inglês americano e britânico como /usr/share/dict/*-english. As informações do pacote fornecem wordlist.sourceforge.net como referência.
intuited
1
Eu encontro um repositório do GitHub que contém 479k de palavras em inglês.
Haolee 29/05
6

Para uma solução mais rápida baseada em NLTK, você pode fazer o hash do conjunto de palavras para evitar uma pesquisa linear.

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
fonte
2
Em vez de um dicionário, usar um conjunto
jhuang
4

Acho que existem 3 soluções baseadas em pacotes para resolver o problema. São pyenchant, wordnet e corpus (auto-definidos ou do ntlk). O Pyenchant não pôde ser instalado facilmente no win64 com o py3 . O Wordnet não funciona muito bem porque seu corpus não está completo. Então, para mim, escolho a solução respondida por @Sadik e uso 'set (words.words ())' para acelerar.

Primeiro:

pip3 install nltk
python3

import nltk
nltk.download('words')

Então:

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

print("hello" in setofwords)
>>True
Young Yang
fonte
3

Com 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
fonte
1
Isso retornará verdadeiro se o texto tiver mais de 3 palavras e houver menos de 4 erros (palavras não reconhecidas). Em geral, para o meu caso de uso, essas configurações funcionam muito bem.
grizmin
1

Para uma abordagem semântica da Web, você pode executar uma consulta sparql no WordNet no formato RDF . Basicamente, basta usar o módulo urllib para emitir a solicitação GET e retornar resultados no formato JSON, analisar usando o módulo python 'json'. Se não for uma palavra em inglês, você não obterá resultados.

Como outra idéia, você pode consultar a API do Wikcionário .

Burkestar
fonte
1

Para todos os usuários Linux / Unix

Se o seu sistema operacional usa o kernel do Linux, existe uma maneira simples de obter todas as palavras do dicionário inglês / americano. No diretório /usr/share/dictvocê tem um wordsarquivo. Há também um mais específico american-englishe british-englisharquivos. Eles contêm todas as palavras nesse idioma específico. Você pode acessar isso em todas as linguagens de programação, e é por isso que pensei que você gostaria de saber sobre isso.

Agora, para usuários específicos do python, o código python abaixo deve atribuir as palavras da lista ao valor de cada palavra:

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 isto ajude!!!

Linux4Life531
fonte