【ポートフォリオ】固有表現抽出データセットの作成　＃０　導入

# 概要

日本語で固有表現抽出データセットを自作しました。
（質の高いデータセットではない可能性があります。）

:::note
ポートフォリオとして、**自作のデータセットでファインチューニングした言語モデルを使ったアプリ**を公開しました。

この記事を読むだけでも、この記事の内容をある程度理解できるとは思いますが、プロジェクト全体を理解している前提で書かれています。
プロジェクト全体の概要については、[こちらの記事](https://qiita.com/wolf4032/private/9dd7423c706fa86bf005)をご覧ください。
:::


# 作成・公開したデータセット

https://huggingface.co/datasets/wolf4032/token-classification-japanese-search-local-cuisine


# データの構造

```python
{
    'text': '関西地方あるいは四国地方の、秋に食べられているしいらを使用した魚料理があったら、検索。',
    'entities': [
        {
            'name': '関西地方',
            'span': [0, 4],
            'type': 'AREA'
        },
        {
            'name': '四国地方',
            'span': [8, 12],
            'type': 'AREA'
        },
        {
            'name': '秋',
            'span': [14, 15],
            'type': 'SZN'
        },
        {
            'name': 'しいら',
            'span': [23, 26],
            'type': 'INGR'
        },
        {
            'name': '魚料理',
            'span': [31, 34],
            'type': 'TYPE'
        }
    ]
}
```
料理を検索するアプリに使う、言語モデルの作成を目的としたデータセットです。
（言語モデルは、入力文から、料理検索用のキーワードを抽出するようにファインチューニングします。）
各データには、入力文中に含まれる、検索キーワードとして相応しい固有表現の位置と、種類が示されています。

固有表現の種類は以下の４つです。
1. **AREA：　都道府県/地方**
1. **TYPE：　種類**
1. **SZN：　季節**
1. **INGR：　食材**

データの構造は、[stockmark/ner-wikipedia-dataset](https://huggingface.co/datasets/stockmark/ner-wikipedia-dataset)のものをそのまま採用させていただきました。


# 作成に使用したノートブックの解説

[＃１　基本的な文頭表現の作成](https://qiita.com/wolf4032/private/5fea8539cdb42335e055)
[＃２　文頭表現の分類](https://qiita.com/wolf4032/private/06bdbc09ae72a228867f)
[＃３　似た文頭表現の追加](https://qiita.com/wolf4032/private/ad5cdf11199111e312e7)
[＃４　文頭表現へのカンマと並列表現の追加](https://qiita.com/wolf4032/private/67d8aee0d87d4f1d83de)
[＃５　文末表現の作成](https://qiita.com/wolf4032/private/cc7b8ee77639e328af75)
[＃６　テンプレートの作成](https://qiita.com/wolf4032/private/8071f68c13cfeb561b3a)
[＃７　トークン化前のデータセットの作成](https://qiita.com/wolf4032/private/8c0fadc274a7188a921e)
[＃８　エンコード済みデータセットの作成](https://qiita.com/wolf4032/private/38e6ca2452773f2a5a43)


# 背景

固有表現抽出言語モデルを作成したかっただけなので、最初は、ChatGPTにデータセットを作成してもらっていました。
しかし、そのデータセットを使って、ファインチューニングした言語モデルの予測には、以下の問題がありました。
1. **入力文の先頭の固有表現を、本来の種類関係なく、高確率でAREAに分類する**
1. **文末の表現を変えるだけで、固有表現の予測結果も変わる**
例えば、「鶏肉を使った料理を教えて」という入力文と、「鶏肉を使った料理はありますか？」という文章で、予測結果が異なってしまうようなことが見られました。
文末の表現は、固有表現抽出と関係がないはずなので、このような挙動は好ましくないのではと思いました。

この問題は、データセットの２つの特徴が原因ではないかと考えました。
1. **多くの入力文の先頭がAREAの固有表現だった**
固有表現”周辺の表現”よりも、固有表現の”位置”がラベルの予測に大きな影響を与えてしまいそう。
1. **文末表現のバリエーションが少なかった**
例えば、データセットのうち、「～を教えて」という文末表現を含む入力文の多くに、INGRの固有表現が含まれていたら、ファインチューニング後の言語モデルが、「～を教えて」という文末表現を含む入力文に、INGRの固有表現が含まれていなくても、いずれかの語彙をINGRに分類してしまいがちになりそう。

そこで、０から自分でデータセットを作成することにしました。

本来の自然言語処理では、すでにある大量のデータを前処理して使うと思うので、自分で作成するのは何か違うような気がしましたが、そもそもChatGPTが作成する入力文は、自然な日本語とは言い難いものが多いように見られ、前処理以前に、自分で作成するしかないと考えました。


# 方針

ChatGPTが作成したデータセットの問題を踏まえ、以下の条件を満たすデータセットを作成することにしました。
1. **入力文が含む固有表現の種類、数、順番を、思いつく限りで全てのパターンが採用されている**
1. **豊富な文末表現のバリエーションを持つ**

これらの条件を満たしていれば、固有表現抽出の判断材料として、語彙の位置や、文末表現の優先度が著しく低くなり、各固有表現の”周辺の表現”を最重視するようになるのではないかと考えました。


# 大まかな手順

これ以降、”文頭表現”という言葉は、入力文中の、固有表現を含む部分であり、文末表現以外の部分のことを意味します。
例えば、「東京の、肉料理を教えてください。」という入力文では、「東京の、肉料理」までが文頭表現で、「を教えてください」の部分を文末表現とします。
1. **多種多様な文頭表現の作成**
1. **多種多様な文末表現の作成**
1. **各文頭表現に、ランダムに一つの文末表現をくっつける**

厳密には異なりますが、全体をイメージしやすい様に表現すると、以上のような手順となります。
詳細は[作成に使用したノートブックの解説](#作成に使用したノートブックの解説)のそれぞれの記事で紹介します。

# 参考資料

[stockmark/ner-wikipedia-dataset](https://huggingface.co/datasets/stockmark/ner-wikipedia-dataset)