🏢

企業名の辞書「JCLdic」を使ってテキストから企業名を抽出する API を作りました with Docker

2023/01/30に公開

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.

使用する辞書を変更する

app/Dockerfile

ファイル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

app/mecabrc

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