Spacy V3.0 から追加された Token の morph について日本語は他と仕様が違うようだったので調べました。
動作確認は google colab。 コードは Gist にアップロードしています。
spacy 3.7.5 en-core-web-sm 3.7.1 ja-core-news-sm 3.7.0
ドキュメント
Token のattributes には Morphological analysis.
とだけ記載。
MorphAnalysis によると CoNLL-U Format の Morphological Annotation の情報が辞書で入っています。
英語モデルの morph
まずは英語のモデル en_core_web_sm
で確認。
上記ドキュメントとdiscussions に書いてある通り、 morph には Universal features の情報が入っています。
実際に結果をみてみます。
import spacy nlp = spacy.load("en_core_web_sm") text = ("When Sebastian Thrun started working on self-driving cars at " # 省略 "this week.") doc = nlp(text) for token in doc: print(token.text, token.pos_, token.tag_, token.morph.to_dict())
単語によって morph に含まれる情報は異なります。
たとえば動詞の場合は時制 (Tense)・動詞派生語 (VerbForm) を含むことが多い。
When {} Sebastian {'Degree': 'Pos'} Thrun {'Number': 'Sing'} started {'Tense': 'Past', 'VerbForm': 'Fin'} working {'Aspect': 'Prog', 'Tense': 'Pres', 'VerbForm': 'Part'} on {}
名詞の場合、 格 (Case) や 数 (Number, 単数・複数などの情報) を含む。
I PRON PRP {'Case': 'Nom', 'Number': 'Sing', 'Person': '1', 'PronType': 'Prs'} can AUX MD {'VerbForm': 'Fin'} tell VERB VB {'VerbForm': 'Inf'} you PRON PRP {'Person': '2', 'PronType': 'Prs'}
morph の特定の情報だけ取得したい場合は get
を使います。
返却値は リスト なので扱いに注意が必要です。 該当の key がない場合は None ではなく空のリストを返却します。
doc[1].morph.get("Number"), doc[2].morph.get("Number") ([], ['Sing'])
日本語モデル
日本語の morph も v3.2 から対応しているようなので確認。
https://github.com/explosion/spaCy/releases/tag/v3.2.0
Japanese reading and inflection from sudachipy are annotated as Token.morph features.
ja_nlp = spacy.load("ja_core_news_sm") # https://ja.wikipedia.org/wiki/SpaCy ja_text = ( "spaCyは高度な自然言語処理を行うためプログラミング言語" "PythonとCythonで書かれたオープンソースソフトウェア・ライブラリである。" ) ja_doc = ja_nlp(ja_text) for token in ja_doc: print(token.text, token.pos_, token.tag_, token.morph.to_dict())
日本語モデル ja_core_news_*
では、 morph に形態素解析器 sudachipy の結果を格納しています。
Python NOUN 名詞-固有名詞-一般 {'Reading': 'パイソン'} と ADP 助詞-格助詞 {'Reading': 'ト'} Cython NOUN 名詞-普通名詞-一般 {'Reading': 'cython'} で ADP 助詞-格助詞 {'Reading': 'デ'} 書か VERB 動詞-一般 {'Inflection': '五段-カ行;未然形-一般', 'Reading': 'カカ'} れ AUX 助動詞 {'Inflection': '助動詞-レル;連用形-一般', 'Reading': 'レ'} た AUX 助動詞 {'Inflection': '助動詞-タ;連体形-一般', 'Reading': 'タ'} オープン NOUN 名詞-普通名詞-サ変形状詞可能 {'Reading': 'オープン'} ソース NOUN 名詞-普通名詞-一般 {'Reading': 'ソース'} ソフトウェア NOUN 名詞-普通名詞-一般 {'Reading': 'ソフトウェア'} ・ SYM 補助記号-一般 {'Reading': '・'}
基本的にはどの token にも読み (Reading) があります。
また、活用する単語 (動詞、助動詞など) は活用 (Inflection) が含まれています。
これらはそれぞれ sudachipy における Morpheme.reading()
と Morpheme.part_of_speech()
と対応しているようです。
Morpheme.part_of_speech()
の品詞 (pos) は tag_
に入っているので、
それ以外を morph に格納したのだと思われます。
活用
活用は Unidic における 活用型 (cType) と活用形 (cForm) を ;
で連結しています。
どちらかだけ使いたい時は ;
で split すればよいです。
inflection = ja_doc[3].morph.get("Inflection") print(inflection) if inflection: ctype, cform = inflection[0].split(";") print(f"ctype: {ctype}, cform: {cform}") ['助動詞-ダ;連体形-一般'] ctype: 助動詞-ダ, cform: 連体形-一般
活用型・活用形の定義については
に詳細が記載されています。ちなみにどちらもPDFです。
比較的細かく分類されているので、ルールベースで取得したいときは定義を確認することをおすすめします。
例えば活用形の終止形は 終止形-一般
以外に 終止形-撥音便
・終止形-促音便
などのケースを含め6種類あります。
(下記図参照)
# 終止形の判定方法 is_end = cform.startswith("終止形") # or is_end = cform.split("-")[0] == "終止形"