認知アーキテクチャを統合したbertによる感情分析について
解決したいこと
認知アーキテクチャを統合したbertによる感情分析を行ったのですが、精度があまり良くありませんでした。以下の資料を見て、精度向上の見込みがあると感じたためやってみたのですが、逆に精度が下がってしまいました。手法や手順、及び具体的なコードについてなにかご意見や提案をいただけたら嬉しいです。
https://hai-conference.net/proceedings/HAI2024/pdf/G-28.pdf
https://www.jcss.gr.jp/meetings/jcss2024/proceedings/pdf/JCSS2024_P-2-62A.pdf
感情分析に使用するデータセットとして「WRIMEデータセット」をダウンロードして読み込みます。このデータセットは8つの基本感情に対して主観と客観の視点から4段階で評価した結果をまとめています。
事前学習済みモデル(bert)を読み込み、感情分類タスクに適応させます。今回は
・学習率:2e-5
・バッチサイズ:16
・エポック数:3
などのように訓練パラメータを設定しました。
このモデルを訓練した結果が以下の通りです。
Accuracy: 0.7346875
Precision: 0.7290057167284929
Recall: 0.7346875
F1 Score: 0.7304683153558532
そしてその後、ACT-Rモデルを定義し、感情ラベルをメモリにフィードバックする機能を実装しました。予測された感情ラベルをACT-Rモデルにフィードバックし、メモリを更新します。
ACT-Rモデルを使用して新しい感情予測を生成した結果が以下の通りになりました。
Accuracy: 0.68375
F1 Score: 0.5553247958426132
Precision: 0.46751406249999994
Recall: 0.68375
今回使用したソースコード
pip install transformers datasets torch
import pandas as pd
from sklearn.metrics import accuracy_score, precision_recall_fscore_support
from transformers import BertTokenizer, BertForSequenceClassification, Trainer, TrainingArguments
import torch
from torch.utils.data import Dataset
# WRIMEデータセットのダウンロード
!wget https://github.com/ids-cv/wrime/raw/master/wrime-ver1.tsv
# データセットの読み込み
df = pd.read_table('wrime-ver1.tsv')
print(df.head())
# データフレームの列名を確認
print(df.columns)
# Googleドライブのマウント
from google.colab import drive
drive.mount('/content/drive')
# Hugging Face Hubにログイン
!huggingface-cli login
# トークンを入力し、Gitクレデンシャルとして追加するプロンプトに従う
# トークナイザーの読み込み
tokenizer = BertTokenizer.from_pretrained('cl-tohoku/bert-base-japanese')
# データセットを訓練用とテスト用に分割
df_groups = df.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)) # train : 17104
print('test :', len(df_test)) # test : 1133
# 訓練データとテストデータのトークン化
train_encodings = tokenizer(df_train['Sentence'].tolist(), padding='max_length', truncation=True, return_tensors='pt')
test_encodings = tokenizer(df_test['Sentence'].tolist(), padding='max_length', truncation=True, return_tensors='pt')
# データセットクラスの定義
class WRIMEDataset(Dataset):
def __init__(self, encodings, labels):
self.encodings = encodings
self.labels = labels
def __getitem__(self, idx):
item = {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}
item['labels'] = torch.tensor(self.labels[idx])
return item
def __len__(self):
return len(self.labels)
# 訓練データセットとテストデータセットの作成
train_labels = df_train['Avg. Readers_Joy'].tolist()
test_labels = df_test['Avg. Readers_Joy'].tolist()
train_dataset = WRIMEDataset(train_encodings, train_labels)
test_dataset = WRIMEDataset(test_encodings, test_labels)
# モデルの準備
model = BertForSequenceClassification.from_pretrained('cl-tohoku/bert-base-japanese', num_labels=8)
training_args = TrainingArguments(
output_dir='./results',
evaluation_strategy='epoch',
learning_rate=2e-5,
per_device_train_batch_size=16,
per_device_eval_batch_size=16,
num_train_epochs=3,
weight_decay=0.01,
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=test_dataset
)
# モデルの訓練
trainer.train()
# モデルの評価
predictions = trainer.predict(test_dataset)
preds = predictions.predictions.argmax(-1)
# 精度、適合率、再現率、F1スコアの計算
accuracy = accuracy_score(test_labels, preds)
precision, recall, f1, _ = precision_recall_fscore_support(test_labels, preds, average='weighted')
print(f"Accuracy: {accuracy}")
print(f"Precision: {precision}")
print(f"Recall: {recall}")
print(f"F1 Score: {f1}")
# 感情分析結果を取得
predictions = trainer.predict(test_dataset)
predicted_labels = predictions.predictions.argmax(-1)
# ACT-Rモデルにフィードバック
class ACTRModel:
def __init__(self):
self.memory = []
def update_memory(self, emotion):
self.memory.append(emotion)
def predict(self, input_data):
# ここでACT-Rモデルを用いた予測ロジックを実装
# 現在は単にメモリから最新の感情を返すだけ
if self.memory:
return self.memory[-1]
else:
return 0 # デフォルト値
actr_model = ACTRModel()
# 予測ラベルをACT-Rモデルにフィードバック
for label in predicted_labels:
actr_model.update_memory(label)
# ACT-Rモデルを用いた新しい予測を生成
actr_predictions = [actr_model.predict(label) for label in predicted_labels]
# 評価指標の計算
from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score
# 実際の感情ラベル
true_labels = test_labels
# 精度の計算
accuracy = accuracy_score(true_labels, actr_predictions)
f1 = f1_score(true_labels, actr_predictions, average='weighted')
precision = precision_score(true_labels, actr_predictions, average='weighted')
recall = recall_score(true_labels, actr_predictions, average='weighted')
print(f"Accuracy: {accuracy}")
print(f"F1 Score: {f1}")
print(f"Precision: {precision}")
print(f"Recall: {recall}")