8

文中の重要な単語 (つまり、「a」や「the」ではない) の一般的な同義語識別子を作成しようとしています。そのために Python で自然言語ツールキット (nltk) を使用しています。私が抱えている問題は、nltk の同義語ファインダーがその同義語にリンクするために品詞引数を必要とすることです。これを修正しようと試みたのは、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

これは私が現在取り組んでいるコードです。ご覧のとおり、最初に入力を見出し語化して、長期的には一致する数を減らしています (これを何万もの文で実行する予定です)。理論的には、この効果をさらに高め、生成する冗長な単語の数を減らすために、この後に単語をステミングしますが、このメソッドはほぼ常に以下の形式でエラーを返します。

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'

これが実行されるデータをあまり制御できないため、コーパスを単純にクリーンアップすることは実際にはオプションではありません。これを解決する方法についてのアイデアはありますか?

さらに調査を行ったところ、有望な手がかりが得られましたが、それをどのように実装できるかはまだわかりません。単語が見つからない場合、または誤って割り当てられた単語の場合、類似性メトリック (Leacock Chodorow、Wu-Palmer など) を使用して、正しく分類された最も近い他のキーワードにその単語をリンクさせたいと思います。おそらく編集距離の測定と関連していますが、これに関するドキュメントを見つけることができませんでした。

4

2 に答える 2

7

どうやら nltk を使用すると、単語に関連付けられたすべての synset を取得できます。確かに、通常、さまざまな言葉の意味を反映した多くの用語があります。同義語を機能的に見つけるには (または 2 つの単語が同義語である場合)、可能な限り最も近い同義語セットを照合する必要があります。これは、上記の類似性メトリックのいずれかによって可能になります。以下に示すように、2つの単語が同義語であるかどうかを確認する方法で、これを行うための基本的なコードを作成しました。

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

徐々に強力なステミング アルゴリズムを実装しようとするかもしれませんが、最初に行ったいくつかのテストでは、このコードは実際に、見つけたすべての単語で機能しました。このアルゴリズムを改善する方法について誰かがアイデアを持っている場合、またはこの回答を何らかの方法で改善する方法がある場合は、ぜひ聞いてください。

于 2012-06-14T04:03:30.873 に答える
1

ラップWord_Set = wordnet.synset(Call)して例外try:を無視できますか? WordNetError一部の単語が正しく分類されていないというエラーがあるようですが、この例外は認識されていない単語でも発生するため、例外をキャッチすることは私には良い考えのようです.

于 2012-06-13T00:11:33.903 に答える