企業名の辞書「JCLdic」を使ってテキストから企業名を抽出する API を作りました with Docker
JCLdicとは
TIS株式会社が公開した企業名の辞書で、国税庁に登録されている法人情報を元に生成されています。
「TIS」「ティアイエス」「テイアイエス」などの表記揺れを考慮して認識できるようです。
参照:TIS、自然言語処理で企業名認識を行うための辞書「JCLdic」を無償公開
CSVとMeCabの辞書形式それぞれで以下3つの辞書が公開されています。
- JCL-slim
- ふりがななし
- 余分な英語なし
- デジタル名なし
- 2文字以上30文字以下の社名
- JCL-medium
- デジタル名なし
- 2文字以上30文字以下の社名
- JCL-full
こちらが各辞書ごとのユニークな企業名の数です。
Single Lexicon | Total Names | Unique Company Names |
---|---|---|
JCL-slim | 7067216 | 7067216 |
JCL-medium | 7555163 | 7555163 |
JCL-full | 8491326 | 8491326 |
IPAdic | 392126 | 16596 |
Juman | 751185 | 9598 |
NEologd | 3171530 | 244213 |
Multiple Lexicon | ||
IPAdic-NEologd | 4615340 | 257246 |
IPAdic-NEologd-JCL(medium) | 12093988 | 7722861 |
参照:Japanese Company Lexicon (JCLdic)
注意:ユニークな企業数ではありません。
2019年12月27日までのデータを使用して作成されていますが、辞書を作成した手順とコードが公開されているため最新のデータを含めて再作成可能です。
今回はJCL-slimとIPAdic-NEologdを使用しています。
作ったもの
投げられたテキストから企業名を抽出、名寄せされた企業名を返すAPIを作りました。
Docker Composeで動くようにしたので気軽に試していただければと思います。
curl -X "GET" "http://0.0.0.0:8000/company-extraction" --data-urlencode "s=TIS株式会社は自然言語処理で企業名認識を行うための辞書JCLdic(日本会社名辞書)を無償公開。"
{
"companies":[
{
"name":"TIS株式会社",
"extract_name":"TIS株式会社"
},
{
"name":"株式会社JCL",
"extract_name":"JCL"
}
],
"s":"TIS株式会社は自然言語処理で企業名認識を行うための辞書JCLdic(日本会社名辞書)を無償公開。"
}
注意:JCL
が意図せず企業名として検出されています。
試してみる
1. 準備
git clone https://github.com/Doarakko/japanese-company-extraction
cd japanese-company-extraction
2. 起動
docker-compose up --build
3. Go
curl -X "GET" "http://0.0.0.0:8000/company-extraction" --data-urlencode "s=<text>"
Hints
辞書の中身を見てみる
JCL-slim
import polars as pl
pl.Config.set_fmt_str_lengths(100)
columns = ["name", "id_0", "id_1", "cost", "part_of_speech", "detail_part_of_speech", "category", "temp_0", "temp_1", "temp_2", "normalized_name", "katakana_0", "katakana_1"]
slim_df = pl.read_csv("jcl_slim_mecab.csv", has_header=False, new_columns=columns)
slim_df.select(pl.col(columns).where(pl.col("name").str.contains("gmo"))).head()
name | id_0 | id_1 | cost | part_of_speech | detail_part_of_speech | category | temp_0 | temp_1 | temp_2 | normalized_name | katakana_0 | katakana_1 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
hugmo | 1292 | 1292 | 4000 | 名詞 | 固有名詞 | 組織 | * | * | * | 株式会社hugmo | * | * |
株式会社hugmo | 1292 | 1292 | 4000 | 名詞 | 固有名詞 | 組織 | * | * | * | 株式会社hugmo | * | * |
株式会社digitalbigmo | 1292 | 1292 | 4000 | 名詞 | 固有名詞 | 組織 | * | * | * | 株式会社digitalbigmo | * | * |
digitalbigmo | 1292 | 1292 | 4000 | 名詞 | 固有名詞 | 組織 | * | * | * | 株式会社digitalbigmo | * | * |
mogmog | 1292 | 1292 | 4000 | 名詞 | 固有名詞 | 組織 | * | * | * | 株式会社mogmog | * | * |
一部カラムのユニーク数を見てみます。
slim_df.select(
[
pl.col("name").n_unique().alias("unique_name_count"),
pl.col("normalized_name").n_unique().alias("unique_normalized_name_count"),
pl.col("cost").n_unique().alias("unique_cost_count"),
]
)
unique_name_count | unique_normalized_name_count | unique_cost_count |
---|---|---|
7064800 | 2940350 | 1 |
cost
はすべて 4000
、1社あたり約2個の企業名が登録されていることがわかります。
unique_name_count
がこちらに記載の企業数(7067216)と一致していませんが、辞書を使いやすくするために一部のデータを削除しているようです。
Considering the trade-off between dictionary size and searching performance, we delete zenkaku(全角) names and only preserve the hankaku(半角) names.
JCL-medium
medium_df = pl.read_csv("jcl_medium_mecab.csv", has_header=False, new_columns=columns)
medium_df.select(pl.col(["name", "normalized_name"]).where(pl.col("normalized_name").str.contains("gmo"))).head()
name | normalized_name |
---|---|
株式会社hugmo | 株式会社hugmo |
hugmo | 株式会社hugmo |
ハグモー | 株式会社hugmo |
株式会社digitalbigmo | 株式会社digitalbigmo |
digitalbigmo | 株式会社digitalbigmo |
JCL-slimと比較するとふりがな(ハグモー
)が追加されていますね。
JCL-full
full_df = pl.read_csv("drive/MyDrive/jcl_full_mecab_backup.csv", has_header=False, new_columns=columns)
full_df.select(pl.col(["name", "normalized_name"]).where(pl.col("name").str.lengths() == 1)).head()
name | normalized_name |
---|---|
F | F株式会社 |
R | 株式会社R |
k | 株式会社k |
Z | 有限会社Z |
W | 株式会社W |
JCL-fullの場合1文字のエイリアスや数字なども登録されているため、JCL-mediumまたはJCL-slimの使用が推奨されています。
The full version contains all kinds of names, including digits, one character aliases, etc. These abnormal names will cause annotation error for NER task. We recommend use the JCL_medium version or JCL_slim version.
使用する辞書を変更する
ファイルURLとファイル名を変更。
WORKDIR /usr/local/lib/mecab/dic/user_dict
RUN wget https://s3-ap-northeast-1.amazonaws.com/chakki.jcl.jp/public/jcl_slim_mecab.dic.zip
RUN unzip jcl_slim_mecab.dic.zip
userdic
の指定先をapp/Dockerfile
で変更したファイル名に。
;dicdir = /usr/local/lib/mecab/dic/ipadic
dicdir = /usr/local/lib/mecab/dic/mecab-ipadic-neologd
;dicdir = /usr/local/lib/mecab/dic/jumandic
;dicdir = /usr/local/lib/mecab/dic/unidic
userdic = /usr/local/lib/mecab/dic/user_dict/jcl_slim_mecab.dic
; output-format-type = wakati
; input-buffer-size = 8192
; node-format = %mn
; bos-format = %Sn
; eos-format = EOSn
おわりに
こういった辞書を企業がOSSとして公開してくれているのはありがたいですね。
ただ本記事冒頭の例にもありますが、カバー範囲が広い分意図せず企業名として検出されてしまうケースが多く発生しそうです。
また大文字・小文字の違いなどにより、このようなケースも発生します。
curl -X "GET" "http://0.0.0.0:8000/company-extraction" --data-urlencode "s=line financial株式会社"
{
"companies":[
{
"name":"株式会社line",
"extract_name":"line"
}
],
"s":"line financial"
}
企業名の名寄せの大変さが少しわかったところで私は撤退したいと思います。
ありがとうございました。
Discussion