INCEpTIONで固有表現アノテーションしてみた

# はじめに

固有表現抽出のためのアノテーションツールとしては、日本では doccano[^doccano] あたりがよく利用されている印象があります。

一方で社内では INCEpTION[^inception] というツールが高機能だということで利用していましたが、日本ではあまり利用されていないのか、日本語の解説記事が見当たりませんでした。

よって INCEpTION 触って理解した、アノテーションの一連の手順をまとめてみます。

:::note warn
今回説明するにあたって使用したバージョンは INCEpTION 28.2 です。バージョンにより一部UI等が異なる可能性があります。
:::

以降の作業の説明にあたっては、INCEpTION 28.2 の公式ガイドを参照しました。

https://inception-project.github.io/releases/28.2/docs/admin-guide.html

https://inception-project.github.io/releases/28.2/docs/user-guide.html

[^doccano]: https://github.com/doccano/doccano
[^inception]: https://github.com/inception-project/inception

# INCEpTION におけるワークフロー

INCEpTION 複数人でのアノテーションができるようになっており、以下の図のようなワークフローが想定されています。

![](https://inception-project.github.io/releases/28.2/docs/user-guide/images/progress_workflow.jpg)

画像引用元：https://inception-project.github.io/releases/28.2/docs/user-guide.html#_workflow

上記の図を大まかに分けると以下の4ステップになります。

1. INCEpTION上に作業用プロジェクトを準備する
1. ドキュメントにアノテーションする
1. キュレーション（複数名でバラバラに行われたアノテーションの修正や統合）する
1. 最終的なデータセットを出力する

# INCEpTION を使用した固有表現アノテーション

それでは簡単なサンプルとして、2名のアノテーターが羅生門のテキストに「人物」、「地名」のアノテーションを付与するという想定で、アノテーションの一連の手順を説明します。

## インストール

まずは INCEpTION のインストールから始めます。

Administrator Guide に記載されている Docker Compose による方法[^inception-docker-compose]に従ってローカルマシン上に INCEpTION を構築します。

docker-compose.yml ファイルを置くディレクトリを作成します。

```
mkdir inception
cd inception
```

作成した inception ディレクトリに docker-compose.yml ファイルを作成します。ファイルはAdministrator Guide に記載されている内容をそのまま使用します。

<details>
<summary>docker-compose.yml の内容</summary>

```yml:docker-compose.yml
##
# docker-compose up [-d]
# docker-compose down
##
version: '2.4'

networks:
  inception-net:

services:
  db:
    image: "mariadb:10.7"
    environment:
      - MYSQL_RANDOM_ROOT_PASSWORD=yes
      - MYSQL_DATABASE=inception
      - MYSQL_USER=${DBUSER:-inception}
      - MYSQL_PORT=3306
      - MYSQL_PASSWORD=${DBPASSWORD:-inception}
    volumes:
      - ${INCEPTION_DB_HOME:-db-data}:/var/lib/mysql
    command: ["--character-set-server=utf8mb4", "--collation-server=utf8mb4_bin"]
    healthcheck:
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-p${DBPASSWORD:-inception}", "-u${DBUSER:-inception}"]
      interval: 20s
      timeout: 10s
      retries: 10
    networks:
      inception-net:

  app:
    image: "${INCEPTION_IMAGE:-ghcr.io/inception-project/inception}:${INCEPTION_VERSION:-28.2}"
    ports:
      - "${INCEPTION_PORT:-8080}:8080"
    environment:
      - INCEPTION_DB_DIALECT=org.hibernate.dialect.MariaDB103Dialect 
      - INCEPTION_DB_DRIVER=org.mariadb.jdbc.Driver
      - INCEPTION_DB_URL=jdbc:mariadb://db:3306/inception?useSSL=false&useUnicode=true&characterEncoding=UTF-8
      - INCEPTION_DB_USERNAME=${DBUSER:-inception}
      - INCEPTION_DB_PASSWORD=${DBPASSWORD:-inception}
      - JAVA_OPTS=-Dspring.jpa.properties.hibernate.dialect.storage_engine=innodb
    volumes:
      - ${INCEPTION_HOME:-app-data}:/export
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped
    networks:
      inception-net:
      
volumes:
  app-data:
  db-data:
```

</details>

以下のコマンドでコンテナを起動します。

```
docker-compose -p inception up -d
```

コンテナが起動したら <http://localhost:8080/login.html> にアクセスします。

コンテナ起動時に Admin アカウントが作成されているので、以下の User ID、Password でログインします。

User ID|Password
-------|--------
`admin`|`admin`

初回アクセス時には INCEpTION の使用統計の収集に協力するか聞かれます。収集しないようにしたい場合は「Disabled」を選択して Save ボタンをクリックします。

![INCEpTION Telemetry Settings](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/685b0dd6-c8e0-8e2a-9b44-0145776598cb.png)

[^inception-docker-compose]: https://inception-project.github.io/releases/28.2/docs/admin-guide.html#_docker_compose

## ユーザーの作成

今回のチュートリアルで使用するユーザーを作成します。

ユーザー作成画面にアクセスします。

![INCEpTION-Administration-Users.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/0fdf1b98-d8ac-7351-385b-5469ff1b7f91.png)

1. 画面上部の Administration ボタンをクリックします
1. サイドバーの Users をクリックします

![INCEpTION-Users-Creation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/c6cb877e-715d-e6bb-be6d-beabfaf35621.png)

1. Create ボタンをクリックします
1. User details パネルの Username, password, Roles を以下の表に従い設定します
1. Save ボタンをクリックして保存します

Username|Password|Roles
--------|--------|-----
`user1` | `user1user1` | `ROLE_USER`, `ROLE_PROJECT_CREATOR`
`user2` | `user2user2` | `ROLE_USER`, `ROLE_PROJECT_CREATOR`

作成できたら `user1` アカウントでログインしなおします。

## プロジェクトの作成

アノテーション作業のためのプロジェクトを作成します。

![INCEpTION-Projects-Creation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/3a612d8c-4081-92eb-15ea-0d4ad3b29fb7.png)

1. 左上の New project... ボタンをクリックします

![INCEpTION-Projects-Creation-Details.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/909bd364-a2bc-93b7-0431-6d9ba833d02f.png)

以下の表の内容を各項目に入力し、 Save ボタンをクリックしてプロジェクトを保存します。

Name|URL slug
---|---
サンプル1|`sample1`

なお URL slug はプロジェクトのURLの一部になるIDであるため、複数プロジェクトを作成する場合は被らないようにする必要があります。使用可能な文字種などの詳細はUser Guideを参照してください[^project-url-slug]。

[^project-url-slug]: https://inception-project.github.io/releases/28.2/docs/user-guide.html#sect_projects

ダッシュボードから設定ページに移動し、プロジェクトの各種設定をしていきます。

![INCEpTION-Project-Dashboard.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/ef774cbc-d58f-8ea0-667e-ea41359b9e3b.png)

1. 上部メニューバーの Dashboard ボタンをクリックします
1. サイドバーから Settings を選択します

### ユーザーの追加

プロジェクトにユーザーを追加します。user1はプロジェクト作成時に既に追加されているため、 user2 を追加します。

![INCEpTION-Administration-Project-User.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/bc92d31c-09f4-1cc1-cbcd-6b0b59ac36ff.png)

1. サイドバーから Users を選択します
1. Add users の隣の入力欄をクリックするとドロップダウンが表示されるため、そこから user2 を選択します
1. Add ボタンをクリックします

これで user2 がこのプロジェクトに追加されました。user2にはデフォルトではannotator権限のみが付与されます。権限の詳細は User Guide の Getting started 内のセクション[^inception-users-in-getting]を参照してください。

[^inception-users-in-getting]: https://inception-project.github.io/releases/28.2/docs/user-guide.html#users_in_getting_started


### タグセットの作成

アノテーションに付与する以下の2つのタグを作成します。

|Name|
|----|
|人物|
|地名|

![Tagsets 設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/24d5d6d3-0a2e-9acd-089b-ab163c039a9b.png)

1. サイドバーから Tagsets を選択します
1. Tagsets パネルの Create ボタンをクリックして新しい Tagset を作成します
1. Tagset Details パネルの Name を設定します
1. Tagset Details パネルの Save ボタンをクリックして作成した Tagset を保存します
1. Tags パネルの Create ボタンをクリックして新しい Tag を作成します
1. Tag Details パネルの Name を設定します
1. Tag Details パネルの Save ボタンをクリックして変更を保存します

### Layer の設定

INCEpTION では1つのドキュメントに対し固有表現(Named Entity)、品詞(POS; Part of Speech)など複数の種類のアノテーションを付与できます。そしてそれらを Layer という単位で管理しています。

今回は固有表現のアノテーションをしたいので、 Layer にあらかじめ用意されている Named entity エントリの設定を編集して利用します。

![Layer 設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/3c440396-e6bf-349c-40c0-60e9df3c9ccb.png)

1. サイドバーからから Layers を選択します
1. Layers パネルの Named entity エントリを選択します
1. Features パネルの value: [String] エントリを選択します
1. Feature Details パネルの Tagset に先ほど作成した「サンプルタグセット」を設定します
1. Feature Details パネルの Save ボタンをクリックして変更を保存します

### キーバインドの設定

アノテーションするドキュメントの量が多い場合や付与するタグの種類が多い場合、ショートカットキーを設定しておいた方が効率よくアノテーション作業を進められます。

![INCEpTION-Administration-Layers-Keybingings.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/206a3055-8099-23f2-5803-e8b1f1defa8d.png)

1. Feature Details パネルの Key bindings 項目でキーバインドを設定したいタグ名を選択します
1. 設定したいキーバインドを入力します
1. `+` ボタンをクリックしてキーバインド設定を追加します
1. Save ボタンをクリックして変更を保存します

上記の手順を繰り返し、今回は以下の2つのキーバインドを設定します。

タグ名|キーバインド
---|---
人物|`p`
地名|`l`

なおキーバインドには <kbd>Ctrl + p</kbd> のような修飾キーと通常キーの組み合わせは設定できますが、<kbd>k + p</kbd> のような通常キーのシーケンスは設定できません[^layer-keybindings]。

[^layer-keybindings]: https://inception-project.github.io/releases/28.2/docs/user-guide.html#_key_bindings

### ドキュメントのアップロード

アップロードするドキュメントは1文1行にし、形態素を半角スペースで分かち書きした形式にしておく必要があります。また文字コードはUTF-8、改行コードはLFにしておくとよいでしょう。

今回は青空文庫にある羅生門のテキストファイル[^rashomon]をダウンロードして修正を加えて、 rashomon_wakati.txt というテキストファイルを用意します。

```text:rashomon_wakati.txtの一部
ある 日 の 暮方 の 事 で ある 
一 人 の 下人 が 、 羅生門 の 下 で 雨 やみ を 待っ て い た 
広い 門 の 下 に は 、 この 男 の ほか に 誰 も い ない 
```

修正後のテキストファイルのサンプルは上記です。エディタを用いて余計な注釈記号等を除去しています。また句点（`。`）を改行に変換し1文1行にした後、Mecabを用いて分かち書きしています。

[^rashomon]: https://www.aozora.gr.jp/cards/000879/card127.html

アノテーションするドキュメントをプロジェクトにアップロードします。

![INCEpTION-Documents-Upload.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/79b50d10-9b34-b0ae-ba59-504d6d107fa5.png)

1. サイドバーから Documents を選択します
1. フォルダアイコンをクリックしてアップロードするファイルを選択します
1. Format には Plain text (space-sparated tokens, one sentence per line) を選択します
1. Import ボタンをクリックしてドキュメントをアップロードします

## アノテーション

プロジェクト設定ができたので、アノテーションしていきましょう。

上部メニューバーの Dashboard ボタンをクリック、サイドバーから Annotation を選択してアノテーション画面にアクセスします。

アノテーション画面は以下のようになります。

![INCEpTION-Annotation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/d7580985-b082-81a3-c520-5091aa121547.png)

1. あらかじめアノテーションするレイヤーとして Named entity を選択しておきます
1. アノテーションしたい箇所をドラッグします
1. 付与したいタグ名をクリックし選択します

タグ名をクリックする代わりに先ほど設定したキーバインドを押してもタグ名が選択できます。

例えば「人物」を付与したいならば、<kbd>p</kbd>を押します。

設定したキーバインドを忘れたときは、右下の show keybindings… をクリックして確認できます。

またページ移動やUndoなどよく行う操作にはデフォルトでショートカットキーが設定されていたりするので、詳細は User Guide を参照してください[^inception-annotation-navigation][^inception-annotation-undo-redo]。

[^inception-annotation-navigation]: https://inception-project.github.io/releases/28.2/docs/user-guide.html#_navigation
[^inception-annotation-undo-redo]: https://inception-project.github.io/releases/28.2/docs/user-guide.html#_undore_do

### 検索

ドキュメントの量が多い場合やアノテーションしたい用語の表現のあたりが付いている場合、検索機能を使って任意の用語を見つけられます。

INCEpTION では検索機能に MTAS というライブラリを使用しており[^inception-search]、CQL (Corpus Query Language)というクエリ言語を用いて検索します。

[^inception-search]: https://inception-project.github.io/releases/28.2/docs/user-guide.html#sect_search-core

以下に検索対象ドキュメント、検索クエリ、検索結果の一例を示します。

```text:ドキュメント
ある 日 の 暮方 の 事 で ある 
一 人 の 下人 が 、 羅生門 で 雨 やみ を 待っ て い た 
広い 門 の 下 に は 、 この 男 の ほか に 誰 も い ない 
```

```text:検索クエリ
下
```

```text:検索結果
広い 門 の 下 に は 、 この 男 の ほか に 誰 も い ない 
```

上記の検索クエリのように、単純に検索したい表現を入力した場合、トークン単位での完全マッチで検索します。よって「下」はマッチしますが、「下人」はマッチしません。

#### 検索クエリ例

他にも検索クエリの例を示します。

```text:検索クエリ
"下.*"
```

検索クエリには正規表現を使用できます。上記のクエリを入力した場合は、「下」と「下人」の両方にマッチします。ただし正規表現を使用する場合はダブルクォートで括る必要があります。

```text:検索クエリ
<Named_entity.value="人物"/>
````

上記クエリで検索した場合は、Named entity の人物タグを付与した箇所がマッチします。

他にも CQL の記法はありますが、より詳細に知りたい場合は User Guide の Mtas search syntax のセクション[^inception-search-mtas]を参照してください。

[^inception-search-mtas]: https://inception-project.github.io/releases/28.2/docs/user-guide.html#sect_search-mtas

### Recommender

INCEpTION には Recommender という、既に付与したアノテーションからアノテーション候補をドキュメント中に提示してくれる機能があり、アノテーション作業の補助として利用できます。

Recommender には Multi-Token Sequence Classifier (OpenNLP NER) [^inception-recommender-opennlp-ner]という固有表現抽出タスクで利用できるものが用意されているので、今回はこれを使います。

[^inception-recommender-opennlp-ner]: https://inception-project.github.io/releases/28.2/docs/user-guide.html#_multi_token_sequence_classifier_opennlp_ner

#### Recommender の設定

ダッシュボードから設定ページに移動し、Recommenderの設定をしていきます。

![INCEpTION-Administration-Recommenders.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/15fbc15d-cdf6-90ce-fb84-017c3d5eac9c.png)

1. サイドバーから Recommenders を選択します
1. Create ボタンをクリックします
1. Details パネルの項目を以下の表に従って入力します
1. Save ボタンをクリックして変更を保存します

Layer|Feature|Tool
---|---|---
Named entity|value|Multi-Token Sequence Classifier (OpenNLP NER)

設定を終えたら Dashboard からアノテーション用ページに戻ります。

その他 Recommenders の設定については User Guide の Recommenders のプロジェクト設定セクション[^inception-project-recommenders]を参照してください。

[^inception-project-recommenders]: https://inception-project.github.io/releases/28.2/docs/user-guide.html#sect_projects_recommendation

#### Recommender の使用

それでは設定した Recommender 利用できるようを有効化します。

![INCEpTION-Annotation-Recommender-Activate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/fea173de-0711-d71f-1e8e-b24ff069ed4e.png)

アノテーションページのサイドバーのロボットのアイコンをクリックし、表示された Active Learning パネルの三角矢印のアイコンをクリックします。

![INCEpTION-Annotation-Recommendations.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/69630053-91eb-64b6-194b-d72bdeaa288c.png)



### アノテーション作業の完了

アノテーション作業が終わったら画面上部の錠のアイコンをクリックし、ドキュメントをアノテーション完了の状態にします。

![INCEpTION-Annotation-Finish.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/aee54865-7250-a834-55d1-fb03fd154add.png)

ドキュメントがアノテーション完了の状態になると、後続のキュレーション作業ができるようになります。

## キュレーション

複数人のアノテーションをキュレーションするという状況を再現するため、 `user2` でも上記手順に従い、アノテーションしておきます。

Dashboard のサイドバーの Curation を選択し、表示されたドキュメント選択ページから rashomon_wakati.txt を選び、キュレーションページを開きます。

キュレーションページを開くと以下のような画面になります。

![INCEpTION-Curation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/e66efddd-c33d-9091-8fe6-8245f40ed8b3.png)

画面下部には各ユーザーが実施したアノテーション内容が表示され、画面上部にはそれらアノテーション結果を統合したキュレーション済みの内容が表示されています。

画面下部の各ユーザーが付けたアノテーションをクリックするとそのアノテーションが承認され、上部のキュレーション済みのドキュメントに反映されます。

### アノテーションの一括マージ

アノテーションの数が多い場合、アノテーションを一つひとつ確認して承認していくのは大変です。特定のユーザーのアノテーションが信頼できるならば、一括でキュレーション済みのドキュメントに反映できます。

![INCEpTION-Curation-Merge-All.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/886084f6-288a-857e-ee23-029ed008ca00.png)

画面下部にある特定のユーザーが付与したアノテーションを右クリックすると、Merge all Named entity というメニューが出ます。メニューをクリックすると、そのユーザーが付けたすべてのアノテーションがマージされます。

各ユーザーのアノテーションがキュレーション済みドキュメントに取り込まれたかどうかは、画面左側の Units パネルで確認できます。

Units パネルの情報は自動更新されないので、アノテーションをマージするなどした場合は、上部の Refresh ボタンをクリックして最新化してください。

![INCEpTION-Curation-Accepted.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/2394e763-03c7-cc2c-0d5d-24e4bec00d2c.png)

数字の背景が緑色になっているものは、当該の行に付与されたアノテーションがキュレーション済みドキュメントに取り込まれていることを示します。

各色が何を示しているかは Units パネル上部の Legend ボタンをクリックするか、 User Guide の Curating a document[^inception-curating-doc]セクションを参照してください。

[^inception-curating-doc]: https://inception-project.github.io/releases/28.2/docs/user-guide.html#_curating_a_document

## データセットの出力

キュレーション作業が完了したら、画面上部の Export ボタンをクリックしてデータセットに出力できます。

![INCEpTION-Curation-Export-Dataset.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3489051/cccd81eb-8cb8-20bd-481e-302740941c20.png)

出力するデータセットのフォーマットは十数種類用意されているため、機械学習ライブラリが要求するフォーマットに応じて適当なものを選択すると良いでしょう。

出力できるフォーマットにどのようなものがあるかは User Guide の Appendix C: Formats セクション[^inception-appendix-formats]に記載されています。

[^inception-appendix-formats]: https://inception-project.github.io/releases/28.2/docs/user-guide.html#sect_formats

# おわりに

User Guide を見ると、今回使用したもの以外にもいくつか機能があるようなので、それらの機能を使ってよりアノテーション作業を効率化できるとよいなと思いました。