このシリーズでは、自然言語処理において主流であるTransformerを中心に、環境構築から学習の方法までまとめます。
今回の記事ではHuggingface Transformersの入門として、分類モデル学習のためのデータセット作成方法を紹介します。
Google colabを使用して、簡単に最新の自然言語処理モデルを実装することができますので、ぜひ最後までご覧ください。
【前回】
今回の内容
・Huggingface Transformersとは
・学習データの準備方法
・データセットの構成を確認する
・公開データにラベル付けをする
Huggingface Transformersとは
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上で公開されており、誰でも無料で使うことができます。
学習データの準備方法
文章分類モデルの作成のためのデータセット作成には、下記のような方法があります。
Huggingface Transformers datasetsを使用する
Huggingface Transformersでは自然言語処理に関する言語のデータセットを提供しています。
huggingface datasetsというライブラリ を使用することで、公開されているものを活用することで、すぐに学習を実装することができます。
まずはここで学習させたいデータセットがないか、確認してみましょう。
このライブラリの詳細は以下の記事をご覧ください。
公開されているデータセットを使用
huggingface datasets 以外にも公開されているデータセットがあります。
文章分類問題で有名なデータセットとして、livedoor ニュース記事のデータセットがあります。
(livedoor ニュースコーパス(https://www.rondhuit.com/download.html)より引用)
この記事の後半では、このデータセットを加工する方法を紹介します。
自分で作成する
公開されているデータセットがない場合は、自分で作成することになります。
この記事の後半では、自分で作成する方法にも触れます。
データセットの構成を確認する
huggingface datasets からデータセットをダウンロード
データセットの構成を確認するため、datasetsにあるデータセットをダウンロードして中身を見てみることにします。
まずはライブラリをインストールします。
!pip install transformers datasets
次に公開されているデータセットをダウンロードします。
今回使用するデータセットはこちらのものになります。
from datasets import load_dataset
dataset_org = load_dataset("tyqiangz/multilingual-sentiments", "japanese")
データセットの内容を表示する
データセットの中身を表示してみます。
dataset_org
実行すると以下のように表示されます。
DatasetDict({
train: Dataset({
features: ['text', 'source', 'label'],
num_rows: 120000
})
validation: Dataset({
features: ['text', 'source', 'label'],
num_rows: 3000
})
test: Dataset({
features: ['text', 'source', 'label'],
num_rows: 3000
})
})
学習データが120000件、検証データとテストデータが3000件のデータセットであることがわかりました。
内容を確認するため、ダウンロードしたデータセットをpandas形式に変換します。
dataset_org.set_format(type="pandas")
dataset_org["train"][:]
index | text | source | label |
---|---|---|---|
0 | 普段使いとバイクに乗るときのブーツ兼用として購入しました。見た目や履き心地は良いです。 しかし、2ヶ月履いたらゴム底が削れて無くなりました。また、バイクのシフトペダルとの摩擦で表皮が剥がれ、本革でないことが露呈しました。ちなみに防水とも書いていますが、雨の日は内部に水が染みます。 安くて見た目も良く、履きやすかったのですが、耐久性のなさ、本革でも防水でも無かったことが残念です。結局、本革の防水ブーツを買い直しました。 | amazon_reviews_multi | 2 |
1 | 十分な在庫を用意できない販売元も悪いですが、Amazonやら楽⚪︎が転売を認めちゃってるのが結果的に転売の後押しになっちゃってるんだよなぁ… Amazonもここぞとばかりに抱き合わせ販売しまくるし… それを恥ずかしいと思えなくなったら動物と同じですよ、最大手さん。 | amazon_reviews_multi | 2 |
2 | 見た目はかなりおしゃれで気に入りました。2、3回持ち歩いた後いつも通りゼンマイを巻いていたら突然空回り。 針の調整はできるけど、つまみをあげても下げてもゼンマイを巻くことができず。 時計屋に持って行って中を開けてもらったら、中のケースと外側の規格がそもそも合っていないため、固定されず、一度ズレると噛み合わなくなるんだそう。 返品して交換した方がいいと言われましたが、保証書付いてないし、 クーリングオフ期間もとっくに過ぎています。 アンティーク感覚で家で放置するならおススメですが、 本来の用途としては全く使えません。 ご注意を。 | amazon_reviews_multi | 2 |
3 | よくある部分での断線はしませんでした ただiphoneとの接続部で接触不良、折れました iphoneの中に残されてしまい摘出に苦労しました | amazon_reviews_multi | 2 |
4 | プラモデルの塗装剥離に使う為に購入 届いて早速使ってみた 結果 1ヶ月経っても未だに剥離出来ない 何じゃこら! | amazon_reviews_multi | 2 |
huggingface datasetsからダウンロードしたデータはラベル付けがされており、すぐに分類問題の学習ができることがわかります。
データセットをCSVファイルとして出力する
先ほどpandas形式に変換したデータをCSV形式で出力することができます。
dataset_org["train"][:].to_csv("train.csv", index=None)
dataset_org["validation"][:].to_csv("validation.csv", index=None)
dataset_org["test"][:].to_csv("test.csv", index=None)
公開データにラベル付けをする
公開されているデータセットの中には、学習するために自分でラベル付けの処理を行う必要があるものがあります。
ここでは、livedoor ニュース記事のデータセットを例に紹介します。
(livedoor ニュースコーパス(https://www.rondhuit.com/download.html)より引用)
まずはダウンロードします。
# livedoorニュースコーパスのダウンロード
!wget https://www.rondhuit.com/download/ldcc-20140209.tar.gz
!tar zxvf ldcc-20140209.tar.gz
「./text」にカテゴリごとにフォルダ分けされたニュースデータが保存されます。
各テキストファイルを読み込んで、タイトルのみを抽出する関数を定義します。
import os
import pandas as pd
# タイトルリストの取得
def get_title_list(path):
title_list = []
filenames = os.listdir(path)
for filename in filenames:
# ファイルの読み込み
with open(path+filename) as f:
title = f.readlines()[2].strip()
title_list.append(title)
return title_list
次にこの関数を、各ジャンルごとに分類されているニュース記事のフォルダに対して実行していきます。
まずは空のDataFrameを作成します。
# データセットの生成(各ニュース記事のタイトルを取得)
df = pd.DataFrame(columns=['label', 'sentence'])
次に「dokujo-tsushin(独女)」のタイトルを読み込み、ラベルとして「0」を割り当て、DataFrameに順番に追加していきます。
それ以降、それぞれのジャンルにも同様の処理を行います。
#0
title_list = get_title_list('text/dokujo-tsushin/')
for title in title_list:
df = df.append({'label':0 , 'sentence':title}, ignore_index=True)
#1
title_list = get_title_list('text/it-life-hack/')
for title in title_list:
df = df.append({'label':1 , 'sentence':title}, ignore_index=True)
#2
title_list = get_title_list('text/sports-watch/')
for title in title_list:
df = df.append({'label':2 , 'sentence':title}, ignore_index=True)
#3
title_list = get_title_list('text/kaden-channel/')
for title in title_list:
df = df.append({'label':3 , 'sentence':title}, ignore_index=True)
#4
title_list = get_title_list('text/livedoor-homme/')
for title in title_list:
df = df.append({'label':4 , 'sentence':title}, ignore_index=True)
#5
title_list = get_title_list('text/movie-enter/')
for title in title_list:
df = df.append({'label':5 , 'sentence':title}, ignore_index=True)
#6
title_list = get_title_list('text/peachy/')
for title in title_list:
df = df.append({'label':6 , 'sentence':title}, ignore_index=True)
#7
title_list = get_title_list('text/smax/')
for title in title_list:
df = df.append({'label':7 , 'sentence':title}, ignore_index=True)
#8
title_list = get_title_list('text/topic-news/')
for title in title_list:
df = df.append({'label':8 , 'sentence':title}, ignore_index=True)
全てのニュース記事の追加が終わったら、最後にデータの順番をシャッフルします。
# データをシャッフルする
df = df.sample(frac=1)
結果を出力すると以下のよう表示されます。
index | label | sentence |
---|---|---|
6940 | 8 | 人気ゲーム「探検ドリランド」に不正利用…GREEの対応に疑問の声 |
419 | 0 | 食と生活を見直して、旬の女になろう! |
7118 | 8 | 和田アキ子が板野友美に「挨拶せんかい!」と激怒、携帯真っ二つに「やりすぎ」の声 |
2009 | 2 | 【Sports Watch】引退を表明した坂田、亀田一家に“もういいかげんにしてくれ” |
2506 | 2 | ヤクルト・宮本慎也、巨人・坂本との合同トレに「賛否両論あったみたいですけど……」 |
5374 | 6 | 香里奈に続け!モデル小林優美が女優デビュー |
404 | 0 | 独女の母たちの叫び |
1470 | 1 | どこよりも詳しく解説!写真でみる世界最軽量Ultrabook、NEC「LaVie Z」 |
3055 | 3 | ガソリンスタンドでの電気自動車の充電サービスが有料化へ − 1月から【話題】 |
7235 | 8 | SKE48 平松可奈子が、胸を強調した画像を「誤爆」 |
5071 | 6 | 加藤夏希、マリエによる“おんなのこ革命。” 神戸コレクション ′10S/S |
3297 | 3 | ホワイトボードは大きなタッチスクリーン、しかもUSBバスパワー!—パナソニック電子黒板「エリート パナボード」【売れ筋チェック】 |
1535 | 1 | スマホ&ケータイ、デジカメ&携帯ゲーム機で!色んなSDカードを一挙解説! |
2803 | 3 | 【話題】タイ洪水被害でパソコン、デジタルカメラ生産に影響 |
4525 | 5 | 今夏、新生“G.I.ジョー”が日本に上陸する |
元のニュースデータに、ラベル付けをすることができました。
これは、huggingface datasetsからダウンロードしたデータと同じ形式になっていることがわかります。
このデータもCSVファイルとして出力することができます。
# 上記で取得したデータを学習用、検証用、テスト用に分割する
num = len(df)
df[:int(num*0.7)].to_csv('./text/news_train.csv', sep=',', index=False)
df[int(num*0.7):int(num*0.9)].to_csv('./text/news_val.csv', sep=',', index=False)
df[int(num*0.9):].to_csv('./text/news_test.csv', sep=',', index=False)
まとめ
最後までご覧いただきありがとうございました。
今回の記事ではHuggingface Transformersの入門として、分類モデル学習のためのデータセット作成方法を紹介しました。
次回は今回作成したデータセットをもとに、学習の実装を紹介します。
是非ご覧ください。