Jak sprawdzić, czy słowo jest słowem angielskim w Pythonie?

134

Chcę sprawdzić w programie w języku Python, czy słowo jest w słowniku języka angielskiego.

Wydaje mi się, że najlepszym rozwiązaniem może być interfejs nltk wordnet, ale nie mam pojęcia, jak go używać do tak prostego zadania.

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

is_english_word(token.lower())

W przyszłości mógłbym chcieć sprawdzić, czy w słowniku znajduje się forma liczby pojedynczej słowa (np. Właściwości -> właściwość -> angielskie słowo). Jak miałbym to osiągnąć?

Barthelemy
źródło

Odpowiedzi:

215

Aby uzyskać (znacznie) większą moc i elastyczność, użyj dedykowanej biblioteki do sprawdzania pisowni, takiej jak PyEnchant. Jest samouczek lub możesz po prostu zanurkować od razu:

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

PyEnchantzawiera kilka słowników (en_GB, en_US, de_DE, fr_FR), ale możesz użyć dowolnego z OpenOffice, jeśli chcesz mieć więcej języków.

Wygląda na to, że istnieje biblioteka pluralizacyjna inflect, ale nie mam pojęcia, czy jest dobra.

Katriel
źródło
2
Dziękuję, nie wiedziałem o PyEnchant i rzeczywiście jest o wiele bardziej przydatny do tego rodzaju kontroli, które chcę przeprowadzać.
Barthelemy,
Nie rozpoznaje <helo>? Niezbyt popularne słowo, ale znam <helo> jako skrót od <helicopter> i nie znam <Helot>. Chciałem tylko zwrócić uwagę, że rozwiązanie nie jest uniwersalne i że inny projekt może wymagać innych słowników lub zupełnie innego podejścia.
dmh
15
Pakiet jest w zasadzie niemożliwy do zainstalowania dla mnie. Super frustrujące.
Monica Heddneck
9
Enchant nie jest obecnie obsługiwany dla Pythona 64- bitowego w systemie
Ricky Boyce,
9
pyenchant nie jest już utrzymywany. Pyhunspell ma nowszą aktywność. Również /usr/share/dict/i /var/lib/dictmoże być przywoływany w konfiguracjach * nix.
pkfm
48

Nie będzie działać dobrze z WordNet, ponieważ WordNet nie zawiera wszystkich angielskich słów. Inną możliwością opartą na NLTK bez zaklęcia jest korpus słów 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
źródło
5
Ta sama wzmianka dotyczy również tutaj: o wiele szybciej po konwersji do zestawu:set(words.words())
Iulius Curt
uważaj, ponieważ musisz wyróżniać słowa, aby uzyskać właściwe wyniki
famargar
2
UWAGA: słowa takie jak makaron lub hamburgera nie znajdują się na tej liście
Paroksh Saxena
45

Korzystanie z NLTK :

from nltk.corpus import wordnet

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

Powinieneś zapoznać się z tym artykułem, jeśli masz problemy z instalacją wordnet lub chcesz wypróbować inne metody.

Susheel Javadi
źródło
2
Jest to szczególnie przydatne dla użytkowników cygwin, ponieważ instalacja zaklęcia jest dość problematyczna.
alehro
27
WordNet nie zawiera wszystkich słów w języku angielskim, zawiera tylko niewielki ich podzbiór.
justhalf
2
Oprócz tego, że w wordnet brakuje wielu popularnych słów, takich jak „chciałbym” i „jak”, jest to zauważalnie wolniejsze niż rozwiązanie Kindall.
Ryan Epp
3
ponadto wordnet.synsets nie sprawdza po prostu, czy jest w nim słowo. Najpierw próbuje lematyzować. Dlatego konwertuje „saless” (nie prawdziwe angielskie słowo) na „sprzedaż”.
Lyndon White,
to jest wadliwa metoda zrobienia tego, biorąc pod uwagę, jak działają synchronizacje. wstaw „tiltes”, aby zobaczyć, o czym mówię
RetroCode
37

