文章内の人名や地名を抜き出して列挙する

##問題意識

1. テキスト文の解析手法としての固有表現抽出は、良い意味で「枯れた」、信頼性の高い手法です。
2. テキスト文から意味を抽出する技術としては、文章の自動要約モデルがあり、深層学習を用いた要約文の自動生成モデルなども、膨大な件数の論文が日々、提案されています。
3. 文章の自動要約技術は素晴らしいものですが、生成された要約文からは、元の文に含まれていた、特定の「人物名」や「地名」が脱落してしまう事が多いと思います。
4. 興味を持ったテキスト文中に含まれる「人物名」の単語だけを、すべて漏らさず一覧出力することで、その文書が「誰」に言及していて、誰に言及していない文であるのかを、ひと目で確認することができます。
5. このように、要約文から漏れてしまう「情報」を、固有表現を抽出することで、すくいとることができるケースがあるのではないでしょうか。


__（ 参考 ）__
なお、文章の自動要約モデルには、*Extractrive summarization*と*Abstractive summarization*モデルの２つの流れがあります。

・ [@koreyouさんQiita記事 「論文紹介: Neural Latent Extractive Document Summarization」](https://qiita.com/koreyou/items/1776e56d8ff2e0e6ba23)
・ [[DL輪読会]Abstractive Summarization of Reddit Posts with Multi-level Memory Networks](https://www.slideshare.net/DeepLearningJP2016/dlabstractive-summarization-of-reddit-posts-with-multilevel-memory-networks-132350977)

####__そこで、今回は、固有表現のラベル名を指定すると、対象テキストから、該当する単語だけを、配列リストで返してくれるメソッドを、定義してみました。__
___


###（ 事前準備 ）

```bash:Terminal
pip install spacy
pip install "https://github.com/megagonlabs/ginza/releases/download/latest/ginza-latest.tar.gz"
```

###今回、定義した自作メソッド
##### *extract_words_by_entity_label*

```Python3:Python3
def extract_words_by_entity_label(text, label):
    if label in ["PERSON", "NORP", "FAC", "ORG", "GPE", "LOC", "PRODUCT", "EVENT", "WORK_OF_ART", "LAW", "LANGUAGE", "DATE", "TIME", "PERCENT", "MONEY", "QUANTITY", "ORDINAL", "CARDINAL"]:
            text = text.replace("\n", "")
            doc = nlp(text)
            words_list = [ent.text for ent in doc.ents if ent.label_ == label]

    else:
            print("その固有表現ラベルは存在しません。")
            words_list = []

    return words_list

```

###__*label* に指定できる固有表現のラベルの種類__

__以下の*spaCy*公式Webサイトに、*spaCy*で定義されている*Entity*のラベル名の一覧が掲載されている__
・ [Spacy *Named Entity Recognition*](https://spacy.io/api/annotation#named-entities)

```text:ラベルの種類
PERSON	People, including fictional.
NORP	Nationalities or religious or political groups.
FAC	Buildings, airports, highways, bridges, etc.
ORG	Companies, agencies, institutions, etc.
GPE	Countries, cities, states.
LOC	Non-GPE locations, mountain ranges, bodies of water.
PRODUCT	Objects, vehicles, foods, etc. (Not services.)
EVENT	Named hurricanes, battles, wars, sports events, etc.
WORK_OF_ART	Titles of books, songs, etc.
LAW	Named documents made into laws.
LANGUAGE	Any named language.
DATE	Absolute or relative dates or periods.
TIME	Times smaller than a day.
PERCENT	Percentage, including ”%“.
MONEY	Monetary values, including unit.
QUANTITY	Measurements, as of weight or distance.
ORDINAL	“first”, “second”, etc.
CARDINAL	Numerals that do not fall under another type.
```

###（ 使用例 ）

####__用意するテキスト__

* [NHK NewsWeb 2020年11月16日 18時36分付配信記事 （社会面）「官房長官 北朝鮮の拉致被害者に向けた政府のラジオ放送の収録」](https://www3.nhk.or.jp/news/html/20201116/k10012715321000.html?utm_int=news-politics_contents_list-items_004)

```text
加藤官房長官は、政府などが北朝鮮にいる拉致被害者に向けて放送しているラジオ番組の収録を行い、一日も早い帰国に向けて全力で取り組むと強調し、「ご家族と抱きしめ合う日が必ず来るとの思いを強く持ち続けて生き抜いてください」と呼びかけました。
拉致問題担当大臣を兼務する加藤官房長官は16日、政府や、北朝鮮に拉致された可能性が排除できない、いわゆる特定失踪者について調査している「特定失踪者問題調査会」が、北朝鮮にいる拉致被害者に向けて放送しているラジオ番組の収録を行いました。
この中で、加藤官房長官は「拉致問題は菅内閣でも最重要課題と位置づけている。菅総理大臣とともにご家族と面会し、『何としても結果を出してほしい』という切実な思いをともにした」と述べました。
そのうえで「相互不信の殻を破り、不幸な過去を清算して、北朝鮮との国交正常化を目指す決意に変わりはない」と述べ、一日も早い拉致被害者の帰国に向けて、政府一丸となり全力で取り組むと強調しました。
Aそして「再び祖国の土を踏み、帰国を待ちわびるご家族と抱きしめ合う日が必ず来るとの思いを強く持ち続け、どうか、お身体を大事にされて、生き抜いてください」と呼びかけました。
```

```Python3:Python3
>>> text = """加藤官房長官は、政府などが北朝鮮にいる拉致被害者に向けて放送しているラジオ番組の収録を行い、一日も早い帰国に向けて全力で取り組むと強調 し、「ご家族と抱きしめ合う日が必ず来るとの思いを強く持ち続けて生き抜いてください」と呼びかけました。
拉致問題担当大臣を兼務する加藤官房長官は16日、政府や、北朝鮮に拉致された可能性が排除できない、いわゆる特定失踪者について調査している「特定失踪者問題調査会」が、北朝鮮にいる拉致被害者に向けて放送しているラジオ番組の収録を行いました。
この中で、加藤官房長官は「拉致問題は菅内閣でも最重要課題と位置づけている。菅総理大臣とともにご家族と面会し、『何としても結果を出してほしい』という切実な思いをともにした」と述べました。
そのうえで「相互不信の殻を破り�そのうえで「相互不信の殻を破り�そのうえで「相互不信の殻を破り�そのうえで「相互不信の殻を破り�そのうえで「相互不信の殻を破り�そのうえで「相互不信の殻を破り�そのうえで「相互不信の殻を破り�そのうえで「相互不信の殻を破り�そのうえで「相... 拉致問題担当大臣を兼務する加藤官房長官は16日、政府や、北朝鮮に拉致された可能性が排除できない、いわゆる特定失踪者について調査している「特定失踪者 問題調査会」が、北朝鮮にいる拉致被害者に向けて放送しているラジオ番組の収録を行いました。
... この中で、加藤官房長官は「拉致問題は菅内閣でも最重要課題と位置づけている。菅総理大臣とともにご家族と面会し、『何としても結果を出してほしい』とい う切実な思いをともにした」と述べました。
... そのうえで「相互不信の殻を破りうえで「相互不信の殻を破りうえで「相互不信の殻を破りうえで「相互不信の殻を破りうえで「相互不信の殻を破りうえで「相 互不信の殻を破りうえで「相互不信の殻を破りうえで「相互不信の殻を破りうえで「相るとの思いを強く持ち続け、どうか、お身体を大事にされて、生き抜いてくだ さい」と呼びかけました。"""
>>>
>>> text = text.replace("\n", "")
>>> text
'加藤官房長官は、政府などが北朝鮮にいる拉致被害者に向けて放送しているラジオ番組の収録を行い、一日も早い帰国に向けて全力で取り組むと強調し、「ご家族と抱きしめ合う日が必ず来るとの思いを強く持ち続けて生き抜いてください」と呼びかけました。拉致問題担当大臣を兼務する加藤官房長官は16日、政府や、北朝鮮に拉致された可能性が排除できない、いわゆる特定失踪者について調査している「特定失踪者問題調査会」が、北朝鮮にいる拉致被害者に向けて放送しているラジオ番組の収録を行いました。この中で、加藤官房長官は「拉致問題は菅内閣でも最重要課題と位置づけている。菅総理大臣とともにご家族と面会し、『何としても結果を出してほしい』という切実な思いをともにした」と述べました。そのうえで「相互不信の殻を破りうえで「相互不信の殻を破りうえで「相互不信の殻を破りうえで「相互不信の殻を破りうえで「相互不信の殻を破りうえで「相互不信の殻を破りうえで「相互不信の殻を破りうえで「相互不信の殻を破りうえで「相るとの思いを強く持ち続け、どうか、お身体を大事にされて、生き抜いてください」と呼びかけました。'
```

####（ 上記のテキストに含まれる固有表現 ）

```Python3:Python3
>>> import spacy
>>> from spacy.matcher import Matcher
>>> nlp = spacy.load('ja_ginza')
>>>
>>> tmp = ["ラベル名  :  {label}   単語 : {word}".format(label=ent.label_, word= ent.text) for ent in doc.ents]
>>> tmp
['ラベル名  :  PERSON   単語 : 加藤官房長官', 'ラベル名  :  LOC   単語 : 北朝鮮', 'ラベル名  :  PERSON   単語 : 加藤官房長官', 'ラベル名  :  DATE   単語 : 16日', 'ラベル名  :  LOC   単語 : 北朝鮮', 'ラベル名  :  LOC   単語 : 北朝鮮', 'ラベル名  :  PERSON   単語 : 加藤官房長官', 'ラベル名  :  PERSON   単語 : 菅', 'ラベル名  :  PERSON   単語 : 菅']
>>>
>>> from pprint import pprint
>>> pprint(tmp)
['ラベル名  :  PERSON   単語 : 加藤官房長官',
 'ラベル名  :  LOC   単語 : 北朝鮮',
 'ラベル名  :  PERSON   単語 : 加藤官房長官',
 'ラベル名  :  DATE   単語 : 16日',
 'ラベル名  :  LOC   単語 : 北朝鮮',
 'ラベル名  :  LOC   単語 : 北朝鮮',
 'ラベル名  :  PERSON   単語 : 加藤官房長官',
 'ラベル名  :  PERSON   単語 : 菅',
 'ラベル名  :  PERSON   単語 : 菅']
>>>
```

####（ 冒頭のメソッドの挙動 ）

```Python3:Python3
>>> words_list = extract_words_by_entity_label(text, "aaa")
その固有表現ラベルは存在しません。
>>>
>>> print(words_list)
[]
>>>
>>> label = "LOC"
>>> words_list = extract_words_by_entity_label(text, label)
>>> print(words_list)
['北朝鮮', '北朝鮮', '北朝鮮']
>>>
>>> for label in ["LOC", "DATE", "PERSON"]:
...     print(label, " : ", extract_words_by_entity_label(text, label))
...
LOC  :  ['北朝鮮', '北朝鮮', '北朝鮮']
DATE  :  ['16日']
PERSON  :  ['加藤官房長官', '加藤官房長官', '加藤官房長官', '菅', '菅']
>>>
```

##（ 参考にしたサイト ）

1. [@moriyamanaotoさんのQiita記事 「spaCyを使ってルールベースの記述をシンプルに！」](https://qiita.com/moriyamanaoto/items/e98b8a6ff1c8fcf8e293)

###__（ 応用 ）__

__特定の事物属性（*Entity*）を帯びた単語を、対象テキストから取り出し後で、さらに次の処理を行うと、よいかもしれない。__

1. 人名や場所のうち、目についた単語が、文章内で、__どのような文脈の中で出現しているのか__を、__係り受け解析__で可視化する。
2. 地名単語のうち、__目についた地名の緯度経度や施設の種別等__を、以下の記事を参考に可視化する。

・[ロケーション名を入力すると、施設の種類や住所etc.を返すGeocodingツール](https://qiita.com/Afo_guard_enthusiast/items/a940876672fe816995a9)