自然言語処理ライブラリGiNZAの解析結果を解りやすく表示してみた

# はじめに

この記事はspaCy/GiNZAを触ったことがない人を対象に、どのような解析結果が出力されるか把握し理解することを目的としています。


# spaCy/GiNZAとは
[GiNZA](https://github.com/megagonlabs/ginza)は[Universal Dependencies(UD)](https://universaldependencies.org/)に基づいたオープンソースな日本語処理ライブラリです。
[spaCy](https://github.com/explosion/spaCy)というMITライセンスで商用レベルな自然言語処理フレームワークをベースに構築されています。

Pythonがインストールされていれば、簡単にインストールすることができます。

```
$ pip install -U ginza
```

# まずはそのまま動かしてみる

ginzaコマンドが使えるようになっているためそのまま解析することができます。

```
$ ginza
銀座でランチをご一緒しましょう。今度の日曜日はどうですか。
# text = 銀座でランチをご一緒しましょう。
1       銀座    銀座    PROPN   名詞-固有名詞-地名-一般 _       6       obl     _       SpaceAfter=No|BunsetuBILabel=B|BunsetuPositionType=SEM_HEAD|NP_B|Reading=ギンザ|NE=B-GPE|ENE=B-City
2       で      で      ADP     助詞-格助詞     _       1       case    _       SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=SYN_HEAD|Reading=デ
3       ランチ  ランチ  NOUN    名詞-普通名詞-一般      _       6       obj     _       SpaceAfter=No|BunsetuBILabel=B|BunsetuPositionType=SEM_HEAD|NP_B|Reading=ランチ
4       を      を      ADP     助詞-格助詞     _       3       case    _       SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=SYN_HEAD|Reading=ヲ
5       ご      ご      NOUN    接頭辞  _       6       compound        _       SpaceAfter=No|BunsetuBILabel=B|BunsetuPositionType=CONT|Reading=ゴ
6       一緒    一緒    VERB    名詞-普通名詞-サ変可能  _       0       root    _       SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=ROOT|Reading=イッショ
7       し      する    AUX     動詞-非自立可能 _       6       advcl   _       SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=SYN_HEAD|Inf=サ行変格,連用形-一般|Reading=シ
8       ましょう        ます    AUX     助動詞  _       6       aux     _       SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=SYN_HEAD|Inf=助動詞-マス,意志推量形|Reading=マショウ
9       。      。      PUNCT   補助記号-句点   _       6       punct   _       SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=CONT|Reading=。

# text = 今度の日曜日はどうですか。
1       今度    今度    NOUN    名詞-普通名詞-副詞可能  _       3       nmod    _       SpaceAfter=No|BunsetuBILabel=B|BunsetuPositionType=SEM_HEAD|NP_I|Reading=コンド
2       の      の      ADP     助詞-格助詞     _       1       case    _       SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=SYN_HEAD|Reading=ノ
3       日曜日  日曜日  NOUN    名詞-普通名詞-副詞可能  _       5       nsubj   _       SpaceAfter=No|BunsetuBILabel=B|BunsetuPositionType=SEM_HEAD|NP_I|Reading=ニチヨウビ|NE=B-DATE|ENE=B-Day_Of_Week
4       は      は      ADP     助詞-係助詞     _       3       case    _       SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=SYN_HEAD|Reading=ハ
5       どう    どう    ADV     副詞    _       0       root    _       SpaceAfter=No|BunsetuBILabel=B|BunsetuPositionType=ROOT|Reading=ドウ
6       です    です    AUX     助動詞  _       5       aux     _       SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=SYN_HEAD|Inf=助動詞-デス,終止形-一般|Reading=デス
7       か      か      PART    助詞-終助詞     _       5       mark    _       SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=SYN_HEAD|Reading=カ
8       。      。      PUNCT   補助記号-句点   _       5       punct   _       SpaceAfter=No|BunsetuBILabel=I|BunsetuPositionType=CONT|Reading=。
```

無事解析できましたが、コンソールだと見づらいですね。

# 今度はわかりやすく表示してみる

今回、構文従属関係や表を見やすくするため[spaCyのVisualizer](https://spacy.io/usage/visualizers)と[Streamlit](https://www.streamlit.io/)で可視化してみました。
構文従属関係の描画の際、PROPN・ADP・obl・advclといったUD用語を日本語に置き換えるため`create_manual()`を経由してsvgを生成し、`streamlit.image()`で描画しています。


```python
input_list = st.text_area("入力文字列").splitlines()
nlp = spacy.load('ja_ginza')
for input_str in input_list:
    doc = nlp(input_str)
    for sent in doc.sents:
        svg = spacy.displacy.render(create_manual(sent), style="dep", manual=True)
        streamlit.image(svg)
```

また表を`streamlit.table()`で固有表現(エンティティ)を`streamlit.components.v1.html()`で描画しています。ソースコード全文は[こちら](https://github.com/chai3/ginza-streamlit)

動作結果はこんな感じになりました。

![ginza-streamlit.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984562/babe2035-da28-23ec-99de-3bb132deb44a.gif)

入力と解析結果は以下のような形になっています。

## 入力文字列

銀座でランチをご一緒しましょう。今度の日曜日はどうですか。
吾輩は猫である。 名前はまだ無い。 

## 1-1. 銀座でランチをご一緒しましょう。

###  構文従属関係

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984562/b1ef7e47-a1e3-def8-738a-79a66ca999fc.png)

###  詳細

|i(index)|0|1|2|3|4|5|6|7|8|
|---|---|---|---|---|---|---|---|---|---|
|orth(テキスト)|銀座|で|ランチ|を|ご|一緒|し|ましょう|。|
|lemma(基本形)|銀座|で|ランチ|を|ご|一緒|する|ます|。|
|reading_form(読みカナ)|ギンザ|デ|ランチ|ヲ|ゴ|イッショ|シ|マショウ|。|
|pos(PartOfSpeech)|PROPN|ADP|NOUN|ADP|NOUN|VERB|AUX|AUX|PUNCT|
|pos(品詞)|固有名詞|設置詞|名詞|設置詞|名詞|動詞|助動詞|助動詞|句読点|
|tag(品詞詳細)|名詞-固有名詞-地名-一般|助詞-格助詞|名詞-普通名詞-一般|助詞-格助詞|接頭辞|名詞-普通名詞-サ変可能|動詞-非自立可能|助動詞|補助記号-句点|
|inflection(活用情報)|-|-|-|-|-|-|サ行変格連用形-一般|助動詞-マス意志推量形|-|
|ent_type(エンティティ型)|City|-|-|-|-|-|-|-|-|
|ent_iob(エンティティIOB)|B|O|O|O|O|O|O|O|O|
|lang(言語)|ja|ja|ja|ja|ja|ja|ja|ja|ja|
|dep(dependency)|obl|case|obj|case|compound|ROOT|advcl|aux|punct|
|dep(構文従属関係)|斜格要素|格標識|目的語|格標識|複合語|ROOT|副詞的修飾節|助動詞|句読点|
|head.i(親index)|5|0|5|2|5|5|5|5|5|
|bunsetu_bi_label|B|I|B|I|B|I|I|I|I|
|bunsetu_position_type|SEM_HEAD|SYN_HEAD|SEM_HEAD|SYN_HEAD|CONT|ROOT|SYN_HEAD|SYN_HEAD|CONT|
|is_bunsetu_head|TRUE|FALSE|TRUE|FALSE|FALSE|TRUE|FALSE|FALSE|FALSE|
|ent_label_ontonotes|B-GPE|O|O|O|O|O|O|O|O|
|ent_label_ene|B-City|O|O|O|O|O|O|O|O|

### 文節区切り

銀座で/ランチを/ご一緒しましょう。

### 文節の主辞区間と句の区分

銀座(NP)/ランチ(NP)/ご一緒(VP)

### 固有表現(エンティティ)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984562/cb968be9-59ae-ca55-6737-5fc0bc78263d.png)

## 1-2. 今度の日曜日はどうですか。

###  構文従属関係

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984562/c6bb6607-fd13-aed7-7fab-d0fffb47c3ef.png)

### 詳細

|i(index)|9|10|11|12|13|14|15|16|
|---|---|---|---|---|---|---|---|---|
|orth(テキスト)|今度|の|日曜日|は|どう|です|か|。|
|lemma(基本形)|今度|の|日曜日|は|どう|です|か|。|
|reading_form(読みカナ)|コンド|ノ|ニチヨウビ|ハ|ドウ|デス|カ|。|
|pos(PartOfSpeech)|NOUN|ADP|NOUN|ADP|ADV|AUX|PART|PUNCT|
|pos(品詞)|名詞|設置詞|名詞|設置詞|副詞|助動詞|助詞|句読点|
|tag(品詞詳細)|名詞-普通名詞-副詞可能|助詞-格助詞|名詞-普通名詞-副詞可能|助詞-係助詞|副詞|助動詞|助詞-終助詞|補助記号-句点|
|inflection(活用情報)|-|-|-|-|-|"助動詞-デス|終止形-一般"|-|-|
|ent_type(エンティティ型)|-|-|Day_Of_Week|-|-|-|-|-|
|ent_iob(エンティティIOB)|O|O|B|O|O|O|O|O|
|lang(言語)|ja|ja|ja|ja|ja|ja|ja|ja|
|dep(dependency)|nmod|case|nsubj|case|ROOT|aux|mark|punct|
|dep(構文従属関係)|名詞修飾語|格標識|名詞句主語|格標識|ROOT|助動詞|節標識|句読点|
|head.i(親index)|11|9|13|11|13|13|13|13|
|bunsetu_bi_label|B|I|B|I|B|I|I|I|
|bunsetu_position_type|SEM_HEAD|SYN_HEAD|SEM_HEAD|SYN_HEAD|ROOT|SYN_HEAD|SYN_HEAD|CONT|
|is_bunsetu_head|TRUE|FALSE|TRUE|FALSE|TRUE|FALSE|FALSE|FALSE|
|ent_label_ontonotes|O|O|B-DATE|O|O|O|O|O|
|ent_label_ene|O|O|B-Day_Of_Week|O|O|O|O|O|

### 文節区切り

今度の/日曜日は/どうですか。

### 文節の主辞区間と句の区分

今度(NP)/日曜日(NP)/どう(ADVP)

### 固有表現(エンティティ)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/984562/d2a93a84-3a20-c0af-08ed-fad95deb2971.png)



# 参考サイト

* [GiNZA version 4.0: 多言語依存構造解析技術への文節APIの統合](https://www.megagon.ai/jp/blog/ginza-version-4-0/)
* [GiNZA入門 (1) - 事始め](https://note.com/npaka/n/n5c3e4ca67956)
* [はじめての自然言語処理 第4回 spaCy/GiNZA を用いた自然言語処理](https://www.ogis-ri.co.jp/otc/hiroba/technical/similar-document-search/part4.html)
* [自然言語処理ライブラリのGiNZAを使って係り受け解析を試す](https://www.virment.com/ginza-dependency-parse/)
* [自然言語処理におけるPOSタグと係り受けタグ一覧](https://qiita.com/kei_0324/items/400f639b2f185b39a0cf)
* [Universal Dependencies 日本語コーパス](https://www.jstage.jst.go.jp/article/jnlp/26/1/26_3/_pdf)
* [日本語の構文解析における3つの「係り受け」](http://kanji.zinbun.kyoto-u.ac.jp/~yasuoka/publications/kakariuke.html)
* [spaCy building blocks and visualizers for Streamlit apps](https://github.com/explosion/spacy-streamlit)
* [【簡単爆速第3弾】HTML要らずでWebアプリが作れるStreamlitで、HTMLが使えるようになったぞ](https://qiita.com/Nate0928/items/4d8b9abef3e520293a4a)


# 最後に

構文従属関係などが解りやすくなったでしょうか？

本記事の「構文従属関係や表を見やすくする」には残念ながら対応していませんが、[Herokuで自然言語処理ライブラリspaCy/GiNZAのオンラインデモサイトを立ててみた](https://qiita.com/chai31/items/ac27d35eae188bd1fa45) という記事も書きました。
[spaCy/GiNZAのオンラインデモサイト](https://chai3.github.io/spacy-ginza-online-demonstration/)にもアクセスしてみてください。
GiNZAに少しでも興味持ってもらえたら幸いです。