2012-06-12 9 views
8

Próbuję utworzyć ogólny synonim identyfikator dla słów w zdaniu, które są znaczące (tj. Nie "a" lub "the") i używam języka naturalnego toolkit (nltk) w pythonie. Problem, który mam, polega na tym, że wyszukiwarka synonimów w nltk wymaga części argumentacji w celu powiązania jej synonimów. Moją próbą rozwiązania tego problemu było użycie uproszczonej części znacznika mowy obecnej w nltk, a następnie zredukowanie pierwszej litery w celu przekazania tego argumentu do wyszukiwarki synonimów, jednak to nie działa.Synonim ogólny i część przetwarzania mowy przy użyciu nltk

def synonyms(Sentence): 
    Keywords = [] 
    Equivalence = WordNetLemmatizer() 
    Stemmer = stem.SnowballStemmer('english') 
    for word in Sentence: 
     word = Equivalence.lemmatize(word) 
    words = nltk.word_tokenize(Sentence.lower()) 
    text = nltk.Text(words) 
    tags = nltk.pos_tag(text) 
    simplified_tags = [(word, simplify_wsj_tag(tag)) for word, tag in tags] 
    for tag in simplified_tags: 
     print tag 
     grammar_letter = tag[1][0].lower() 
     if grammar_letter != 'd': 
      Call = tag[0].strip() + "." + grammar_letter.strip() + ".01" 
      print Call 
      Word_Set = wordnet.synset(Call) 
      paths = Word_Set.lemma_names 
      for path in paths: 
       Keywords.append(Stemmer.stem(path)) 
    return Keywords 

Jest to kod Obecnie pracuję z, i jak widać jestem pierwszy lemmatizing wejście do zmniejszenia liczby meczów będę mieć w dłuższej perspektywie (Planuję działa to na dziesiątkach tysiące zdań) i teoretycznie chciałbym wyrazić to słowo po tym, aby zwiększyć ten efekt i zmniejszyć liczbę generowanych przeze mnie słów, jednak metoda ta prawie zawsze zwraca błędy w postaci poniższej:

Traceback (most recent call last): 
    File "C:\Python27\test.py", line 45, in <module> 
    synonyms('spray reddish attack force') 
    File "C:\Python27\test.py", line 39, in synonyms 
    Word_Set = wordnet.synset(Call) 
    File "C:\Python27\lib\site-packages\nltk\corpus\reader\wordnet.py", line 1016, in synset 
    raise WordNetError(message % (lemma, pos)) 
WordNetError: no lemma 'reddish' with part of speech 'n' 

Nie mam dużej kontroli nad danymi, które będą nadpisywane, a więc po prostu czyszczenie mojego korpusu nie jest tak naprawdę opcją. Wszelkie pomysły, jak rozwiązać ten problem?

Zrobiłem więcej badań i mam obiecującą przewagę, ale nadal nie jestem pewien, w jaki sposób mogę go wdrożyć. W przypadku nie znalezionego lub nieprawidłowo przypisanego słowa chciałbym użyć metryki podobieństwa (Leacock Chodorow, Wu-Palmer itp.), Aby powiązać słowo z najbliższym poprawnie sklasyfikowanym innym słowem kluczowym. Być może w połączeniu z miarą odległości edycyjnej, ale znowu nie byłem w stanie znaleźć żadnej dokumentacji na ten temat.

Odpowiedz

7

Wygląda na to, że nltk pozwala na pobranie wszystkich synsetów powiązanych ze słowem. Oczywiście większość z nich odzwierciedla różne zmysły. Aby funkcjonalnie znaleźć synonimy (lub jeśli dwa słowa są synonimami), musisz spróbować dopasować najbliższy możliwy zestaw synonimów, co jest możliwe dzięki którymkolwiek z podanych wyżej wskaźników podobieństwa. I zdobione się kilka podstawowych kod, aby to zrobić, jak pokazano poniżej, jak znaleźć, jeśli dwa słowa są synonimami:

from nltk.corpus import wordnet 
from nltk.stem.wordnet import WordNetLemmatizer 
import itertools 


def Synonym_Checker(word1, word2): 
    """Checks if word1 and word2 and synonyms. Returns True if they are, otherwise False""" 
    equivalence = WordNetLemmatizer() 
    word1 = equivalence.lemmatize(word1) 
    word2 = equivalence.lemmatize(word2) 

    word1_synonyms = wordnet.synsets(word1) 
    word2_synonyms = wordnet.synsets(word2) 

    scores = [i.wup_similarity(j) for i, j in list(itertools.product(word1_synonyms, word2_synonyms))] 
    max_index = scores.index(max(scores)) 
    best_match = (max_index/len(word1_synonyms), max_index % len(word1_synonyms)-1) 

    word1_set = word1_synonyms[best_match[0]].lemma_names 
    word2_set = word2_synonyms[best_match[1]].lemma_names 
    match = False 
    match = [match or word in word2_set for word in word1_set][0] 

    return match 

print Synonym_Checker("tomato", "Lycopersicon_esculentum") 

mogę próbować wdrożyć coraz silniejsze wynikające algorytmów, ale przez kilka pierwszych testów zrobiłem, to Kod faktycznie działał dla każdego słowa, które mogłem znaleźć. Jeśli ktoś ma pomysły na ulepszenie tego algorytmu lub ma cokolwiek, co poprawiłoby tę odpowiedź w jakikolwiek sposób, chciałbym to usłyszeć.

+0

Próbuję teraz uruchomić ten kod na chwilę i wydaje się być pełen błędów. Po pierwsze, "worndet" nie jest częścią NLTK, a organizacja pakietów trochę się poruszyła. – aendrew

+0

Przepraszamy, ten kod ma 11 miesięcy. Tak, nltk zmienił się nieco, opublikował zmienioną i działającą wersję dla nowej wersji nltk w miejsce starej. –

+0

Warto również zauważyć, że wyszukiwanie w słowie wordnet jest dość powolne i teoretycznie powinno zostać przekazane do podprocesu. Jeśli chcesz trochę posprzątać i sprawić, że będzie to lepsze narzędzie, daj mi znać, a ja mogę o tym powiedzieć na Github i skopiować na ten temat. –

1

Czy można opakować swój Word_Set = wordnet.synset(Call) z try: i zignorować wyjątek WordNetError? Wygląda na to, że masz błąd, że niektóre słowa nie są poprawnie zaklasyfikowane, ale ten wyjątek pojawiłby się również w przypadku nierozpoznanych słów, więc złapanie wyjątku wydaje mi się dobrym pomysłem.

+1

Aby dodać do tego: WordNet nie ma wszystkich możliwych wyrazów lub wszystkich możliwych zestawów synchronizacyjnych, więc po prostu nie można założyć, że zawsze zwróci wyniki. – Jacob

+0

WordNet może nie zawierać wszystkich wyrazów, ale współczynnik konwersji słów do synonimów jest bardzo niski, nawet po lemytyzacji (mniej niż 50%). Dołączyłem próba z wyjątkiem, ale są głębsze problemy niż ograniczenia WordNet. Żadne słowo, którego szukam, nie jest też niezwykłe. –

+1

Czy jesteś pewien, że słowa są identyfikowane jako właściwa część mowy? [Reddish] (http://www.thefreedictionary.com/reddish) to Adj nie N, czy też źle rozumiem komunikat o wyjątku? – ChipJust

Powiązane problemy