Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Article information
RevisionsShow article in Markdown
Report article
Help us understand the problem. What is going on with this article?

This post is Private. Only a writer or those who know its URL can access this post.

@kjykndz51518yyy

Twitterの人たちに鬼滅の刃の鬼とは何か聞いてみた

1.はじめに

はじめまして、研修中のゴリちゃんです!
今回はみんな大好き鬼滅の刃のTwitter分析を行いました。
鬼滅の刃と言えば映画の公開、漫画の即日完売、アニメの爆発的なヒットなど連日話題になっていますね!

鬼滅の刃のツイートを収集して、Twitterの人たちが鬼滅の刃に関してどのような印象を抱いているのかみていきましう!

2.開発環境

OS : macOS version10.15.7
Pythonの実行環境 : jupyter notobook
python version : 3.7.6

3.ツイートの収集

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

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は日本時間に合わせるために定義しています。
これは実行した時間から遡ってツイートを取得します。実行開始した時間は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')

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

4.学習モデルの作成

学習モデルを作成します。先ほど取得したツイートを使用してモデルを作ります!
取得したツイートをtxtファイルにまとめました。
集めたツイートの一部が以下の内容になっています。

家族で鬼滅にハマってるんだけど、父が「作るか…禰豆子箱…!!😏」って言い出すから冗談でしょwwwと思ってたらほんとに1週間ぐらいで作ってた…しかも単行本用に二段になってる👍💕

鬼滅の刃、妹にゴリ推しされてなんだかんだアニメ見終わったので劇場版見てきた。煉獄さん、かっこよかったよ……煉獄さんの勝ちだよ……

劇場版、『鬼滅の刃』無限列車編の主題歌、炎を歌ってみた。難しい(>_<)練習しないとだ😥

映画のことや家族で鬼滅の刃を楽しんでいる内容など様々なツイートがあることがわかります。

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

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にまとめることができました。

5.結果

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

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

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

6. 考察

最も上位にきた「鼓」は鼓の鬼と呼ばれる響凱というキャラクターがヒットしたのだと思います!
「媛」はTwitterで鬼滅の刃のイラストを作成している方の名前なので結果に出力されたのではないかと考えました。また、「獅」も獅月さん、獅夏さんなど「獅」という字がついたTwitterのイラストレーターさんが関係していると思います。

このようにTwitter関連で活躍している人や鬼滅に出てくるキャラクターが出て来たのではないかと思いました!
「嬌」も嬌華さんというイラストレーターさんがいました。
今回の出力結果は鬼滅とTwiiter業界で活躍する人の名前の一部が結果として出てしまったのではないかと考えられます。Twitterは情報量が多く非常にノイズが大きい媒体であることが今回の分析でわかった気がします、、

結果的に鬼とは何か聞けませんでしたがTwitterに関連強い情報を抽出できたのではないかと思います!

Article information
RevisionsShow article in Markdown
Report article
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
Article information
RevisionsShow article in Markdown
Report article
Help us understand the problem. What is going on with this article?