け日記

最近はPythonでいろいろやってます

日本語NLPライブラリ GiNZA で遊ぶ

つい最近、リクルートと国立国語研究所の共同研究のアウトプットとしNLPライブラリ GiNZA が公開されました。今回はこのGiNZAをお試ししてみます。

www.recruit.co.jp

GiNZA

GiNZAは日本語の自然言語処理の統合ライブラリです。

megagonlabs.github.io

spaCyのフレームワークに乗っかっており、また、形態素解析でSudachi / SudachiPyを使っていることが特徴です。 (これらのライブラリは過去の投稿でも触れてきました。個人的にもspaCyの日本語への適用を期待していましたので、嬉しい限りです。)

インストール

最新リリースは以下でインストールできます。

$ pip install "https://github.com/megagonlabs/ginza/releases/download/v1.0.2/ja_ginza_nopn-1.0.2.tgz"

コンソールから使う

コンソールから使う場合 python -m spacy.lang.ja_ginza.cli で起動します。"友人・我孫子とスカイツリーで美味いスパゲティを食った。" を入力すると、CoNLL-U形式で解析結果が出力されます。

品詞や標準表現 (3列目, "スパゲティ" -> "スパゲッティ") 、係り受け (7列目のIDが関係を表し、"友人"-> "我孫子"、"美味い" -> "スパゲッティ"となっている) などが正しく解析できてますね。 (CoNLL-Uの解析結果の詳細はこちら) 。Sudachiが使われていることもあって、洗練されていそうです。

$ python -m spacy.lang.ja_ginza.cli
Loading model 'ja_ginza_nopn'
mode is C
disabling sentence separator
友人・我孫子とスカイツリーで美味いスパゲティを食った。
# text = 友人・我孫子とスカイツリーで美味いスパゲティを食った。
1       友人    友人    NOUN    名詞-普通名詞-一般      _       3       compound        _       SpaceAfter=No|NP_B
2       ・      ・      PUNCT   補助記号-一般   _       3       punct   _       SpaceAfter=No
3       我孫子  我孫子  PROPN   名詞-固有名詞-地名-一般 _       5       nmod    _       SpaceAfter=No|NP_B|NE=LOC_B
4       と      と      ADP     助詞-格助詞     _       3       case    _       SpaceAfter=No
5       スカイツリー    スカイツリー    PROPN   名詞-固有名詞-一般      _       10      nmod    _       SpaceAfter=No|NP_B
6       で      で      ADP     助詞-格助詞     _       5       case    _       SpaceAfter=No
7       美味い  旨い    ADJ     形容詞-一般     _       8       amod    _       SpaceAfter=No
8       スパゲティ      スパゲッティ    NOUN    名詞-普通名詞-一般      _       10      obj     _       SpaceAfter=No|NP_B
9       を      を      ADP     助詞-格助詞     _       8       case    _       SpaceAfter=No
10      食っ    食う    VERB    動詞-一般       _       0       root    _       SpaceAfter=No
11      た      た      AUX     助動詞  _       10      aux     _       SpaceAfter=No
12      。      。      PUNCT   補助記号-句点   _       10      punct   _       SpaceAfter=No

Pythonから使う

Pythonから使う場合は spacy.load('ja_ginza_nopn') とすることで、GiNZAのモデルを選択できます。あとはspaCyで英文を扱うのと同じように解析できます。

import spacy

# モデルをロード
nlp = spacy.load('ja_ginza_nopn')

# 解析
doc = nlp("""友人・我孫子とスカイツリーで美味いスパゲティを食った。""")

for sent in doc.sents:
    for token in sent:
        print(token.i, token.orth_, token.lemma_, token.pos_, token.dep_, token.head.i)

# 0 友人 友人 NOUN compound 2
# 1 ・ ・ PUNCT punct 2
# 2 我孫子 我孫子 PROPN nmod 4
# 3 と と ADP case 2
# 4 スカイツリー スカイツリー PROPN nmod 9
# 5 で で ADP case 4
# 6 美味い 旨い ADJ amod 7
# 7 スパゲティ スパゲッティ NOUN obj 9
# 8 を を ADP case 7
# 9 食っ 食う VERB root 9
# 10 た た AUX aux 9
# 11 。 。 PUNCT punct 9

spaCyのインタフェースが実装されていますので、今度は固有表現を抽出してみます (以前の投稿も参考にしてみてください) 。

結果としては、"我孫子"が場所 (LOC) として認識されていたり、"スカイツリー"が抽出できていなかったり、もうちょっと、かもしれません。"東京スカイツリータワー"に変えると、ちゃんと場所として抽出されました。

# 固有表現
for ent in doc.ents:
    print(ent.text, ent.label_, ent.start_char, ent.end_char)

# 我孫子 LOC 3 6

まとめ

今回は最近登場したGiNZAを触ってみました。