from sklearn.model_selection import train_test_split
from tensorflow.keras.callbacks import EarlyStopping
from transformers import BertJapaneseTokenizer
from models import build_model
from preprocessing import convert_examples_to_features, Vocab
from utils import load_dataset, evaluate
defmain():
# Set hyper-parameters.
batch_size = 32
epochs = 100
model_path = 'models/'
pretrained_model_name_or_path = 'bert-base-japanese-whole-word-masking'
maxlen = 250# Data loading.
x, y = load_dataset('./data/entail_evaluation_set.txt')
tokenizer = BertJapaneseTokenizer.from_pretrained(pretrained_model_name_or_path)
# Pre-processing.
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)
target_vocab = Vocab().fit(y_train)
features_train, labels_train = convert_examples_to_features(
x_train,
y_train,
target_vocab,
max_seq_length=maxlen,
tokenizer=tokenizer
)
features_test, labels_test = convert_examples_to_features(
x_test,
y_test,
target_vocab,
max_seq_length=maxlen,
tokenizer=tokenizer
)
# Build model.
model = build_model(pretrained_model_name_or_path, target_vocab.size)
model.compile(optimizer='sgd', loss='sparse_categorical_crossentropy')
# Preparing callbacks.
callbacks = [
EarlyStopping(patience=3),
]
# Train the model.
model.fit(x=features_train,
y=labels_train,
batch_size=batch_size,
epochs=epochs,
validation_split=0.1,
callbacks=callbacks)
model.save_pretrained(model_path)
# Evaluation.
evaluate(model, target_vocab, features_test, labels_test)
if __name__ == '__main__':
main()
コードを書き終えたら実行してみましょう。BERTは大きなモデルなのでCPU上で実行するととても時間がかかります。できればGPU上で実行させることをおすすめします。参考までにGPU(NVIDIA Tesla V100)上で学習させたところ、1エポックに30程度かかり、全体としては200秒程度かかりました。性能としては正解率で0.6485という結果になりました。
オープンドメインの情報抽出は、この10年ほどで盛んになってきた自然言語処理の一分野でOpenIE(Open Information Extraction)と呼ばれている。OpenIEでは、ドメインを限定しないテキストからタプルを抽出する。たとえば、「ホンダは本田宗一郎によって創業された」という文であれば (ホンダ; 創業された; 本田宗一郎) というタプルを抽出する。抽出したタプルは知識グラフの構築や質問応答等での有用性が示されている。とりわけ、知識グラフはGartnerのハイプ・サイクル2019年版で取り上げられていることから窺えるように、今後重要な技術となるので、その要素技術としてのOpenIEを知っておく価値はある。
本記事では、教師あり学習を使ったOpenIEの手法を紹介する。紹介する手法はNAACL 2018に提出された論文「Supervised Open Information Extraction」で提案された方法である。これまでのOpenIEでは、限られた教師データしか存在しなかったために、半教師あり学習やルールベースのアプローチが主に使われてきた。この論文では、質問応答のデータセットを変換してOpenIEのデータセットを作成し、OpenIEを系列ラベリングとして定式化して解いている。実験の結果、高性能でありつつ、予測速度に優れている点を示した。AllenNLPで実装が公開されており、以下のWebページから体験できる。
この論文ではOpenIEを以下の図で表されるような系列ラベリングの問題として解いている。系列ラベリングとして解くためにスキーマに工夫をしている。スキーマは系列ラベリングで使われるIOB2であるが、述語(predicate)をP、項(argument)をAとして表現している。項にはポジションが付いており、このポジションがタプル内での項の順番を表している。以下の図でいうと、A0として「Obama」、Pとして「was born」、A1として「in America」が取れるので(Obama; was born; in America)というタプルが得られる。
OpenIEを学習するための教師データが限られているのは先に述べた通りだが、この論文では既存のデータセットを拡張するために質問応答のデータセットを変換してOpenIEの教師データを作成している。質問応答のデータセットとしてはQAMR(Question Answer Meaning Representation)を用いている。たとえば、以下の図の場合、質問文に含まれる「What」を回答である「mercury filling」で置き換えることでOpenIEのデータセットを得ている。このような変換自体は新しいアイデアではなく、先行研究がある。