環境
- 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)
{'日+は': ['ない'], '焼肉+を': ['食べる+ない'], '食べる+ない': ['日+は']}