こんにちは!
なおき(@waste_investor)です!
PythonでTwitterの相互フォロワーを取得して可視化するところまでやってみようと思います。
今回は自分の相互フォロワーに加え、相互フォロワーさんの繋がりも見えるようにしてみます。
PythonでTwitter APIを叩く
まずは、Twitter APIから相互フォロワーリストを作ります。
Twitter APIを使うにはTwitter developers アカウントの作成が必要になります。
アカウントの作成方法はこちらにまとめてあるので、参考に作成してください。
-
-
参考【ツイート解析】Twitter Developersアカウントを作成方法
こんにちは! なおき(@waste_investor)です! ツイート分析をするために、Twitter Developersアカウントを作成しました。 作成までの手順をまとめておきます。 ...
続きを見る
TwitterAPIを叩くのはtweepyというライブラリを使用するので、pipでインストールしておきましょう。
1 |
pip install tweepy |
TwitterAPIで相互フォロワーリストを作成
自分をフォローしている人の一覧と、自分がフォローしている人の一覧を使って相互フォロワーリストを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
import tweepy # Twitter認証コードは別ファイルで管理 import TwitterAPIKey import pandas as pd # TwitterAPIのパスワードを取得(別ファイルで保存) consumer_key =TwitterAPIKey.CONSUMER_KEY consumer_secret =TwitterAPIKey.CONSUMER_SECRET access_token=TwitterAPIKey.ACCESS_TOKEN access_secret =TwitterAPIKey.ACCESS_SECRET # Twitterオブジェクトの生成 auth = tweepy.OAuthHandler(consumer_key, consumer_secret) auth.set_access_token(access_token, access_token_secret) api = tweepy.API(auth) user = ('@waste_investor') # フォロワーのIDを取得 naoki_followers_ids = tweepy.Cursor(api.followers_ids, id = user, cursor = -1).items() # 一旦リストに格納 naoki_followers_ids_list = [] for followers_id in naoki_followers_ids: naoki_followers_ids_list.append(followers_id) # フォローのIDを取得 naoki_friends_ids = tweepy.Cursor(api.friends_ids, id = user, cursor = -1).items() # 一旦リストに格納 naoki_friends_ids_list = [] for friends_id in naoki_friends_ids: naoki_friends_ids_list.append(friends_id) # 相互フォロワーID naoki_friends_list = [] for friends_id in naoki_friends_ids_list: for follwers_id in naoki_followers_ids_list: if friends_id == follwers_id: # フォローIDとフォロワーIDが一致するとき相互フォロワー naoki_friends_list.append(friends_id) # IDだと誰が誰だかわからないので、Twitterの表示名と@を取得 naoki_friends_name_list = [] naoki_friends_screen_name_list = [] for i in range(0, len(naoki_friends_list), 100): for user in api.lookup_users(user_ids=naoki_friends_list[i:i+100]): naoki_friends_name_list.append(user.name) naoki_friends_screen_name_list.append(user.screen_name) # csvに出力 friends_df = pd.DataFrame() friends_df['friends_name'] = naoki_friends_name_list friends_df['friends_screen_name'] = naoki_friends_screen_name_list friends_df.to_csv('friends.csv') |
これで相互フォロワーリストの完成です(一部を抜粋)。
Twitter APIで相互フォローしている人の相互フォロワーリストを作成
自分の繋がりだけではなく、相互フォロワー同士のつながりを見えるようにしていきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
import tweepy import time import pandas as pd user_name_list = [] user_screen_name_list = [] friends_name_list = [] friends_screen_name_list = [] for i, naoki_friend in enumerate(naoki_friends_screen_name_list): # TwitterAPIは15分で400リクエストが限界なので、400リクエストしたら15分間隔をあける while True: try: user_name = naoki_friends_name_list[i] user_screen_name = '@' + str(naoki_friend) # フォローを取得 friends_ids = tweepy.Cursor(api.friends_ids, id = user_screen_name, cursor = -1).items() # フォロワーを取得 followers_ids = tweepy.Cursor(api.followers_ids, id = user_screen_name, cursor = -1).items() friends_id_list = [] for friends_id in friends_ids: friends_id_list.append(friends_id) followers_id_list = [] for followers_id in followers_ids: followers_id_list.append(followers_id) friends_list = [] for friend in friends_id_list: for follower in followers_id_list: # 相互フォロワー if friend == follower: # 自分の相互フォロワー if friend in naoki_friends_list: friends_list.append(friend) # ユーザー名を取得 for i in range(0, len(friends_list), 2000): for user in api.lookup_users(user_ids=friends_list[i:i+2000]): user_name_list.append(user_name) user_screen_name_list.append(user_screen_name) friends_name_list.append(user.name) friends_screen_name_list.append(user.screen_name) except tweepy.TweepError: # 15分間隔をあける time.sleep(60 * 15) continue break # 確認済みフォロワー print(user_screen_name) |
TwitterAPIに送ることができるリクエストが15分で400リクエストまでなので、400リクエストしたら15分間隔を空けないと、エラーになってしまいます。
フォロー・フォロワーさんが多いアカウントで取ろうとするとものすごい時間になり、処理が終わりませんでした。
どこでリクエストの回数が加算されているか、いまひとつ理解していないので、工夫の余地はあると思います。
1 2 3 4 5 6 7 8 9 10 |
import pandas as pd # csvに出力 friends_df = pd.DataFrame() friends_df['user_name'] = user_name_list friends_df['user_screen_name'] = user_screen_name_list friends_df['friends_name'] = friends_name_list friends_df['friends_screen_name'] = friends_screen_name_list friends_df.to_csv('naoki_friends.csv') |
ここまでで、自分の相互フォロワー、そしてその相互フォロワー同士のフォロー関係のリストを作ることができました。
Python networkxを使ってTwitterのフォロー関係を可視化
TwitterAPIから作成したフォロワーの関係はあくまでリスト(表)形式なので、可視性はとても悪いです。
より関係を見やすくするために、ネットワーク状に可視化してみます。
networkxをインストールします。
1 |
pip install networkx |
networkxを使って可視化
networkxはノードとエッジを設定して、ネットワーク構造を可視化できるモジュールです。
ノードはフォロワー名(@のやつ)、エッジにはフォロー関係を入れていきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import collections import itertools import pandas as pd # データの取得 # 相互フォロワー関係リストを読み込み df = pd.read_csv('naoki_friends.csv') my_friends_list = [] friends_list = [] for i in range(len(df)): my_friends_list.append(['@waste_investor', df['user_screen_name'].iloc[i]]) friends_list.append([df['user_screen_name'].iloc[i], '@' + df['friends_screen_name'].iloc[i]]) # 可視化は出現頻度の多い50名に限定 my_friends_count = collections.Counter(itertools.chain.from_iterable(my_friends_list)).most_common(50) friends_count = collections.Counter(itertools.chain.from_iterable(friends_list)).most_common(50) |
ここからが逗子の部分です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
import networkx as nx import matplotlib.pyplot as plt G = nx.Graph() G.add_nodes_from([(friend, {"count":count}) for friend,count in my_friends_count]) G.add_nodes_from([(friend, {"count":count}) for friend,count in friends_count]) for friends in my_friends_list: for node0,node1 in itertools.combinations(friends, 2): if not G.has_node(node0) or not G.has_node(node1): continue if G.has_edge(node0, node1): for (u,v,d) in G.edges(data=True): if u == node0 and v == node1: # ノードを強くする d['weight'] += 1 else: # 自分のフォロワーとの関係は強く表示 G.add_edge(node0, node1, weight=5) for friends in friends_list: for node0,node1 in itertools.combinations(friends, 2): if not G.has_node(node0) or not G.has_node(node1): continue if G.has_edge(node0, node1): for (u,v,d) in G.edges(data=True): if u == node0 and v == node1: # ノードを強くする d['weight'] += 1 else: G.add_edge(node0, node1, weight=1) plt.figure(figsize=(20,20)) pos = nx.spring_layout(G, k=1.0) # パラメータを調節すると見えかたも変わってくる node_size = [ d['count']*30 for (n,d) in G.nodes(data=True)] nx.draw_networkx_nodes(G, pos, node_color='w',alpha=0.5, node_size=node_size) nx.draw_networkx_labels(G, pos, fontsize=20, font_family="Yu Gothic", font_weight="bold") edge_width = [ d['weight']*0.5 for (u,v,d) in G.edges(data=True)] nx.draw_networkx_edges(G, pos, alpha=0.6, edge_color='C', width=edge_width) plt.axis('off') plt.savefig("naoki_friends.png") plt.show() |
これで作成できたグラフがこちらです。
@ではなく、アイコンで表示できればもっと見やすい気もしますが、残念ながらnetworkxに画像を埋め込む口は用意されていないようです。
これで人と人とのつながりが見やすくなりました。
わかったことは、自分の相互フォロワーはとても密接になっていることです。
リプも活発になってTwitterが楽しくなるわけですね。
データを取ってきたり、加工したりするのはそう難しくありませんが、人間がわかるように可視化するのはセンスが問われるのと、いい見え方を考える必要があるので、とても苦労します。
可視化すると文字や数字で追うより、直感的に捉えることができるので、データの可視化スキルを少しづつ高めていきたいです。
TwitterAPIを使ったデータの取得、可視化までPythonを使って実装しています。
Pythonは初心者でもとても扱いやすい言語なので、挑戦してみましょう。