3

私は、Python、NLTK、および WordNetLemmatizer を使用して、レンマタイザーに取り組んでいます。これは、私が期待していたものを出力するランダムなテキストです

from nltk.stem import WordNetLemmatizer
from nltk.corpus import wordnet
lem = WordNetLemmatizer()
lem.lemmatize('worse', pos=wordnet.ADJ) // here, we are specifying that 'worse' is an adjective

出力:'bad'

lem.lemmatize('worse', pos=wordnet.ADV) // here, we are specifying that 'worse' is an adverb

出力:'worse'

さて、ここではすべて問題ありません。動作は、'better'(不規則な形の場合) または'older'(との同じテストで'elder'は決して出力されないことに注意してください。ただし'old'、wordnet は既存のすべての英単語の完全なリストではないと思います)

私の質問は、次の単語を試したときに発生します'furter'

lem.lemmatize('further', pos=wordnet.ADJ) // as an adjective

出力:'further'

lem.lemmatize('further', pos=wordnet.ADV) // as an adverb

出力:'far'

'worse'これは、単語の場合とは正反対の動作です。

誰でも理由を説明できますか? wordnet の synsets データに起因するバグですか、それとも英語の文法に対する私の誤解に起因するものですか?

質問がすでに回答されている場合は申し訳ありませんが、Google と SO で検索しましたが、「さらに」というキーワードを指定すると、この単語の人気のために、関連するものは何も見つかりません...

よろしくお願いします、Romain G.

4

1 に答える 1

5

WordNetLemmatizer関数を使用._morphyして単語の補題にアクセスします。http://www.nltk.org/_modules/nltk/stem/wordnet.htmlから、可能なレンマを最小の長さで返します。

def lemmatize(self, word, pos=NOUN):
    lemmas = wordnet._morphy(word, pos)
    return min(lemmas, key=len) if lemmas else word

そして、._morphy関数は規則を繰り返し適用して補題を取得します。ルールは、単語の長さを短縮し、接辞を . に置き換え続けMORPHOLOGICAL_SUBSTITUTIONSます。次に、短縮された単語と同じであるが短い単語が他にあるかどうかを調べます。

def _morphy(self, form, pos):
    # from jordanbg:
    # Given an original string x
    # 1. Apply rules once to the input to get y1, y2, y3, etc.
    # 2. Return all that are in the database
    # 3. If there are no matches, keep applying rules until you either
    #    find a match or you can't go any further

    exceptions = self._exception_map[pos]
    substitutions = self.MORPHOLOGICAL_SUBSTITUTIONS[pos]

    def apply_rules(forms):
        return [form[:-len(old)] + new
                for form in forms
                for old, new in substitutions
                if form.endswith(old)]

    def filter_forms(forms):
        result = []
        seen = set()
        for form in forms:
            if form in self._lemma_pos_offset_map:
                if pos in self._lemma_pos_offset_map[form]:
                    if form not in seen:
                        result.append(form)
                        seen.add(form)
        return result

    # 0. Check the exception lists
    if form in exceptions:
        return filter_forms([form] + exceptions[form])

    # 1. Apply rules once to the input to get y1, y2, y3, etc.
    forms = apply_rules([form])

    # 2. Return all that are in the database (and check the original too)
    results = filter_forms([form] + forms)
    if results:
        return results

    # 3. If there are no matches, keep applying rules until we find a match
    while forms:
        forms = apply_rules(forms)
        results = filter_forms(forms)
        if results:
            return results

    # Return an empty list if we can't find anything
    return []

ただし、単語が例外のリストに含まれている場合は、 に保持されている固定値が返されます。 http://www.nltk.org/_modules/nltk/corpus/reader/wordnet.htmlexceptionsを参照_load_exception_mapしてください。

def _load_exception_map(self):
    # load the exception file data into memory
    for pos, suffix in self._FILEMAP.items():
        self._exception_map[pos] = {}
        for line in self.open('%s.exc' % suffix):
            terms = line.split()
            self._exception_map[pos][terms[0]] = terms[1:]
    self._exception_map[ADJ_SAT] = self._exception_map[ADJ]

あなたの例に戻ると、worse->badfurther->farはルールから達成できないため、例外リストから取得する必要があります。これは例外リストであるため、矛盾が生じることは避けられません。

例外リストは および に保持され~/nltk_data/corpora/wordnet/adv.excます~/nltk_data/corpora/wordnet/adv.exc

からadv.exc:

best well
better well
deeper deeply
farther far
further far
harder hard
hardest hard

からadj.exc:

...
worldliest worldly
wormier wormy
wormiest wormy
worse bad
worst bad
worthier worthy
worthiest worthy
wrier wry
...
于 2014-04-11T06:54:22.807 に答える