固有表現抽出のアノテーションデータについて

自然言語処理技術のなかでも固有表現抽出(Named Entity Recognition; NER)は情報抽出の処理をやろうとするときにとても役立つ。

応用は幅広く、会社名や個人名などの情報抽出処理、個人情報除去などのような抽出した情報に対する処理、代名詞の解析(照応解析・共参照解析)のような文脈解析処理などに用いられる。

最も簡単なNERの方法としては、辞書や形態素解析結果や正規表現などに基づくルールを用いて、単語列にラベリングする方法があるが、会社名など判断が難しいケースについては機械学習によってNERを行うことが有効なことが多い。機械学習ベースの既存の固有表現抽出器を使ってみたい場合には、GiNZAやKNPのようなNERモデルが同梱されているツールを使用してみるのがよい。

しかし公開モデルの性能では満足いかない場合に自分でモデルを構築しようとしても、公開データセットが見つけにくかったりデータ処理が面倒だったりして想像以上に道のりが険しい。

本記事では、機械学習を用いたNERを行う上で必要な、公開データセットおよびその仕様の知識や、自前で教師データを作成する上での要点を概説する。本記事では、モデル開発プロセス、特に具体のフレームワークに準拠した学習・評価・改善に関する情報は触れていない。

アノテーション仕様とデータセット

固有表現抽出モデルを教師あり学習で自分で開発したい場合には、公開されているデータセットを用いて自分で実験することができる。

さらに、固有表現ラベル体系が自分のニーズに合っていない場合など、自前で教師データを構築したい場合には、アノテーション仕様の決定・アノテーション作業環境構築・作成したアノテーションデータの加工処理などが必要となる。

以下ではまず、アノテーションの仕様を構成する固有表現タグ形式と固有表現ラベル体系を説明し、それらに準拠した日本語固有表現抽出の公開データセットを紹介する。さらに続いて、自前でデータセットを作成する際に有用なライブラリやtips、アノテーション作成ツールを紹介する。

固有表現タグ形式

どのフレーズ(文字・単語列)が固有表現にあたるかという教師ラベル情報を表現する形式として、BIOタグ・BILUO(=BIOES, BMEWO)タグという形式が用いられることが多い。この形式では各トークン(≒単語や文字)ごとに固有表現ラベルを予測させるタスクを想定している。

例えばBIOタグ形式は、代表的なNER Shared TaskであるCoNLL-2003のデータセットで採用されている(CoNLL-2003形式ではPOS/名詞句チャンキング/NERの3タスクの教師ラベルが並置されていることに注意)。

https://www.clips.uantwerpen.be/conll2003/ner/

固有表現ラベルPERSON, COMPANY, TIMEをBIO/BILUOタグで記述する例:

トーク BIO BILUO
昨日 B-TIME U-TIME
山田 B-PERSON B-PERSON
太郎 I-PERSON L-PERSON
O O
MNTSQ B-COMPANY B-COMPANY
( I-COMPANY I-COMPANY
モンテスキュー I-COMPANY I-COMPANY
) I-COMPANY I-COMPANY
株式会社 I-COMPANY L-COMPANY
O O
行っ O O
O O
O O

固有表現ラベルの体系

人名や企業名といった固有表現のカテゴリ全体の定義体系をどう策定するかについては、伝統的に固有表現抽出の研究会議において議論されてきた。よく引用される代表的な会議としては、英語だと Message Understanding Conference(MUC), 日本語だと Information Retrieval and Extraction Exercise(IREX) がよく知られている。

これらから派生して、一般ドメインの固有表現ラベルを細分類化したり、化学(BioCreative IV CHEMDNER)や医療(BioCreative V CDR)などのドメイン特化のラベル体系が提唱されるなど、様々なラベル体系が定義されてきている。日本語の一般ドメイン固有表現を細分類化する研究としては、関根の拡張固有表現階層(Extended Named Entity; ENE*1 )が代表的である。

日本語NERで参照されるラベル体系は長らくIREXおよびENEであったが、近年普及してきたモデル同梱のNLPライブラリであるspaCyの影響を主として、OntoNotes5.0コーパスのラベル体系が参照されることも出てきた。日本語NERの公開データセットであるUD Japanese GSDでは、日本語向けに改変されたOntoNotes5.0ラベル体系が採用されている:

