このシリーズでは、自然言語処理において主流であるTransformerを中心に、環境構築から学習の方法までまとめます。
今回の記事ではHuggingface Transformersによる日本語の要約タスクについて、学習から推論までの流れを紹介します。
Google colabを使用して、簡単に最新の自然言語処理モデルを実装することができますので、ぜひ最後までご覧ください。
今回の内容
・日本語の要約タスクに使用するデータセット
・日本語の要約タスクの学習
・日本語の要約タスクの推論
・要約文の定量的な評価方法(参考)
自然言語処理における要約タスクとは
自然言語処理における要約とは、重要な情報を保持しながらドキュメントや記事を短いテキストに要約するタスクのことを言います。
元の入力からテキストや文章を抽出して要約文を出力する抽出型モデルと、入力した文章から新しい文章を生成して要約を行う抽象型モデルに大別できます。
それぞれのメリット、デメリットをまとめると以下のようになります。
抽出型モデル | 抽象型モデル | |
---|---|---|
概要 | 元の入力からテキストや文章を抽出して要約文を出力する | 入力した文章から新しい文章を生成して要約を行う |
メリット | ・元の文章内の正しい内容が出力される | ・文章が自然で読みやすい ・要約の長さを制御しやすい |
デメリット | ・文章が不自然で読みにくい場合がある ・要約文の長さを制御しにくい | ・内容とは異なる文章が生成されることがある |
Transformerとは
概要
「Transformer」は2017年にGoogleが「Attention is all you need」で発表した深層学習モデルです。
現在では、自然言語処理に利用する深層学習モデルの主流になっています。
これまでの自然言語処理分野で多く使われていた「RNN」(Recurrent Neural Network)や「CNN」(Convolutional Neural Network)を利用せず、Attentionのみを用いたEncoder-Decoder型のモデルとなっています。
「Transformer」が登場して以降、多くの自然言語処理モデルが再構築され、過去を上回る成果を上げています。
最近では自然言語処理だけでなく、ViTやDETRなどといった画像認識にも応用されています。
詳細は以下の記事をご覧ください。
Huggingface Transformersとは
概要
「Hugging Face」とは米国のHugging Face社が提供している、自然言語処理に特化したディープラーニングのフレームワークです。
「Huggingface Transformers」は、先ほど紹介したTransformerを実装するためのフレームワークであり、「自然言語理解」と「自然言語生成」の最先端の汎用アーキテクチャ(BERT、GPT-2など)と、何千もの事前学習済みモデルを提供しています。
ソースコードは全てGitHub上で公開されており、誰でも無料で使うことができます。
事前学習済みモデル
Hugging Faceではタスクに応じた様々な事前学習済みモデルが提供されています。
こちらからご確認ください。
Google colabによる導入
ここからはGoogle colabを使用して実装していきます。
まずはGPUを使用できるように設定をします。
「ランタイムのタイプを変更」→「ハードウェアアクセラレータ」をGPUに変更
今回紹介するコードは以下のボタンからコピーして使用していただくことも可能です。
まずはGoogleドライブをマウントして、作業フォルダを作成します。
from google.colab import drive
drive.mount('/content/drive')
!mkdir -p '/content/drive/My Drive/huggingface_transformers_demo/'
%cd '/content/drive/My Drive/huggingface_transformers_demo/'
!git clone https://github.com/huggingface/transformers
%cd transformers
次に必要なライブラリをそれぞれインストールします。
!pip install -r ./examples/pytorch/summarization/requirements.txt
!pip install git+https://github.com/huggingface/transformers
!pip install datasets
日本語の要約タスクに使用するデータセット
まずは要約のデータセットを用意します。
「ThreeLineSummaryDataset」の「train.csv」にLivedoorニュースのIDのリストを使用して、データを収集します。
詳細はこちらのリンクよりご確認ください。
データの取得
まずはThreeLineSummaryDatasetをクローンします。
!git clone https://github.com/KodairaTomonori/ThreeLineSummaryDataset
次にスクレイピングより、Livedoorニュースの「3行要約」と「本文」を取得します。
サーバーに負荷をかけないように、10秒に1回だけ通信するようにしています。
from urllib.request import urlopen
from bs4 import BeautifulSoup
from bs4.element import NavigableString
from pprint import pprint
import time
# コンテンツの取得
def get_content(id):
time.sleep(10)
URL = 'https://news.livedoor.com/article/detail/'+id+'/'
print(URL)
try:
with urlopen(URL) as res:
output1 = ''
html = res.read().decode('euc_jp', 'ignore')
soup = BeautifulSoup(html, 'html.parser')
lineList = soup.select('.articleBody p')
for line in lineList:
if len(line.contents) > 0 and type(line.contents[0]) == NavigableString:
output1 += line.contents[0].strip()
if output1 == '':
return
output1 += '\n'
output0 = ''
summaryList = soup.select('.summaryList li')
for summary in summaryList:
output0 += summary.contents[0].strip()+'\t'
if output0 == '':
return
print(output0+output1)
with open('output_summary.csv', mode='a') as f:
f.writelines(output0+output1)
except Exception:
print('Exception')
idList = []
with open('ThreeLineSummaryDataset/data/train.csv', mode='r') as f:
lines = f.readlines()
for line in lines:
id = line.strip().split(',')[3].split('.')[0]
idList.append(id)
for i in range(0, 1000):
print('index:', i)
get_content(idList[i])
全てのデータ取得が終わったら、学習用と検証用データに分割します。
import os
import pandas as pd
df = pd.DataFrame(columns=['text', 'summary'])
with open('output_summary.csv') as f:
for line in f.readlines():
strs = line.split('\t')
df = df.append({'text':strs[3] , 'summary':strs[0]}, ignore_index=True)
df = df.sample(frac=1)
num = len(df)
df[:int(num*0.8)].to_csv('summary_train.csv', sep=',', index=False)
df[int(num*0.8):].to_csv('summary_val.csv', sep=',', index=False)
これにより「summary_train.csv」と「summary_val.csv」というファイルが出力されます。
日本語の要約タスクの学習
先ほど作成したデータセットを使用して、学習を進めましょう。
今回は事前学習モデルとして「sonoisa/t5-base-japanese」を使用します。
%%time
# ファインチューニングの実行
!python ./examples/pytorch/summarization/run_summarization.py \
--model_name_or_path=sonoisa/t5-base-japanese \
--do_train \
--do_eval \
--train_file=summary_train.csv \
--validation_file=summary_val.csv \
--num_train_epochs=10 \
--per_device_train_batch_size=4 \
--per_device_eval_batch_size=4 \
--save_steps=5000 \
--save_total_limit=3 \
--output_dir=summary_ja/ \
--predict_with_generate \
--use_fast_tokenizer=False \
--logging_steps=100
学習が終わると結果が「summary_ja」に保存されます。
日本語の要約タスクの推論
早速、学習の結果を使用して推論を行なってみましょう。
Livedoorニュースより、こちらから記事を引用して推論を実装します。
import torch
from transformers import pipeline, AutoTokenizer, AutoModelForSeq2SeqLM
model = AutoModelForSeq2SeqLM.from_pretrained('summary_ja/')
tokenizer = AutoTokenizer.from_pretrained('sonoisa/t5-base-japanese')
text = r"""
ほとんどのテレビ局が特番を組んで安倍晋三元首相の国葬を生放送で伝えるなか、ネット上では〝安定のテレビ東京〟の独自路線が称賛されている。 テレビ各局は国葬が始まる午後2時前から特番を組んで放送。そうした中でテレ東も「報道特番」なる番組を放送するが、これが1時40分からわずか5分だけの放送。同局のホームページには「安倍元総理の国葬直前の様子をお伝えします」とのみ案内が記されていた。実際の報道では「安倍元総理の遺骨 自宅を出発」というテロップが流される中、移動する車の様子や、国葬の会場の様子も伝えられた。国葬が行われている時間帯は何を放送するのか? 「報道特番」終了後の1時45分から3時40分まで「午後のロードショー」で、「ベートーベン」という、1992年に米国で製作されたコメディー映画を放送。HPには「ペット泥棒から逃げ出したセント・バーナードの子犬が、ニュートン家に迷い込む!?犬嫌いの父を説得して飼うことになるが、再びペット泥棒の魔の手が迫る…!」との説明が…。ここまで来ると〝お見事〟と思えるほど、国葬とは全く関係ない内容の映画だ。あくまで独自路線を貫くテレ東に対しては「テレ東はブレないな~」「いつもとかわらず 午後ローでコメディ映画を流すテレ東を応援しよう」「安定、不動の、テレビ東京! 大好きだぞ!」などのツイートが見られた。"""
inputs = tokenizer(text, return_tensors="pt", max_length=512,truncation=True)
outputs = model.generate(inputs["input_ids"], max_length=40, min_length=10,num_beams=4, early_stopping=True)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
実行すると、以下のような結果が表示されます。
「安定のテレビ東京」の独自路線が称賛されている
ニュース記事から、精度良く要約文を出力することができました。
要約文の定量的な評価方法(参考)
今回は算出は行いませんが、参考までに要約文の定量的な評価方法について紹介をします。
ROUGEスコア
ROUGE (Recall-Oriented Understudy for Gisting Evaluation) はスコアは要約のような高い再現率が求められるケースのために開発された指標です。
2004年に発表された論文で提案された指標ですが、現在も要約の論文ではほぼ必ず使われている指標となっています。
「要約システムが作成した要約 (=予測) 」と「人手で書かれた要約 (=正解) 」がどのくらい一致しているかを測定することで、定量的な評価を実現しています。
ROUGEの中にはいくつかの指標があり、以下のように分類されます。
指標 | 計算方法 |
ROUGE-1 | 「要約システムが作成した要約 (=予測) 」と「人手で書かれた要約 (=正解) 」の1-gram(単語)の共起を評価する。 |
ROUGE-2 | 「要約システムが作成した要約 (=予測) 」と「人手で書かれた要約 (=正解) 」の2-gramの共起を評価する。 |
ROUGE-L | 最長共通部分列(LCS) を評価する。1つの文ごとのスコアを計算し、平均をとる。 |
ROUGE-SUM | 最長共通部分列(LCS) を評価する。要約全体に対して計算する。 |
具体的な実装方法はこちらの記事をご覧ください。
まとめ
最後までご覧いただきありがとうございました。
今回の記事では日本語の要約タスクについて、学習から推論までの流れを紹介しました。
このシリーズでは、自然言語処理全般に関するより詳細な実装や学習の方法を紹介しておりますので、是非ご覧ください。