LoginSignup
5
6

More than 5 years have passed since last update.

指定アカウントのツイートをWordCloudで可視化する方法

Last updated at Posted at 2019-03-25

「Twitterデータを使って、何か面白いことができないか」の第三弾です。

第一回:
「停電」に関するツイートをpythonで収集して、WordCloudで可視化してみた
https://qiita.com/pocket_kyoto/items/0f43c9fdce87bddd31cf
第二回:
「クッパ姫」に関するツイートをpythonで収集して、バースト検出してみた
https://qiita.com/pocket_kyoto/items/de4b512b8212e53bbba3

今回は、シンプルに、指定アカウントのツイートを取得して、
WordCloudで可視化してみました。

Twitterデータって、どうやったら収集できるの?

以下の流れで収集できます。

  1. 開発者用のTwitterアカウントを登録する
  2. Twitter APIに利用者登録する
  3. API利用のためのアクセスキー・トークンを取得
  4. Twitter REST APIsで、データを収集

詳しくは、第一回記事を御覧ください。

指定アカウントのツイートを収集する

まずは、ライブラリの読み込みなど、ツイート収集の準備です。
Twitter REST APIsの出力は、json形式であるため、jsonライブラリを使います。
また、pythonからREST APIsを簡単に呼び出せるように、requests_oauthlibライブラリを使います。

# Twitterデータ収集用のログインキーの情報
KEYS = { # 自分のアカウントで入手したキーを記載
        'consumer_key':'*********************',
        'consumer_secret':'*********************',
        'access_token':'*********************',
        'access_secret':'*********************',
       }

# Twitterデータの収集(収集準備)
import json
from requests_oauthlib import OAuth1Session
twitter = OAuth1Session(KEYS['consumer_key'],KEYS['consumer_secret'],KEYS['access_token'],KEYS['access_secret'])

指定アカウントのツイート収集用の関数は、以下のように書きました。
user_name(@以降のアカウント名)を引数としています。
1回あたり最大100ツイートしか検索できないため、for文で複数回リクエストできるようにしています。

# Twitterデータ取得関数
def getAccountTwitterData(user_name, repeat=10):

    url = "https://api.twitter.com/1.1/statuses/user_timeline.json"
    params ={'screen_name':user_name,'exclude_replies':True,'include_rts':False,'count':200} #取得パラメータ
    tweets = []

    mid = -1

    for i in range(repeat):
        if mid != -1: # 初回のみmax_idの指定を解除する
            params['max_id'] = mid # midよりも古いIDのツイートのみを取得する
        res = twitter.get(url, params = params)
        if res.status_code == 200: #正常通信出来た場合

            sub_tweets = json.loads(res.text) #レスポンスからツイート情報を取得

            user_ids = []
            for tweet in sub_tweets:
                user_ids.append(int(tweet['id']))
                tweets.append(tweet)

            # ループで取得したmidよりも古いツイートを取るための工夫(※もっと良い書き方ありそう)
            if len(user_ids) > 0:
                min_user_id = min(user_ids)
                mid = min_user_id - 1
            else:
                mid = -1
            print(mid) # 時系列で見た時に最も古いツイートID

        else: #正常通信出来なかった場合
            print("Failed: %d" % res.status_code)
            break

    print("ツイート取得数:%s" % len(tweets))
    return tweets

この関数を用いて、特定ユーザーのツイートを収集してみます。
総フォロワー数ランキング1位の有吉弘行さんのアカウント("ariyoshihiroiki")のツイートを収集してみます。

tweets = getAccountTwitterData("ariyoshihiroiki", repeat=30)

出力:
1083030050134323201
1052193588430364671
1022730204936953855
996980908119900161
965901986422927360
927507559023460352
901354707137871872
883995701314584575
850964015756869631
823160757894291455
796014648101175296
781414278850936831
763211195511771135
747450926097563647
728578679194820607
708969135716196351
706835898747367423
-1
:
(中略)
:
-1
ツイート取得数:2520


2520のツイートを収集できました。
一定量のツイートは収集できましたが、Twitter APIから、特定ユーザーの全ツイートにアクセスすることは仕様上できないようです。

取得したツイートを可視化する

以下のような関数を定義して、janomeで形態素解析して、単語の出現頻度をカウントした後、WordCloudで可視化しました。

# 文章を形態素解析して、Bag of Wordsに変換する
from janome.tokenizer import Tokenizer
import collections
import re

def CountWord(tweets):
    tweet_list = [tweet["text"] for tweet in tweets]
    all_tweet = "\n".join(tweet_list)

    t = Tokenizer()

    # 原形に変形、名詞のみ、1文字を除去、漢字・平仮名・カタカナの連続飲みに限定
    c = collections.Counter(token.base_form for token in t.tokenize(all_tweet) 
                            if token.part_of_speech.startswith('名詞') and len(token.base_form) > 1 
                            and token.base_form.isalpha() and not re.match('^[a-zA-Z]+$', token.base_form)) 

    freq_dict = {}
    mc = c.most_common()
    for elem in mc:
        freq_dict[elem[0]] = elem[1]

    return freq_dict

WordCloudで可視化する関数

# Word Cloudで可視化、WordCloud可視化関数
def color_func(word, font_size, position, orientation, random_state, font_path):
    return 'white'

from wordcloud import WordCloud
import matplotlib.pyplot as plt
get_ipython().run_line_magic('matplotlib', 'inline')
from matplotlib.font_manager import FontProperties
fp = FontProperties(fname=r'C:\WINDOWS\Fonts\meiryo.ttc', size=50) #日本語対応

def DrawWordCloud(word_freq_dict, fig_title):

    # デフォルト設定を変更して、colormapを"rainbow"に変更
    wordcloud = WordCloud(background_color='white', min_font_size=15, font_path='C:\WINDOWS\Fonts\meiryo.ttc',
                          max_font_size=200, width=1000, height=500, prefer_horizontal=1.0, relative_scaling=0.0, colormap="rainbow")    
    wordcloud.generate_from_frequencies(word_freq_dict)
    plt.figure(figsize=[20,20])
    plt.title(fig_title, fontproperties=fp)
    plt.imshow(wordcloud,interpolation='bilinear')
    plt.axis("off")

有吉弘行さんのアカウントに含まれるツイートを可視化してみます。

freq_dict = CountWord(tweets)
DrawWordCloud(freq_dict, "%sさんのつぶやきキーワード" % "ariyoshihiroiki")

出力:
image.png


できました。
ラジオという単語や、田中さん、上島さんなどの仲の良いメンバーの名前が目立ちます。

ちなみに孫正義さんのアカウント("masason")のツイートを可視化すると以下のようになります。

tweets = getAccountTwitterData("masason", repeat=30)
freq_dict = CountWord(tweets)
DrawWordCloud(freq_dict, "%sさんのつぶやきキーワード" % "masason")

出力:
329646069589884927
241826873217257472

(中略)

-1
ツイート取得数:3068

image.png


原発関連のツイートが目立つことが分かります。

まとめと今後

高度な分析に取り組もうとすると、やはりREST APIs で収集できる範囲では不足な気がしますが、
ユーザーアカウント毎のツイートを簡易に取得できることが分かったので、応用できそうな予感はします。

Twitterデータの他の活用方法についても探っていこうと思います。

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6