BERTで日本語文章をゼロショット分類してみる
ラベル付きデータが用意できない。というケースは、実業務でも良く出会います。
そこで、BERTのような言語モデルが、マスクされたトークンを予測するための事前学習がなされていることを応用して、文書分類を試してみます。
この記事は、以下のオライリー本の「9章 ラベルのないまたは少ない状況への対応方法」の内容を、日本語でも実施できるように試したものです。
まず関連モジュールをinstall
!pip install transformers
!pip install fugashi
!pip install ipadic
BERT_MODELは、日本語対応したモデルを用意
from transformers import pipeline
BERT_MODEL = "cl-tohoku/bert-base-japanese"
マスク言語モデル版
pipe_fill = pipeline("fill-mask", model=BERT_MODEL)
そして、カテゴリ分類を実行してみます
desc = "大きいタスクは小さなタスク達に分割して処理していくのがコツらしいさて、今週はどのタスクをやっていこうかな? "
prompt = "この文章は [MASK] について言及する文章です。"
output = pipe_fill(desc + prompt)
for element in output:
print(f"Token {element['token_str']}:\t{element['score']:.3f}%")
結果がでました。確かにタスクのことが書かれている文章なので、良さそうです。
しかし、私が分類したいラベルとは異なるので、最初にラベルの種類を指定してみます。
desc = "大きいタスクは小さなタスク達に分割して処理していくのがコツらしいさて、今週はどのタスクをやっていこうかな? "
prompt = "この文章は [MASK] についての文章です。"
output = pipe_fill(desc + prompt, targets=["仕事", "娯楽", "運動"])
for element in output:
print(f"Token {element['token_str']}:\t{element['score']:.3f}%")
あまりうまくいかないようです。
NLI版
上記では、マスク言語モデルを直接分類に使用できるように、マスク付きのプロンプトを設定しましたが、よりテキスト分類に近いタスクである自然言語推論(natural language inference:NLI)でファインチューニングされたモデルを適応させてみます。
Transformers には、ゼロショット分類のための MNLI モデルが内蔵されています。
from transformers import pipeline
BERT_MODEL = "cl-tohoku/bert-base-japanese"
pipe_classification = pipeline("zero-shot-classification", model=BERT_MODEL, device=0)
output = pipe_classification(texts, labels, multi_label=True)
# print(output)
for label, score in zip(output[0]["labels"], output[0]["scores"]):
print(f"{label}, {score:.2f}")
今度は前回よりもうまくいきました。
正確な精度は実運用時に要検証であり、ブラックボックス感がある分類方法ですが、導入する現場の状況によっては使えるかもしれません。