Używanie zestawu do przechowywania listy słów, ponieważ wyszukiwanie ich będzie szybsze:

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

Odpowiadając na drugą część pytania, liczba mnoga byłaby już na dobrej liście słów, ale jeśli z jakiegoś powodu chcesz konkretnie wykluczyć je z listy, możesz rzeczywiście napisać funkcję, która je obsłuży. Ale angielskie zasady dotyczące liczby mnogiej są na tyle trudne, że na początek umieściłbym liczbę mnogą na liście słów.

Jeśli chodzi o listę angielskich słów, znalazłem kilka po prostu wpisując w Google „listę angielskich słów”. Oto jeden z nich: http://www.sil.org/linguistics/wordlists/english/wordlist/wordsEn.txt Możesz użyć Google dla brytyjskiego lub amerykańskiego angielskiego, jeśli chcesz konkretnie jeden z tych dialektów.

kindall
źródło
9
Jeśli zrobisz english_wordsa setzamiast a list, is_english_wordbędzie działać znacznie szybciej.
dan04,
Właściwie przerobiłem to jako dyktando, ale masz rację, zestaw jest jeszcze lepszy. Zaktualizowano.
kindall
1
Możesz także porzucić .xreadlines()i po prostu iterować word_file.
FogleBird
3
W ramach ubuntu pakiety wamericani wbritishlisty słów w amerykańskim i brytyjskim języku angielskim jako /usr/share/dict/*-english. Informacje o pakiecie zawierają słowolist.sourceforge.net jako odniesienie.
intuicyjny
1
Znajduję repozytorium GitHub zawierające 479 tys. Angielskich słów.
haolee
6

Aby uzyskać szybsze rozwiązanie oparte na NLTK, możesz zaszyfrować zestaw słów, aby uniknąć wyszukiwania liniowego.

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
źródło
2
Zamiast słownika użyj zestawu
jhuang
4

Uważam, że istnieją 3 rozwiązania pakietowe umożliwiające rozwiązanie problemu. Są to pyenchant, wordnet i corpus (zdefiniowane samodzielnie lub z NTLK). Pyenchant nie mógł łatwo zainstalować w win64 z py3 . Wordnet nie działa zbyt dobrze, ponieważ jego korpus nie jest kompletny. Więc dla mnie wybieram rozwiązanie, na które odpowiada @Sadik i używam 'set (words.words ())', aby przyspieszyć.

Pierwszy:

pip3 install nltk
python3

import nltk
nltk.download('words')

Następnie:

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

print("hello" in setofwords)
>>True
Młody Yang
źródło
3

Dzięki 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
źródło
1
Zwróci to prawdę, jeśli tekst jest dłuższy niż 3 słowa i jest mniej niż 4 błędy (nierozpoznane słowa). Ogólnie w moim przypadku te ustawienia działają całkiem nieźle.
grizmin
1

W przypadku podejścia do sieci semantycznej można uruchomić zapytanie sparql względem WordNet w formacie RDF . Po prostu użyj modułu urllib, aby wysłać żądanie GET i zwrócić wyniki w formacie JSON, przeanalizuj za pomocą modułu Python „json”. Jeśli nie jest to angielskie słowo, nie uzyskasz żadnych wyników.

Jako kolejny pomysł, możesz zapytać API Wikisłownika .

burkestar
źródło
1

Dla wszystkich użytkowników Linux / Unix

Jeśli Twój system operacyjny korzysta z jądra Linuksa, istnieje prosty sposób na pobranie wszystkich słów ze słownika angielsko / amerykańskiego. W katalogu /usr/share/dictmasz wordsplik. Jest też bardziej szczegółowy american-englishi british-englishpliki. Zawierają wszystkie słowa w tym konkretnym języku. Możesz uzyskać dostęp do tego w każdym języku programowania, dlatego pomyślałem, że możesz chcieć o tym wiedzieć.

Teraz, dla konkretnych użytkowników Pythona, poniższy kod Pythona powinien przypisać słowom listy wartość każdego słowa:

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

Mam nadzieję że to pomoże!!!

Linux4Life531
źródło