https://www.anlp.jp/proceedings/annual_meeting/2020/pdf_dir/P1-34.pdf

 

商用利用可能な日本語NERデータセット

商用利用可能*2なNERモデルを構築する際に、元となるテキストの著作権が問題になる。日本語の信頼できるNERアノテーション済みデータセットとしては以下が代表的である。

データセット コーパス 固有表現ラベル体系 利用形態
UD Japanese GSD wikipedia 日本語向けにOntoNotes5からENEに対応付けられた体系 web公開
KWDLC Webからクローリングしてきた文書本文の先頭3文 IREX web公開
GSK2014-A BCCWJ 関根の拡張固有表現(ENE)階層 有料・申請後DVDにて受領

UD_Japanese-GSD

KWDLC - KUROHASHI-CHU-MURAWAKI LAB

GSK2014-A 拡張固有表現タグ付きコーパス | GSK

有償版 (BCCWJ-DVD)

 

(追記)日本語NER向けにOntoNotes5.0->ENEへの対応付けが施されたデータはMegagon Labs様にて管理されており、以下にて公開されている(Matsuda (@hmtd223) 様、情報提供ありがとうございました!)

https://github.com/megagonlabs/UD_Japanese-GSD/releases/tag/v2.6-NE

論文内でも解説されている、OntoNotes5->ENE の対応表は以下で公開されている:

https://github.com/megagonlabs/UD_Japanese-GSD/blob/master/ene_mapping.xlsx 

アノテーションデータ処理

上記のようなデータセットはそれぞれ個別のデータ記述方式で公開されており、所望のスパンデータやBIOデータ(CoNLL2003-likeなフォーマット)を抽出するまでひと手間かかる。データセット特有のフォーマットの問題はひとまず置いといて、一般論としてアノテーションデータの持ち方にも良し悪しがあるので、ここではこの点の整理を試みたい。

NERにおけるアノテーション記録形式

まず、固有表現抽出ではアノテーション情報の保持の仕方に大きく2種類のやり方がある。

「MNTSQ株式会社(以下、乙とする)」 という文字列に対するアノテーションとして、

形式 値の例 解説
文字列スパン [(0, 9), "COMPANY"] エンティティ出現位置とラベルを保持
名称リスト [("MNTSQ株式会社", "COMPANY")] エンティティ名称とラベルの集合として保持

この整理については、Amazon Comprehend の custom entity recognizer の項に記述がある。

文字列スパン形式は、情報ロスの無い正確性にメリットがあるが、このデータを効率的に作成するには後述するNERアノテーションツールを使う必要がある。また、抽出元のテキスト文字列に対して長さが変わるような加工をしてはならない制約が付いて前処理などを施しづらいなど、データの管理により気を払う必要がある。

名称リスト形式は、エンティティ名称あたり1ラベルであり、正確な出現位置の情報が失われるため、同一名称エンティティが複数箇所に出現した際に該当するエンティティがどれかという情報が復元できない。しかし、スプレッドシートなどでの記録が容易な点、人間に読みやすい点、文字列の加工に対して曖昧マッチで復元できる場合もある点などから採用されることも多い。パターン辞書エントリのマッチングから決め打ちでNER教師データを作成するdistant supervisionのアプローチでは、名称リスト形式の制約がそのまま当てはまる。

いずれにしても、実際に学習に使う段階ではスパン形式に変換する必要がある点には注意する。名称リストからテキスト内のスパン情報を再構成する作業は実用上頻繁に起こるため、その用途に有用なライブラリを後ほど紹介する。

その前に、スパン形式で記録するアノテーション作業を行う上で有用なツールを紹介する。

NERアノテーション作成作業の効率化

文書分類のような1テキストに1ラベルをつけるようなタスクはスプレッドシートでの作業で間に合うことが多い。実際、Googleスプレッドシートなどのオンライン編集サービスを用いることはグループワークを円滑にするなどのメリットがある。

しかし、NERの教師データ作成をスプレッドシートでやろうとする場合、せいぜい名称リスト方式を取らないとアノテーション作業が困難である(もちろん、スプレッドシートで名称リスト形式の抽出をやる場合でも、周辺文字列を同時に保持するなどの妥協の仕方はあり得る)。このような固有表現のスパン記録作業を円滑に行うためのOSSSaaSが開発・提供されている。

フリーのOSSとしてはdoccanoがあり、以下の特徴がある:

doccanoでは1アップロードごとに1MBまでという上限があり、ファイル分割を要することがあるなどの制限があるものの、エンジニアであれば容易に環境構築ができ、把握すべき項目も少ないため、まず試してみたい場合におすすめできる。

https://github.com/doccano/doccano

このようなNERアノテーション上のニーズがツールでどう解消されるかについては有料NERアノテーションSaaSであるLightTagのデモ記事にも詳しく説明されている:

https://www.lighttag.io/help/en/articles/4325761-annotating-entities

 

(以下、やや脱線)

少しアノテーション効率化の研究を調べたことがある人にとっては、能動学習のサポートが欲しくなるかもしれない。能動学習(特にuncertainty samplingという手法)とは、モデルが出力するスコアのうち自信の無いデータに対して優先的にラベルをつけることで、より少ない教師データで高い性能が出るという枠組みを指す

Prodigy*3  というSaaSでは能動学習がサポートされているが、LightTag*4というSaaSでは以下の記事で議論されている論点から現時点ではサポート外と表明されている

https://lighttag.io/blog/active-learning-optimization-is-not-imporvement/

議論の大筋を抜粋・意訳すると

  • uncertainty samplingによる能動学習(≒モデルスコアによる学習データ選択)の成否はモデルがデータ境界を理解できるかに依存
  • しかし、実際に構築されるデータは、特定モデルの表現力の限界に依存したバイアスを孕んでしまう恐れがある 
  • 能動学習の本懐であるアノテーションが高コストである課題点に対して、特定モデルのバイアスにさらされた学習データを構築することは長い目で見て投資対効果が悪い(そのモデルに効いても、データで本来解きたい課題全体に対して有効なアノテーション資産が得られるかは微妙)
  • ただし、uncertainty sampling以外の手法を視野に入れたり、不均衡データに対するデータ探索の手法としては有効な場合もある

アノテーションシステムへ能動学習を導入することを検討したくなることがあるが、個人的な意見としては、純粋にアノテーション効率化の用途というよりも、モデルの挙動把握(probing)を助けるエラー分析のいち手段・追加のデータ収集のための指針の手がかりとするような用途の方が向いているのではないかと感じていたので、この議論は大いに参考になった。

NERで頻出のデータ加工処理

NERでは処理の過程で、

  「文字列+スパン」→「トークン+BIOタグ」→「チャンク+固有表現ラベル」

のような変換を経ることが多々あるが、これらの相互変換性(可逆性)を担保するデータハンドルを心がけないと後悔することがしばしばある。

「文字列+スパン」情報を基点にデータを加工・保持するのが基本だが、CoNLL2003フォーマットのようなトークンごとにBIOタグが振られたデータを作るには形態素解析を経る場合があり、実際の抽出結果を用いる際にはトークン列をタグに沿って結合したチャンクデータに変換することがある。

そしてエラー分析の段階において、観察したチャンクのデータから変換元となるBIOタグやスパンデータを頼りに周辺文字列を確認したい、という必要が生じた場合に変換前のデータ形式に戻れない(可逆性が無い)と困るのである。

 

以下、具体例で説明すると

項目
テキスト文字列 "MNTSQ株式会社(以下、乙とする)。契約当事者: MNTSQ株式会社"
文字列スパン [(0, 9, "COMPANY"), (26, 35, "COMPANY")]
単語BIO [("MNTSQ", "B-COMPANY"), ("株式会社", "I-COMPANY"), ("(", "O"), ..., (":", "O"), ("MNTSQ", "B-COMPANY"), ("株式会社", "I-COMPANY")]
チャンク [ (["MNTSQ", "株式会社"], "COMPANY"), (["MNTSQ", "株式会社"], "COMPANY") ]

これをエラー分析などのために可逆的なデータとするためには、チャンク情報に文字列スパン情報を埋め込むなどの工夫が必要となる。しかし、単語BIOの段階では形態素解析を経てインデックスが単語トークン単位に変わってしまったり、形態素解析のための前処理を経て特定文字が除去されてしまう結果、文字列スパンの情報が位置ズレを起こしてしまうなどの事態が発生しがちである。

データ変換の過程で文字・単語の位置対応を慎重に保持することも可能ではあるが、後述する pytokenizations というライブラリを用いれば前処理などを経た後のトークン対応を復元することができる。似た問題はBERTなどで行われるsubwordベースのNERの際にも発生し、BERT(Transformers)ベースのNERを実現するライブラリ camphr*5 ではこのライブラリを用いてトークン対応復元処理が記述されている。

 

