Sansan Tech Blog

Sansanのものづくりを支えるメンバーの技術やデザイン、プロダクトマネジメントの情報を発信

【Techの道も一歩から】第34回「固有表現抽出のためのデータを作る」

f:id:kanjirz50:20190104142720j:plain

こんにちは。 DSOC 研究開発部の高橋寛治です。

本記事は Sansan Advent Calendar 2020 - Adventar の初日の記事です。

クリスマスにアノテーションされたデータがプレゼントされると幸せですよね。 プレゼントを渡せるように、タグ設計やアノテーションについて、どのような考えでどうデータを作るのかを具体的に紹介します。 ただし、Advent Calendar 1日目ということでゆる~く紹介したいと思います。

最近は、固有表現抽出のアノテーションデータの説明や実際のシステム運用の知見、書籍など、固有表現抽出の情報が増えてうれしいですね。

概要

Wikipedia 中の日本語の記事にタグ付けを行い、人名や企業名などを抽出できる固有表現抽出器を作ることを目的とします。

f:id:kanjirz50:20201119094350j:plain
単純化したフローチャート

  • スタンス
    • ざっくりとした性能目標がある
      • えいやで決めた目的・目標があるはずでしょうし、性能目標がないとデータ量を増やすべきか、ドメインを変えるべきかなどの議論ができません
    • 完璧を求めない(うまくいかないことは、あきらめる・妥協する)
      • 完璧に整合性がとれたタグ体系の設計や曖昧さのないタグ付けは、少なくとも私にはできません*1
    • 他人に依頼
      • 他の人に依頼できるとデータ作りがスケールしますし、依頼できるということは再現しやすい気がします

タグとデータを決める

後段のタスクで利用したいタグを定めます。 たとえば、Sansan のニュース配信のために企業名や人名を取り出すタスクとします。 性能目標としては企業名は 8 割くらい取れていればいいものとします*2。 タグ体系に悩む場合は、例えば、拡張固有表現を参考に取捨選択するというのもいいと思います。

ただし、タグを細かく定義したからといって、抽出できるかどうかは別問題です。 ここでは、テキスト中から、人名・企業名・地名・イベント名・時間表現・役職を取得したいとします。

次にタグの形式ですが、固有表現抽出で一般的な IOB2 (Inside-outside-beggining) タグを用います。

  • B: 固有表現の先頭
  • I: 2トークン以上で構成される固有表現の先頭以外のトークン
  • O: 固有表現以外のトークン

IOB2 タグは、入力されたトークン列に対して「B-企業名」のようにタグ付けし、固有表現をモデルで取り扱いやすくします。 実際のタグ付けは、表計算アプリケーション(Google SpreadSheet)で行うため、トークンとタグが対応した状態となります*3。 表計算アプリケーションは結構誰でも操作方法がわかることや環境構築が不要ですので手軽に始められます。 ただし、タスク割り振りは個別に指定もしくは指示する必要があります。

次にデータを選びます。 今回は Wikipedia と決めてしまっています。 作成したデータの取り扱いに縛りがないということで、データの中身というよりは、データの権利や扱いやすさという観点で選びました。 実際には、解析対象となる文書と同じドメインから取得された文書だと、性能が出やすいように思います。

データ量をざっくりと決めます。 学習:開発:テストを 8:1:1 で行うとして、まずは 500 文というように決め打ちします。

アノテーションガイドラインを作成し、アノテーションに取り組む

誰かにアノテーションを依頼する際や後で何を基準にアノテーションしたかを確認するために、アノテーションガイドラインの策定を行います。

作業内容・手順

固有表現とは何かという定義を可能な限り 具体例 を持って示します。

種類 説明
人名 田中太郎, 田中, 太郎 人の名前を表す文字列
組織名 Sansan, Sansan株式会社, Sansan(株) 文中で組織として言及されている文字列
... ... ...

そして、例外的な事例について説明を加えます。 例えば、次のようなものです。

  • 括弧「」や句読点、。は固有表現に含まないとします
  • 役職だと新代表取締役の「新」や、共同 CEO の「共同」部分も含みません
  • サービス名の Sansan と企業名としての Sansan は別なので、こういったものに気をつけます

次に実際の作業手順です。 どの列を見て、何を行うのかを具体的に説明します。

