映画鬼滅の刃は何が良かった？テキストマイニングで推測する


# はじめに
本記事では、「劇場版 鬼滅の刃 無限列車編」のレビューからテキストマイニングを行い、良かった点を推測します。使用するデータは前回の記事[映画.comのレビューをスクレイピングする][Scraping]で取得したものになります。

[Scraping]:https://qiita.com/yuya2220/items/84b17cca7840be6d52d0

# 環境
python 3.10.4
Windows 11 Home

# テキストマイニングとは
大量のテキストから目的に応じた情報を抽出することです。文章を単語や文節で区切り、出現頻度や相関関係を分析します。
今回はnlplotを使ってワードクラウドと共起ネットワークを作成し、映画の良かった点を推測します。

# 使用するライブラリ
```python
pip install pandas
pip install numpy
pip install matplotlib
#形態素解析に使うライブラリ
pip install mecab-python3
#テキストマイニングに使うライブラリ
pip install nlplot
#以下はポジネガ分析に使うライブラリ
pip install torch torchvision
pip install transformers[ja]
pip install ipadic
```

# 作成コード

## ポジティブ印象のレビューだけ抽出する
BERTでポジネガ分析を行い、ポジティブと判定されたレビューだけ抽出します。データ量が多い場合は実行にかなり時間がかかるため、1度csv等に変換しても良さそうです。BERTについては[こちら][bert]の記事で紹介いたしましたので、よろしければご参照ください。

[bert]:https://qiita.com/yuya2220/items/b0aed6f8a6ae2f585447
```python
import pandas as pd
from transformers import pipeline, AutoModelForSequenceClassification, BertJapaneseTokenizer
import MeCab

def make_positive_reviews(input_df):
    model = AutoModelForSequenceClassification.from_pretrained('koheiduck/bert-japanese-finetuned-sentiment') 
    tokenizer = BertJapaneseTokenizer.from_pretrained('cl-tohoku/bert-base-japanese-whole-word-masking')
    nlp = pipeline("sentiment-analysis", model=model, tokenizer=tokenizer, max_length=512, truncation=True)
    positive_reviews = []
    for row_i in input_df.itertuples():
        #row_i[2]：レビューデータ
        review = row_i[2]
        analyze_result = nlp(review)
        judge = analyze_result[0]['label']
        if judge == 'POSITIVE':
            positive_reviews.append(review)
            
    colmn_name = ['レビュー']
    output_df = pd.DataFrame(positive_reviews, columns=colmn_name)
    return output_df
```

## 文章から名詞だけ抜き出す
形態素解析を行い、名詞と判定された単語を配列に格納します。
```python
import MeCab

def make_noun_array(text):
    tagger = MeCab.Tagger()
    tagger.parse('')
    wordlist = []
    node = tagger.parseToNode(text).next
    while node:
        word_type = node.feature.split(',')[0]
        if word_type == '名詞':
            wordlist.append(node.surface)
        node = node.next
    return wordlist
```

## ワードクラウドを作成する
ポジティブと判定された文章の名詞からワードクラウドを作成します。今回は、「それ」、「そこ」等の指示語や映画のタイトルを分析から除外しました。

```python
import pandas as pd
import nlplot
import matplotlib.pyplot as plt

df = pd.read_csv('無限列車編_レビュー.csv')
positive_df = make_positive_reviews(df)
positive_df['名詞リスト'] = positive_df['レビュー'].apply(make_noun_array)

npt = nlplot.NLPlot(positive_df, target_col='名詞リスト')
#除外する単語
stopwords = ["それ", "の", "あと", "たち", "そこ", "うち", "こと", "もの",
            "鬼", "滅", "刃", "無限", "列車", "映画", "アニメ"]
fig_wc = npt.wordcloud(
width=1000,
height=600,
max_words=50,
max_font_size=150,
colormap='tab20_r',
stopwords=stopwords,
mask_file=None,
save=False
)
plt.figure(figsize=(15, 25))
plt.imshow(fig_wc, interpolation="bilinear")
plt.axis("off")
plt.show()
```

## 共起ネットワークを作成する
ポジティブと判定された文章の名詞から共起ネットワークを作成します。除外語はワードクラウドと同じです。

```python
import nlplot
import matplotlib.pyplot as plt
import plotly
from plotly.subplots import make_subplots
from plotly.offline import iplot

df = pd.read_csv('無限列車編_レビュー.csv')
positive_df = make_positive_reviews(df)
positive_df['名詞リスト'] = positive_df['レビュー'].apply(make_noun_array)

npt = nlplot.NLPlot(positive_df, target_col='名詞リスト')
##stopwords:除外する語句
stopwords = ["それ", "の", "あと", "たち", "そこ", "うち", "こと", "もの",
            "鬼", "滅", "刃", "無限", "列車", "映画", "アニメ"]
#min_edge_frequency:単語の最低出現回数（n回以上出現）
npt.build_graph(stopwords=stopwords, min_edge_frequency=70)
fig_co_network = npt.co_network(
    title='Co-occurrence network',
    sizing=100,
    node_size='adjacency_frequency',
    color_palette='hls',
    width=1100,
    height=700,
    save=False
)

iplot(fig_co_network)
plt.show()
```

# 実行結果

## ワードクラウド
<img width="800" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292716/df7371ea-e0d4-a25f-ec66-9bf8eaaf0106.png>

「煉獄」、「炭治郎」といったキャラクターの名前の他、「原作」、「作品」、「シーン」等の単語が大きい文字で出力されました。こういった単語は結びつきを見ないと良かった点が分からないので、共起ネットワークで深堀りします。「戦闘」、「声優」、「炎」（主題歌）、「ストーリー」等は良かった点として考えられそうです。

## 共起ネットワーク
<img width="800" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292716/04ef0341-2b37-8b4b-e76b-345a052e2982.png>

一番大きな輪の「煉獄」に着目すると、「言葉」、「最後」、「感動」といった単語と結びついているのが分かります。煉獄の最後の言葉が良かった点の1つと考えられそうです。また、「シーン」の輪に着目すると、「原作」、「戦闘」、「迫力」といった単語と結びついています。原作のシーンが再現されている、戦闘シーンに迫力があること等が良かった点として推測できます。

# 終わりに

今回はnlplotを使って「劇場版 鬼滅の刃 無限列車編」のレビューをテキストマイニングしました。
良かった点はおおよそ想定通りでした。映画のレビューを分析対象とするなら、評価の分かっていないもう少しマイナーな作品の方が、発見があって面白かったかもしれません。
ワードクラウドと共起ネットワークは比較的簡単に作成できたので、アンケートをとることがあれば取り入れてみたいと思いました。