Hugging Face Transformerと日本語用BERTを使用して簡単な感情分析を行う方法!

python
スポンサーリンク

最近、感情分析(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)

まとめ

  1. データの前処理と準備:
    • データセットの読み込みと、トレーニング・テストデータへの分割が行われました。
    • Hugging Face Transformersライブラリを使用して、日本語の感情分析モデル作成に必要なデータセットを整形しました。
    • データのトークン化やラベルの正規化(総和が1になるように変換)を行い、Transformersライブラリで扱える形式に整えました。
  2. 分類モデルのトレーニングと評価:
    • Hugging Face TransformersのAutoModelForSequenceClassificationを使用して、感情分類モデルを定義しました。
    • トレーニングとテストデータを用いて、モデルのトレーニングと評価が行われました。
    • 評価には、精度などの評価指標を用いて、モデルの性能評価を行いました。
  3. 感情分析の実行:
    • 実際の文章を使って、作成した感情分析モデルが感情を予測する様子を確認しました。
    • 文章の感情を予測するための関数を定義し、モデルにテキストを与えることで、文章の感情を抽出することができました。
  4. モデルの応用と検討:
    • 感情分析モデルは、テキストや文章から感情を抽出するための強力なツールです。
    • 応用範囲は広く、ソーシャルメディアの感情分析、製品レビューの評価、顧客の感情分析など、多岐にわたります。

感情分析モデルの作成は、言語処理分野で重要な課題です。適切なデータの前処理、モデルのトレーニングと評価、そして実際の文章への適用といったプロセスを通じて、モデルの性能向上や応用範囲の拡大に取り組んでいます。

コメント