文が単語に分解された列 固有表現の先頭はB、つながっている場合はI、固有表現ではない場合はO 説明
BOS
田中 B-人名 田中は人名であり、単語の先頭なので B
太郎 I-人名 太郎は田中に続く人名であり、単語の続きであるため I
O 固有表現に当てはまらないので O
O 固有表現に当てはまらないので O
Sansan B-組織名 Sansanは組織名であり、単語の先頭なので B
株式 I-組織名 株式はSansanの続きなのでI
会社 I-組織名 会社はSansan株式の続きなんで I
... ... ...

BOS は言語処理に取り組んでいる人にとっては当たり前ですが、普通はわかりません。 これは文頭を表すもので、気にしなくていいことを伝える必要があります。 空行を入れて文の区切りとするか、特殊なタグを入れて区切りとするか、うまくわかってもらえるほうを選びます。

また、 B-ORGANIZATION のような英語で書かれたタグをデータセットではよく見かけますが、作業依頼時の説明を簡略化するために B-企業名 のように置換したほうがやさしいと思います。

表計算ツールでタグ付けする場合は、データの入力規則(セレクトボックス)がおすすめです。 半角と全角のような目で見て気づきにくい誤りを減らせます。

少量をアノテーション

アノテーションする際にわからないものや迷うものが出てきます。 そのような時は、えいやで決めます・・・が一貫性は極力保てるよう努力します。 細かいことは、後段のタスクで問題になってから考えましょう。

少量をアノテーションした結果を目視で確認します。 人によるタグ付け結果では、いきなり I タグ から始まったり、タグの種類が一つの固有表現内で変化したりと、意外な間違いが見つかります。 こういったものも見つけて、フィードバックや注意喚起によりアノテーションの正確性を高めます。

アノテーション

おおよそ問題なく作業が行えるようになったら、アノテーションする量を増やします。

確認し、学習に使ってみる

実際にアノテーションされたデータの確認です。

タグの種類数や頻度、一つの固有表現内に複数の種類が紐付いていないか、IOB2形式になっているかを確認します。 どうしても誤りは入ってしまうため、ちょっとしたスクリプトを書いて、誤りらしいところを探し、手作業で修正します。

さて、データが整ったところで学習してみましょう。 BERT ベースのモデルに対して、ファインチューニングしてみます。

...
11/10/2020 18:49:44 - INFO - __main__ - eval_accuracy_score = 0.9079700572435051
11/10/2020 18:49:44 - INFO - __main__ - eval_precision = 0.7475961538461539
11/10/2020 18:49:44 - INFO - __main__ - eval_recall = 0.7873417721518987
11/10/2020 18:49:44 - INFO - __main__ - eval_f1 = 0.7669543773119605
...

F 値で 0.77 程度の固有表現抽出モデルが構築できました。 たまたまですが、おおよそ目標の数値が出ました。

これで足りない場合は、少しデータを増やすか減らして学習した際に、データ量が性能に影響しそうかどうかを検証します。 影響するなら、データを増やせばいいですね。

データを作ろう

データを作ることは、時間も労力もリスクも要します。 しかしながら、データと手法がかみ合うと、これまでに無かったものが作れると信じています。 基本的にはざっくりと取り組んでおります*4が、一例として参考にしていだけると幸いです。

ちなみに作ったデータは、朝起きたら枕元にあるクリスマスプレゼントとは異なりますが、公開予定です。

執筆者プロフィール

高橋寛治 Sansan株式会社 DSOC (Data Strategy & Operation Center) 研究開発部 研究員

阿南工業高等専門学校卒業後に、長岡技術科学大学に編入学。同大学大学院電気電子情報工学専攻修了。在学中は、自然言語処理の研究に取り組み、解析ツールの開発や機械翻訳に関連する研究を行う。大学院を卒業後、2017年にSansan株式会社に入社。キーワード抽出など自然言語処理を生かした研究開発に取り組む。

▼本連載のほかの記事はこちら

buildersbox.corp-sansan.com

*1:複数人間でのアノテーションの一致度の研究など、これだけで研究になる話

*2:企業名をキーとして配信を実現しているため、多少間違えて取得したとしても実在しない企業なら、後段タスクは影響はほぼ無い

*3:タグの始点と終点といったスパンを記録する方法もある

*4:何かしら定量的に例えばタグの種類に対する最低限のデータ量の目安を定める方法を作れないかとぼんやり思います。

© Sansan, Inc.