2
Help us understand the problem. What are the problem?

GiNZA sub_phrases で文節の依存関係を解析

環境

  • Google Colaboratory
  • Python 3.7.12
  • ginza-5.1.0

ginza.sub_phrases

ginza.sub_phrasesを使うと、文節の依存関係を解析できます。

!pip install ginza ja_ginza
from collections import defaultdict

import spacy
import ginza

nlp = spacy.load("ja_ginza")

def analyze(text: str, phrase_func):
    ret = defaultdict(list)
    doc = nlp(text)
    for sentence in doc.sents:
        for token in ginza.bunsetu_head_tokens(sentence):
            for _relation, sub_phrase in ginza.sub_phrases(token, phrase_func):
                ret[sub_phrase].append(phrase_func(token))
    return dict(ret)
analyze("焼肉を食べない日はない", ginza.phrase)
{'日': ['ない'], '焼肉': ['食べ'], '食べ': ['日']}

出力するフレーズ単位の制御

ginza.sub_phrases()の第2引数で、出力の形式を変更できます。公式ドキュメントには下記のように記載されています。

トークンが属する文節を係り先とする文節を依存関係ラベルと共に返します。phrase_funcにはginza.bunsetuまたはginza.phraseを指定します。:

ginza.phraseを使った場合

analyze("焼肉を食べない日はない", ginza.phrase)
{'日': ['ない'], '焼肉': ['食べ'], '食べ': ['日']}

ginza.bunsetuを使った場合

analyze("焼肉を食べない日はない", ginza.bunsetu)
{'日+は': ['ない'], '焼肉+を': ['食べ+ない'], '食べ+ない': ['日+は']}

ところで、このsub_phrasesのソースコードは下記のようになっています。


@sub_phrases.register(Token)
def _sub_phrases(
        token: Token,
        phrase_func: Callable[[Token], U] = _phrase,
        condition_func: Callable[[Token], bool] = lambda token: True,
) -> Iterable[Tuple[str, U]]:
    return [
        (
            t.dep_,
            phrase_func(t),
        ) for t in bunsetu_span(token).root.children if t.i in bunsetu_head_list(token.doc) and condition_func(t)
    ]

実際の第2引数はphrase_func: Callable[[Token], U]であり、Tokenを引数に取るような関数となっています。

例えばginza.lemma_を渡すことで、原形を返り値として得ることができます。

analyze("焼肉を食べない日はない", ginza.lemma_)
{'日': ['ない'], '焼肉': ['食べる'], '食べる': ['日']}

恒等写像lambda x: xを渡すことで、Tokenオブジェクトをそのまま受け取ることもできます。

analyze("焼肉を食べない日はない", lambda x: x)
{焼肉: [食べ], 食べ: [日], 日: [ない]}

適当な独自定義関数を渡して動かすこともできます。

def genkei(x: ginza.Token):
    return str(ginza.bunsetu(ginza.lemma_)(x))

analyze("焼肉を食べない日はない", genkei)
{'日+は': ['ない'], '焼肉+を': ['食べる+ない'], '食べる+ない': ['日+は']}

参考

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
2
Help us understand the problem. What are the problem?