ナード戦隊データマン

データサイエンスを用いて悪と戦うぞ

固有表現抽出ツールanagoの訓練データを京都ウェブ文書リードコーパスから用意する

前回( https://qiita.com/sugiyamath/items/365b263d4f03d3bca26f ), Hironsanのgithubのツール「anago」を試しましたが、十分なデータの用意ができませんでした。今回は、KWDLCから入力形式のデータを生成します。

形式のルール

  1. 単語とラベルをタブでつなぐ。
  2. 一文ごとに改行だけの行を挿入する。
  3. ラベルは"IOBタグ-分類(英大文字3字)"。

データの置き場所

データは以下のURLからダウンロードします。 http://nlp.ist.i.kyoto-u.ac.jp/nl-resource/KWDLC/download_kwdlc.cgi

このデータを展開し、形式的にnltk_data/corpora/kwdlcに置きます。

コード

import nltk,re
from nltk.corpus.reader.util import *
from nltk.corpus.util import LazyCorpusLoader

root = nltk.data.find('corpora/kwdlc/dat/rel')
fileids = [f for f in find_corpus_fileids(FileSystemPathPointer(root), ".*")
               if re.search(r".+-.+", f)]
data = ""

for fileid in fileids:

    with open(root+"/" + fileid, "r") as file:
        data = data + file.read()

data_spl = data.split("\n")

regexp0 = re.compile(r"^#")
regexp1 = re.compile(r"^([^ ]+) [^ ]+ [^ ]+ [^ ]+ [^ ]+ [^ ]+ [^ ]+$")
regexp2 = re.compile(r".*ne type=\"([A-Z]+)\" target=\"(.+)\".*")

data_fmt = []
for d in data_spl:
    if regexp0.search(d):
        continue
    if regexp1.search(d):
        data_fmt.append(re.sub(regexp1, r"\1", d))
    if regexp2.search(d):
        data_fmt.append(re.sub(regexp2, r"NE:\1:\2", d))


def fill_array(size, it):
    out = []
    for i in range(size):
        out.append(it)
    return out

outs = []
labels = fill_array(len(data_fmt), None)

for i,d in enumerate(data_fmt):
    regexp3 = re.compile("NE:([A-Z]+):(.+)")
    if regexp3.search(d):
        rs = d.split(":")
        tmp_bools = []

        counter = i
        while(counter > 0):
            counter = counter - 1
            if data_fmt[counter] in rs[2]:
                tmp_bools.append(counter)
            else:
                break

        counter = i
        while(counter < len(data_fmt)):
            counter = counter + 1
            if data_fmt[counter] in rs[2]:
                tmp_bools.append(counter)
            else:
                break

        tmp_bools.sort()
        first_flag = True
        for b in tmp_bools:
            if first_flag:
                labels[b] = "B-" + rs[1][:3]
                first_flag = False
            else:
                labels[b] = "I-" + rs[1][:3]
        outs.append(None)
    else:
        outs.append(d)

with open("kwdlc.txt", "w") as file:
    for i, d in enumerate(outs):
        regexp4 = re.compile("。")
        if d is not None:
            if labels[i] is None:
                if regexp4.search(d):
                    file.write(d + "\t" + "O" + "\n")
                else:
                    file.write(d + "\t" + "O")
            else:
                file.write(d + "\t" + labels[i])
            file.write("\n")