自然言語処理で、Twitterユーザーに『鬼滅の刃』の「鬼」とは何か聞いてみた

はじめまして、アイデミーのゴリちゃんです!

今回は、みんな大好き『鬼滅の刃』について、機械学習の自然言語処理を活用したTwitter分析を行いました。

『鬼滅の刃』と言えば、映画の公開、漫画最終巻の即日完売、アニメの爆発的なヒットなど連日話題になりましたね!

さて、ファンが『鬼滅の刃』の鬼をどのように捉えているのかが気になりました。それを知るためには自然言語処理を用いて鬼滅関連のツイートから「鬼」と類似度の高い文字を導き出せば「鬼とは何であるか」のが分かると考えました。

そこで、『鬼滅の刃』に関するのツイートを収集して「鬼」の類似ワードを出力することで、Twitterのユーザーが『鬼滅の刃』にどのような印象を抱いているのか見ていきたいと思います!

開発環境

OS : macOS version10.15.7

Pythonの実行環境 : Jupyter Notebook

Python version : 3.7.6

ツイート取集

まずツイートを収集します。「鬼滅」と書かれたツイートを取得しました。

Twitterのツイートを取得するためにはTwitter API利用申請が必要になります。

申請方法については以下のリンクにわかりやすく書いてあります。

https://www.itti.jp/web-direction/how-to-apply-for-twitter-api/

https://help.twitter.com/ja/rules-and-policies/twitter-api

ライブラリは以下のものを使用します。

tweepyはTwitter関連のライブラリです!

import tweepy
import datetime
import csv
from time import sleep

まず、CSVファイルに書き込むためのclassを作成します。

そしてclassの中にはheaderについての関数と取得した内容を書き込むmake関数を作成しています。

class make_csv:
    def __init__(self,filename):
        self.filename=filename
        # csvファイルの作成とヘッダーの書き込み
        with open(self.filename,mode="w",encoding="utf-8") as file:
            writer=csv.writer(file) # writerオブジェクトを作成
            header=[
                "RT",
                "text",
                "tweet_id",
                "post_date",
                "retweet",
                "favorite",
                "user",
                "screen_name",
                "reply_id",
                "language"
                ] # ヘッダー
            writer.writerow(header) # ヘッダーを書き込む
    def make(self,tweet):
        # csvファイルの作成とヘッダーの書き込み
        with open(self.filename,mode="a",encoding="utf-8") as file:
            writer=csv.writer(file) # writerオブジェクトを作成

            if 'RT' in tweet.text:
                RT=True
            else:
                RT=False
            text = str(tweet.text).replace('\n','')
            if text.find(','):
                text.replace(',',',')

            body=[
                RT,
                text,
                tweet.id,
                tweet.created_at + datetime.timedelta(hours=+9),
                tweet.retweet_count,
                tweet.favorite_count,
                tweet.user.name,
                tweet.user.screen_name,
                tweet.in_reply_to_status_id,
                tweet.lang
                ]
            writer.writerow(body) # を書き込む

次にツイートを実際に探す関数を定義します。ツイートを取得する上での問題点は、1週間以上のツイートをまとめて取得できないことと、1回の検索で100ツイートしか取得できないことです。以上のことを踏まえてcount=100にしています。

hours=+9は日本時間に合わせるために定義しています。

これは実行した時間から遡ってツイートを取得します。2020年11月12日16時30分に実行開始し、11月13日1時15分に実行を終了して約50万件のツイートを取得しました。

def search(api,word,lang):
    now = datetime.datetime.now()
    file_name = 'result_{0}_{1}.csv'.format(word,now.strftime('%Y-%m-%d_%H-%M'))
    mc = make_csv(file_name)
    try:
        tweet_data = api.search(q=word, count=100, lang=lang)
    except tweepy.error.TweepError as tweeperror:
        print(tweeperror)
    for tweet in tweet_data:
        mc.make(tweet)
    next_max_id = tweet_data[-1].id
    i = 1
    sleep(1)
    while True:
        i += 1
        print('検索ページ:' + str(i))
        try:
            tweet_data = api.search(q=word, count=100, max_id=next_max_id-1, lang=lang)
        except tweepy.error.TweepError as tweeperror:
            print(tweeperror)
            sleep(60)
            continue
        try:
            next_max_id = tweet_data[-1].id
            post_date = tweet_data[-1].created_at + datetime.timedelta(hours=+9)
        except IndexError as ie:
            print(ie)
            break
        for tweet in tweet_data:
            mc.make(tweet)
        if (post_date - now) > datetime.timedelta(days=7):
            break
        else:
            sleep(1)

次にTwitterのAPIkeyなどを入力する関数を定義します。’・・・・・’の部分に取得したコードを入力してください。

def __init__():
    place = api.geo_search()