※ NERのような系列抽出のタスクをトークン単位のBIOタグ予測ではなく、スパン形式を直に予測する流儀のモデリングも研究されている。特に機械読解タスクのSQuADはスパンを出力するモデルとして知られているが、関係抽出タスクの一つである意味役割付与(SRL)のタスクなどでもスパン予測の研究が近年見られる。スパンを直に予測する際には当記事で述べた変換処理の一部は不要となるかもしれない。)

NERアノテーションデータ加工に有用なライブラリ

アノテーション名称リストからテキスト内のスパン情報を再構成したり、前処理などを経たテキスト内のトークン対応位置を復元したりするのに便利なライブラリを紹介する。

ライブラリ名 用途
pyahocorasick 高速な厳密マッチ/スパン抽出
regex 柔軟な曖昧スパン抽出
pytokenizations / pytextspan トークン列・文字列どうしのアラインメント

https://pypi.org/project/pyahocorasick/

https://pypi.org/project/regex/

https://pypi.org/project/pytokenizations/

https://pypi.org/project/pytextspan/


pyahocorasick

文字列マッチングアルゴリズムであるAho–Corasickアルゴリズムを計算するライブラリ。オートマトンの事前計算によって厳密マッチおよびスパン抽出を高速に行うことができる。以下、スパン抽出における使用例:

from ahocorasick import Automaton

A=Automaton()
# 
A.add_word("MNTSQ株式会社",("COMPANY","mntsq株式会社"))

A.make_automaton()

text = "MNTSQ株式会社(以下、「乙」とする)"
for item in A.iter(text):
    end = item[0] + 1
    start = end - len(item[1][1])
    print(item, text[start:end]) 
(8, ('COMPANY', 'mntsq株式会社')) MNTSQ株式会社
regex

python標準ライブラリreの拡張。誤り数を許容した正規表現マッチが利用できたりする点で便利。他にも、漢字やひらがななど文字種指定のマッチングができるなど、unicodeの処理が便利になるご利益もある。

上記のpyahocorasick相当の処理:

import regex as re

text = "MNTSQ株式会社(以下、「乙」とする)"
annotation = "MNTSQ株式会社"

for m in re.finditer(annotation, text):
    start, end = m.span()
    print(text[start:end])
MNTSQ株式会社

 

曖昧マッチもできる。詳細はPyPyページ内マニュアルの Approximate “fuzzy” matching 項を参照。: 

import regex as re

text = "MNTSQ 株式会社(以下、「乙」とする)"
annotation = "MNTSQ株式会社"
# 空白文字の挿入を1文字許容したマッチ
fuzzy_pattern = re.compile("(?:%s){i<=1:\s}" % (re.escape(annotation)))

for m in fuzzy_pattern.finditer(text):
    start, end = m.span()
    print(text[start:end])
MNTSQ 株式会社
pytokenizations / pytextspan

2つのトークン列・文字列のアラインメントをとることのできるライブラリ。スパンデータで抽出することができる。元となるトークン列・文字列でスパン情報を記録した後に、前処理などで加工したトークン列・文字列に対して対応するスパンを再構成するといった使い方ができる。他にも、異なる形態素解析器の解析結果の比較、wordとsubwordの対応関係の再構成など系列間対応を取る比較に幅広く使うことができる。

列比較のアルゴリズムとしてはdiffコマンドで使用されるMyersのアルゴリズムを使用して計算されている。また実装内ではNFKDのunicode正規化を行っているため、その範囲で文字が同一視されることに注意する。

前処理のような系統的な加工を経る際にはこのツールが適しているが、一方でOCR誤りのようなエラーが変則的なケースに対しては、前述のregexの許容編集数や誤り許容文字を調整することで曖昧マッチするのが適していることもある。

以下に公式の使用例を拡張した例を示す:

pytokenizations demo (https://github.com/tamuhey/…

 

以上、固有表現抽出の教師データにまつわる論点や処理のtipsについて経験上つまづいた点を中心に概説した。この記事はMNTSQ株式会社の業務時間内に書かれた。

MNTSQ株式会社では契約書の自然言語処理による解析に協力いただける心強い仲間を募集しています。

www.wantedly.com