概要
・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()
7月3日取得(集計期間:6月25日〜7月3日)
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の障害の影響かな
頻出ワードの可視化を行う
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)])