最近、感情分析(Sentiment Analysis)は自然言語処理の重要な分野の1つです。本記事では、Hugging Face Transformerと東北大学の日本語用BERTを使用して、日本語テキストの感情分析を行う手法について解説します。
必要なパッケージのインストール
まず、Hugging FaceのTransformersおよびDatasetsパッケージをインストールします。これらのパッケージは、モデルのダウンロードやデータセットの処理などを行います。
! pip install transformers datasets
また、東北大学の日本語用BERT使用に必要なパッケージもインストールします。
! pip install fugashi ipadic
その他、Matplotlibで日本語フォントを使用できるように設定します。
!apt-get -y install fonts-ipafont-gothic
!rm /root/.cache/matplotlib/fontlist-v330.json
※ ここでランタイムを再起動してください。
ライブラリのインポートとデータの準備
次に、必要なライブラリをインポートします。また、GitHubからWRIMEデータをダウンロードし、PandasのDataFrameとして読み込みます。
# ライブラリのインポート
import numpy as np
import pandas as pd
from transformers import AutoTokenizer, AutoModelForSequenceClassification, TrainingArguments, Trainer
from datasets import Dataset, load_metric
import japanize_matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
# GitHubよりWRIMEデータをダウンロードする
! wget https://github.com/ids-cv/wrime/raw/master/wrime-ver1.tsv
# pandas.DataFrameとして読み込む
df_wrime = pd.read_table('wrime-ver1.tsv')
このようにして、Hugging Face Transformerと東北大学の日本語用BERTを使用して感情分析を行うための準備を行います。
データの前処理
データを読み込んだ後、Plutchikの8つの基本感情を扱うために準備を行います。感情の強度が低いサンプルは除外し、トレーニングとテスト用のデータを分割します。
# Plutchikの8つの基本感情
emotion_names = ['Joy', 'Sadness', 'Anticipation', 'Surprise', 'Anger', 'Fear', 'Disgust', 'Trust']
emotion_names_jp = ['喜び', '悲しみ', '期待', '驚き', '怒り', '恐れ', '嫌悪', '信頼']
num_labels = len(emotion_names)
# readers_emotion_intensities 列を生成する
df_wrime['readers_emotion_intensities'] = df_wrime.apply(lambda x: [x['Avg. Readers_' + name] for name in emotion_names], axis=1)
# 感情強度が低いサンプルは除外する
is_target = df_wrime['readers_emotion_intensities'].map(lambda x: max(x) >= 2)
df_wrime_target = df_wrime[is_target]
# train / test に分割する
df_groups = df_wrime_target.groupby('Train/Dev/Test')
df_train = df_groups.get_group('train')
df_test = pd.concat([df_groups.get_group('dev'), df_groups.get_group('test')])
print('train :', len(df_train))
print('test :', len(df_test))
次に、感情分析に使用するモデルの指定とTokenizerの読み込みを行います。
# 使用するモデルを指定して、Tokenizerを読み込む
checkpoint = 'cl-tohoku/bert-base-japanese-whole-word-masking'
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
以上がデータの前処理および準備です。次に、データをTransformers用のフォーマットに変換し、分類モデルのトレーニングを行います。その後、感情分析の実行と結果の可視化を行います。
データの前処理とTransformers用のデータへの変換
データをTransformers用のフォーマットに変換するために、トークン化(Tokenization)と前処理を行います。
# 前処理関数: tokenize_function
# 感情強度の正規化(総和=1)も同時に実施する
def tokenize_function(batch):
tokenized_batch = tokenizer(batch['Sentence'], truncation=True, padding='max_length')
tokenized_batch['labels'] = [x / np.sum(x) for x in batch['readers_emotion_intensities']] # 総和=1に正規化
return tokenized_batch
# Transformers用のデータセット形式に変換
target_columns = ['Sentence', 'readers_emotion_intensities']
train_dataset = Dataset.from_pandas(df_train[target_columns])
test_dataset = Dataset.from_pandas(df_test[target_columns])
# 前処理(tokenize_function)を適用
train_tokenized_dataset = train_dataset.map(tokenize_function, batched=True)
test_tokenized_dataset = test_dataset.map(tokenize_function, batched=True)
ここでは、データセットをTransformerモデルに入力できる形式に変換しています。データのトークン化やラベルの正規化を行い、準備が整いました。
分類モデルのトレーニング
これから、トレーニングとテストを行います。まず、Sequence Classification用のモデルを準備し、トレーニングを実行します。
# 分類モデルのため AutoModelForSequenceClassification を使用する
model = AutoModelForSequenceClassification.from_pretrained(checkpoint, num_labels=num_labels)
# 評価指標を定義
metric = load_metric("accuracy")
def compute_metrics(eval_pred):
logits, labels = eval_pred
predictions = np.argmax(logits, axis=-1)
label_ids = np.argmax(labels, axis=-1)
return metric.compute(predictions=predictions, references=label_ids)
# 訓練時の設定
training_args = TrainingArguments(
output_dir="test_trainer",
per_device_train_batch_size=8,
num_train_epochs=1.0,
evaluation_strategy="steps", eval_steps=200) # 200ステップ毎にテストデータで評価する
# Trainerを生成
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_tokenized_dataset,
eval_dataset=test_tokenized_dataset,
compute_metrics=compute_metrics,
)
# 訓練を実行
trainer.train()
この部分では、モデルのトレーニング設定を行い、訓練を実行します。
モデルの評価
トレーニングを行った後、感情分析の評価を行います。
# 感情分析のテストを行う
def analyze_emotion(text, show_fig=False, ret_prob=False):
# 推論モードを有効か
model.eval()
# 入力データ変換 + 推論
tokens = tokenizer(text, truncation=True, return_tensors="pt")
tokens.to(model.device)
preds = model(**tokens)
prob = np_softmax(preds.logits.cpu().detach().numpy()[0])
out_dict = {n: p for n, p in zip(emotion_names_jp, prob)}
# 棒グラフを描画
if show_fig:
plt.figure(figsize=(8, 3))
df = pd.DataFrame(out_dict.items(), columns=['name', 'prob'])
sns.barplot(x='name', y='prob', data=df)
plt.title('入力文 : ' + text, fontsize=15)
if ret_prob:
return out_dict
# 動作確認
analyze_emotion('今日から長期休暇だぁーーー!!!', show_fig=True)
analyze_emotion('今日は仕事が忙しい・・・', show_fig=True)
analyze_emotion('あぁー、イライラするっ!!', show_fig=True)
まとめ
- データの前処理と準備:
- データセットの読み込みと、トレーニング・テストデータへの分割が行われました。
- Hugging Face Transformersライブラリを使用して、日本語の感情分析モデル作成に必要なデータセットを整形しました。
- データのトークン化やラベルの正規化(総和が1になるように変換)を行い、Transformersライブラリで扱える形式に整えました。
- 分類モデルのトレーニングと評価:
- Hugging Face Transformersの
AutoModelForSequenceClassification
を使用して、感情分類モデルを定義しました。 - トレーニングとテストデータを用いて、モデルのトレーニングと評価が行われました。
- 評価には、精度などの評価指標を用いて、モデルの性能評価を行いました。
- Hugging Face Transformersの
- 感情分析の実行:
- 実際の文章を使って、作成した感情分析モデルが感情を予測する様子を確認しました。
- 文章の感情を予測するための関数を定義し、モデルにテキストを与えることで、文章の感情を抽出することができました。
- モデルの応用と検討:
- 感情分析モデルは、テキストや文章から感情を抽出するための強力なツールです。
- 応用範囲は広く、ソーシャルメディアの感情分析、製品レビューの評価、顧客の感情分析など、多岐にわたります。
感情分析モデルの作成は、言語処理分野で重要な課題です。適切なデータの前処理、モデルのトレーニングと評価、そして実際の文章への適用といったプロセスを通じて、モデルの性能向上や応用範囲の拡大に取り組んでいます。
コメント