consumer_key    = '・・・・・・・・・・・・・・・・・・・・・・・・・'
consumer_secret = '・・・・・・・・・・・・・・・・・・・・・・・・・・・・'
access_token   = '・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・'
access_token_secret  = '・・・・・・・・・・・・・・・・・・・・・・・・・・'
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)
api = tweepy.API(auth, wait_on_rate_limit = True)

wordlistに取得したい言葉を入力します。

‘鬼滅’

‘煉獄さん’

のようにいくつかのワードを同時に入手できるようにしました。

(今回は’鬼滅’のみが必要なので一つしか入れていません)

wordlist=[
    '鬼滅'
    ]
for word in wordlist:
    search(api,word,lang='ja')

以上のようなコードを使用して「鬼滅」と記載されたツイートを収集することができました!!

学習モデルの作成

学習モデルを作成します。先ほど取得したツイートを使用してモデルを作ります!

取得したツイートをtxtファイルにまとめました。

以下は、集めたツイート内容の一部です。

これらのツイートデータを整理するために英数字や記号などを削除し、名詞を取り出す操作をしました。

with open("kimetu_yaiba.txt", "r") as f:
    kimetu = f.read()

# 英数字の削除
kimetu = re.sub("[a-xA-Z0-9_]","",kimetu)
# 記号の削除
kimetu = re.sub("[!-/:-@[-`{-~]","",kimetu)
# 空白・改行の削除
kimetu = re.sub(u'\n\n', '\n', kimetu)
kimetu = re.sub(u'\r', '', kimetu)

def meishi(text):
    t = Tokenizer()
    tokens = t.tokenize(text)
    noun = []
    for token in tokens:
        partOfSpeech = token.part_of_speech.split(",")[0]
        if partOfSpeech == "名詞":
            noun.append(token.surface)
    return noun

#名詞取り出し
kimetu = meishi(kimetu)

次にをWord2vecの学習モデルを作成したいと思います。Word2vecとはテキストデータを解析して、各単語の意味をベクトル化する手法です。ベクトル化することで単語同士の意味の近さを計算することや、単語同士の足し算や引き算をすることも可能です。

例えば、

王-男性+女性=女王

ということが可能になります!

Word2vecを使用したため以下のライブラリを使用しました。

from gensim.models import word2vec

そして以下のコードを使用してWord2vecの学習モデルを作成しました。

model = word2vec.Word2Vec(kimetu,
                          sg=1,
                          size=300,
                          min_count=2,
                          window=10,
                          hs=1,
                          negative=0)
model.save('kimetu_yaiba.model')

ここまでで取得したツイートを単語ごとにベクトル化して、kimetu_yaiba.modelにまとめることができました。

結果

作成したモデルを使用して「鬼」という言葉の類似度を計算しました。

model = word2vec.Word2Vec.load("kimetu_yaiba.model")

model.wv.most_similar(positive=[u"鬼"], topn=10)

<出力結果>

鼓 : 0.4020339749279022

喘 : 0.3988995850086212

溺 : 0.3856756091117859

窒 : 0.3804914355278015

姑 : 0.3793377280235290

媛 : 0.3649221658706665

嬌 : 0.3539180159568786

助 : 0.3534685969352722

獅 : 0.3446348905563354

峙 : 0.3425127863883972

以上のような結果を取得することができました。

考察

最も上位の「鼓」は、鼓の鬼と呼ばれる響凱というキャラクターがヒットしたのだと思います!

「媛」はTwitterで『鬼滅の刃』のファンアートを公開している方のアカウント名なので結果に出力されたのではないかと考えました。また、「獅」も獅月さん、獅夏さんなど「獅」という字がついたファンアートのアカウント名が関係していると思います。

このようにTwitterでファンアートを公開している人や『鬼滅の刃』のキャラクターが上位となったのではないかと思いました!

今回の出力結果には、『鬼滅の刃』とTwiiterで人気のあるアカウント名の一部が反映されてしまったのではないかと考えられます。Twitterは情報量が多く、非常にノイズが大きい媒体であることが今回の分析でわかった気がします。

結果的に鬼とは何か聞けませんでしたが、Twitterに特化した『鬼滅の刃』関連ワードを抽出できたのではないかと思います!

▼この記事はQiitaでも公開しています。

https://qiita.com/kjykndz51518yyy/private/1655b84ab0d4edd3c93c

今回ご紹介した、Twitterのデータを抽出して分析する自然言語処理の仕組みは、Python専門オンラインスクールAidemy Premium Planの「自然言語処理講座」で学習が可能です。

プログラミング未経験からでもAIスキルが身につくAidemy Premium Plan

PythonやAIプログラミングを学ぶなら、オンライン制スクールのAidemy Premium Planがおすすめです。
「機械学習・ディープラーニングに興味がある」
「AIをどのように活用するのだろう?」
「文系の私でもプログラミング学習を続けられるだろうか?」
少しでも気になることがございましたら、ぜひお気軽にAidemy Premium Planの【オンライン無料相談会】にご参加いただき、お悩みをお聞かせください!