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方向の判定をしない傾向がありそうです。

PART1: 事前学習済みBERTモデルの分析結果


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と判定する精度を向上することができました。

PART2: 学習後BERTモデルの分析結果
PART1: 事前学習済みBERTモデルの分析結果

終わりに

今回初めて、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のカリキュラムの一環で、データ分析講座の最終成果物として公開しています。



この記事が気に入ったらサポートをしてみませんか?