Google Playに公開中のアプリのコメントをネガポジ分析してみた
SNSやネット上のコメントを分析するツールやサービスはたくさんあると思いますが、そこまでコストをかけなくても、ネット上のコメントからユーザーの反応(満足、不満)の傾向だけでも簡単につかめるといいなと思い、手始めにGoogle Playのアプリに対するコメントをPythonでネガポジ分析してみました。
基本情報
環境
OS:Windows
言語 : Python
実行環境 : Google Colaboratory
私のレベル
Python初心者
達成したいこと
Google Playに寄せられたユーザーのコメントをネガポジ分析し、まずはユーザーの反応の傾向を大まかに把握できるようにする
分析の流れ
PART1: 事前学習済みBERTモデルを用いて、ネガポジ分析を実施
① 分析対象データの準備
② 事前学習済みBERTモデルでネガポジ分析
PART2: PART1のモデルを日本語のデータセットで学習させ、学習後のモデル
でネガポジ分析を実施
③ 日本語データセットを読み込み、学習データとテストデータを作
成
④ モデルの学習を実行
➄ 学習後のBERTモデルでネガポジ分析
⑥ 学習前と学習後の精度の差を確認
PART 1
①分析対象データの準備
Google Playに書き込んでいただいたユーザーさんのコメントをCSVファイルにコピーします。今回は、ランダムに45件のコメントを抽出しました。ファイルの構成はこのようになっています。
ID: 1から昇順にふった番号
Label: 0: Negative, 1: Neutral, 2: Positiveの判定 (コメントを見て自分で判定)
※のちにモデルの分析結果と比較するため
Comment: 実際のコメント
②事前学習済みBERTモデルでネガポジ分析
Google DriveにCSVファイルを保存しているので、Google Driveをマウントします。
from google.colab import drive
#Google Driveをマウント
drive.mount('/content/drive')
fugashi, ipadic, accelerate, transformersをインストールします。最初、インストールせずにコードを実行したため、途中で何度かエラーが発生し、最終的にこの4つのインストールが必要でした。
!pip install fugashi
!pip install ipadic
!pip install -U accelerate
!pip install -U transformers
事前学習済み日本語BERTモデルとトークナイザーを読み込みます。
BERTモデルは東北大学さんが公開している事前学習済み日本語BERTモデルを使用しました。
import pandas as pd
import torch
from transformers import AutoModelForSequenceClassification, AutoTokenizer
from torch.optim import AdamW
# 事前学習済みの日本語BERTモデルとトークナイザーを読み込む
model = AutoModelForSequenceClassification.from_pretrained("cl-tohoku/bert-base-japanese", num_labels=3)
tokenizer =AutoTokenizer.from_pretrained("cl-tohoku/bert-base-japanese")
CSVファイルを読み込んで分析対象のデータを準備します。CSVのLabelは0,1,2表記のため、文字列に変換しています。
# CSVファイルを読み込む
df = pd.read_csv("/content/drive/MyDrive/ReviewData/App_Review.csv")
#Labelのデータを文字列に変換
label_mapping = {0: "Negative", 1: "Neutral", 2: "Positive"}
df["Label"] = df["Label"].map(label_mapping)
#学習のためのデータをトークン化
test_texts = df["Comment"].tolist()
分析を実行し、分析結果をPredicted Labelに格納します。
# 分析を実行
results = []
for text in test_texts:
with torch.no_grad():
inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
inputs = {key: value.to(device) for key, value in inputs.items()}
outputs = model(**inputs)
logits = outputs.logits
predicted_label = torch.argmax(logits, dim=1).item()
results.append(predicted_label)
# 分析結果をDataFrameに追加
df["Predicted_Label"] = results
# 予測ラベルを文字列に変換
label_mapping = {0: "Negative", 1: "Neutral", 2: "Positive"}
df["Predicted_Label"] = df["Predicted_Label"].map(label_mapping)
# 結果を表示
pd.set_option('display.max_colwidth', 40)
print(df)
結果を見ると、NagativeなコメントをNegativeと判定したケースは1件のみで、あとはNeutralもしくはPositiveと判定されています。事前学習済みモデルは、あまりNegative方向の判定をしない傾向がありそうです。
PART2
Part2では、モデルを学習した場合に分析結果が改善するか見てみます。
③日本語データセットを読み込み、学習データとテストデータを
作成
日本語データセットは株式会社リクルートさんが公開している、Japanese Realistic Textual Entailment Corpusを使用しました。
from transformers import Trainer, TrainingArguments
!curl -L -O https://raw.githubusercontent.com/megagonlabs/jrte-corpus/master/data/pn.tsv
# Japanese Realistic Textual Entailment Corpusのデータセットを読み込む
df = pd.read_csv("pn.tsv", sep='\t', header=None,
names=["id", "label", "text", "judges", "usage"])
# ラベルを 1, 0, -1 --> 0, 1, 2 へ変換
# Label: 2 (Positive), 1 (Neutral), 0 (Negative)
df["label"] = df["label"] + 1
#UsageがTrainのデータを学習用データとして設定
df_train = df[(df["usage"] == "train")]
train_docs = df_train["text"].tolist()
train_labels = df_train["label"].tolist()
len(train_docs)
#UsageがTestのデータを学習用データとして設定
df_test = df[df["usage"] == "test"]
test_docs = df_test["text"].tolist()
test_labels = df_test["label"].tolist()
len(test_docs)
# 事前学習済みの日本語BERTモデルとトークナイザーを読み込む
model = AutoModelForSequenceClassification.from_pretrained("cl-tohoku/bert-base-japanese", num_labels=3)
tokenizer =AutoTokenizer.from_pretrained("cl-tohoku/bert-base-japanese")
train_encodings = tokenizer(train_docs, return_tensors='pt', padding=True, truncation=True, max_length=128)
test_encodings = tokenizer(test_docs, return_tensors='pt', padding=True, truncation=True, max_length=128)
④モデルの学習を実行
データセットと学習のためのアーギュメントを定義したのち、学習を実行します。今回は学習回数 (num_train_epochs)をまずは3に設定しています。
#データセットを定義
class JpSentiDataset(torch.utils.data.Dataset):
def __init__(self, encodings, labels): #インスタンスを初期化
self.encodings = encodings
self.labels = labels
def __getitem__(self, idx): #インデックスに対するエンコーディングとそのラベルをPyTorchのテンソルに返す
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_dataset = JpSentiDataset(train_encodings, train_labels)
test_dataset = JpSentiDataset(test_encodings, test_labels)
# GPU が利用できる場合は GPU を利用する
device = "cuda:0" if torch.cuda.is_available() else "cpu"
# Fine-tuningのための訓練アーギュメントを設定
training_args = TrainingArguments(
per_device_train_batch_size=4,
evaluation_strategy="epoch",
num_train_epochs=3, #一旦3に設定。
logging_dir="./logs",
output_dir="./checkpoints"
)
# Trainerを初期化してFine-tuningを開始
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=test_dataset,
tokenizer=tokenizer,
)
trainer.train()
➄学習後のBERTモデルでネガポジ分析
学習後BERTモデルを使ったネガポジ分析の実行手順は、PART1の事前学習済みモデルを使った分析手順と同じになります。
- コード割愛 -
⑥学習前と学習後の精度の差を確認
学習後の結果を見ると、Negative-Negative件数が18件となっており、NegativeなコメントをNegativeと判定する精度を向上することができました。
終わりに
今回初めて、Pythonを用いたネガポジ分析を実施してみましたが、モデルを学習することで、分析精度を向上させることができました。
学習回数を増やしてみたり、目的にあった学習データを準備することで更に分析精度を上げられるのかなと思うので、今後の改善に向けた課題にしたいと思います。最後までお読みいただきありがとうございました。
今回Pythonで分析を行うにあたり、下記URLを参考にさせていただきました。ありがとうございました。
1. https://github.com/megagonlabs/jrte-corpus
2. https://github.com/cl-tohoku/bert-japanese
3. https://qiita.com/kuroneko2828/items/5a69cb23533e012300dc
4. https://jupyterbook.hnishi.com/language-models/fine_tune_jp_bert_part02.html
このブログはAidemy Premiumのカリキュラムの一環で、データ分析講座の最終成果物として公開しています。
この記事が気に入ったらサポートをしてみませんか?