7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

TwitterAPIを使って特定のキーワードを含むツイート可視化

Last updated at Posted at 2021-07-03

概要

・TwitterのAPIを利用して直近1週間の特定のキーワードを含むツイート可視化
 ①レンタルサーバーのツイート数推移(時間)をプロット
 ②直近1週間のレンタルサーバーのツイート数推移(日)をプロット
 ③頻出ワードのランキング

今後やってみたいこと

・TwitterAPIを使った特定キーワードのネガポジ分析
・クラスタ分析

環境

Python 3.5.2
Jupyter Notebook

前準備

Twitter APIを使用するにはデベロッパー申請が必要。

実装


import json
from requests_oauthlib import OAuth1Session, OAuth1
import requests

# requests-oauthlibという Python 用の OAuth 認証ライブラリを用いてアクセスする。
# Requestsは、 Python の HTTP 通信ライブラリ。 
# Requests を使うとWebサイトの情報取得や画像の収集などを行うことができる。

# TwitterのAPI-keyを入力
KEYS = {
    'consumer_key':'-----------------',
    'consumer_secret':'-----------------',
    'access_token':'-----------------',
    'access_secret':'-----------------',
}
twitter = OAuth1Session(KEYS['consumer_key'],KEYS['consumer_secret'],KEYS['access_token'],KEYS['access_secret'])

## ツイート情報取得用エンドポイントURL
url = "https://api.twitter.com/1.1/search/tweets.json"

# Standard search APIでツイートの取得
# result_type:取得するツイートの種類が選択できる recentは、最新のツイート
params ={'q': "key_word", 'count':'100','lang':'ja', 'result_type':'recent'}

res = twitter.get(url, params = params)

def getTwitterData(key_word, repeat):
    url = "https://api.twitter.com/1.1/search/tweets.json"
    params ={'q': key_word, 'count':'100','lang':'ja', 'result_type':'recent'}
    tweets = []
    mid = -1
    break_flag = 0

# max_idは、取得Tweetの範囲の指定
# res = twitter.get(url, params = params)でTwitterからデータを取得
# if res.status_code == 200:  httpレスポンスステータスコードで成功した場合200が返ってきた場合以下の処理をする
# sub_tweets = json.loads(res.text)['statuses'] :['statuses'] のデータをとってくる
# limit = res.headers['x-rate-limit-remaining'] if 'x-rate-limit-remaining' in res.headers else 0  :['x-rate-limit-remaining'] の値があったらその値を入れてなかったら0にする

    for i in range(repeat):
        params['max_id'] = mid
        res = twitter.get(url, params = params)
        if res.status_code == 200:
            sub_tweets = json.loads(res.text)['statuses']
            limit = res.headers['x-rate-limit-remaining'] if 'x-rate-limit-remaining' in res.headers else 0          
            tweet_ids = []
            for tweet in sub_tweets:
                tweet_ids.append(int(tweet['id']))
                tweets.append(tweet)
            if len(tweet_ids) > 0:
                min_tweet_id = min(tweet_ids)
                mid = min_tweet_id - 1
            else:
                break_flag = 1
                break;  
            ## 終了判定
            if break_flag == 1:
                break;            
        else:
            print("Failed: %d" % res.status_code)
            break_flag = 1
    print("ツイート取得数:%s" % len(tweets))
    return tweets

tweets = getTwitterData("レンタルサーバー", 180)
ツイート取得数1965

import pandas as pd
df_tweet = pd.DataFrame(tweets)
display(df_tweet.info())
df_tweet.dtypes

# エラーが出たのでデータの型をdf_tweet.dtypesで確認。「created_at」がobjectであるためエラーが起きていた

# 日付の文字列の列に対してto_datetime()を適用し、datetime64[ns]型に変換
df_tweet['created_at'] = pd.to_datetime(df_tweet['created_at'])

# 変更を確認
df_tweet.dtypes

データ型の確認

created_at                   datetime64[ns, UTC]
id                                         int64
id_str                                    object
text                                      object
truncated                                   bool
entities                                  object
extended_entities                         object
metadata                                  object
source                                    object
in_reply_to_status_id                    float64
in_reply_to_status_id_str                 object
in_reply_to_user_id                      float64
in_reply_to_user_id_str                   object
in_reply_to_screen_name                   object
user                                      object
geo                                       object
coordinates                               object
place                                     object
contributors                              object
is_quote_status                             bool
retweet_count                              int64
favorite_count                             int64
favorited                                   bool
retweeted                                   bool
possibly_sensitive                        object
lang                                      object
retweeted_status                          object
quoted_status_id                         float64
quoted_status_id_str                      object
dtype: object

この中で、分析によく使いそうな項目

created_a UTC+0(グリニッジ標準時)であるため、日本時間が必要な場合は変換が必要
text ツイート本文が含まれている。
user ツイートしたユーザ情報が含まれている。フォロワー数やユーザ登録日など、複数の情報を含んでいる。リツイート数など、様々な情報を引き出すことが可能

直近1週間の時間毎のレンタルサーバーのツイート数推移をプロット

import matplotlib.pyplot as plt
import seaborn as sns

plt.figure(figsize=(20,5))
g = sns.barplot(x="created_at", y="id", data=df_tweet.set_index("created_at").resample("H")["id"].count().reset_index())
labels = g.get_xticklabels()
g.set_xticklabels(labels, rotation=90)
plt.show()

6月13日取得(集計期間:6月5日〜6月13日)
Twitter01.png

7月3日取得(集計期間:6月25日〜7月3日)
twitter_1.png
6月に比べてレンタルサーバーを含むツイートが減少

日別でプロットする

plt.figure(figsize=(20,5))
g = sns.barplot(x="created_at", y="id", data=df_tweet.set_index("created_at").resample("D")["id"].count().reset_index())
labels = g.get_xticklabels()
g.set_xticklabels(labels, rotation=90)
plt.show()

6月13日取得(集計期間:6月5日〜6月13日)
  2021年6月10日にツィートが多いのは、fastlyの障害の影響かな
Twitter02.png

7月3日取得(集計期間:6月25日〜7月3日)
twitter_2.png

頻出ワードの可視化を行う

df = df_tweet.copy()
df = df.dropna(subset=["text"])
import MeCab

m = MeCab.Tagger('-Ochasen  -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd')
def word_analysis(doc):
    node = m.parseToNode(doc)
    word_list=[]
    while node:
        hinshi = node.feature.split(",")[0]
        if hinshi == "名詞":
          word_list.append(node.feature.split(",")[6])
        node = node.next
    return word_list

df["名詞"]=df["text"].apply(word_analysis)

import itertools
import collections
word_pickup = df["名詞"]
words =list( itertools.chain.from_iterable(word_pickup))
c = collections.Counter(words)

import seaborn as sns
import matplotlib.pyplot as plt

sns.set(font = "Hiragino Maru Gothic Pro",context="talk")
fig = plt.subplots(figsize=(10,30))
sns.countplot(y=words,order=[i[0] for i in c.most_common(50)])

6月13日取得(集計期間:6月5日〜6月13日)
Twitter03.png
7月3日取得(集計期間:6月25日〜7月3日)
twitter3.png

7
7
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
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?