Twitterのフォロワーのコミュニティを可視化してみよう

Twitterのフォロワーのコミュニティを可視化してみよう

こんにちは、エンジョイワークスでエンジニアをやっている北矢です。

今回は、Twitterのコミュニティを可視化して遊んでみようと思います。(前回記事にしたPLATEAUの続編はまた後日書こうと思います)

可視化するにあたって、ネットワークデータを扱おうと思います。ここ数年、機械学習の分野でネットワークデータに対する深層学習 (Graph Neural Network; GNN)が盛り上がっているように見受けられます。タスクによっては、テーブルデータよりネットワークデータの方が有効的だったりします。それはズバリ、人と人の繋がりを分析するケースです。

本記事では、自分の勉強も兼ねて、ネットワークデータにまつわる分析をしていこうと思います。

  1. ネットワークとは
  2. TwitterのAPIからネットワーク取得
  3. ネットワークを使ってnode2vecで学習
  4. 自分と関係性の近いTwitterアカウントの探索
  5. フォロワーのコミュニティを可視化
  6. さいごに

ネットワークとは

ネットワークは人と人の繋がりだけでなく、インターネットだったり、地図の経路だったり、建築物の動線を表現するデータ構造です。最近では、コロナの感染経路を予測するにあたって、交通機関ネットワークと人の動きが活用されています。(たぶん)

ネットワークとは次の2つで構成されています。ネットワークはグラフとも呼ばれます。

・ノード:点(人、物、場所)
・エッジ:辺(繋がり、経路)

ノードを人だとしたら、エッジが関係性です。ところどころ、双方向に矢印が向いているエッジがありますね。Twitterでいうと、双方向でフォローしている状態になります。

TwitterのAPIからネットワーク取得

では早速、人と人の繋がりを分析するために、TwitterのAPIを取得して、ネットワークを取得してみましょう。TwitterのAPIを利用方法はこちらの記事を参考に、TwitterのAPIキーやアクセストークンを生成します。

ここからはPythonを用いてTwitterデータ分析していきます。なお、分析をするにあたって、こちらの記事を参照させて頂きました。

まずは、Twitterのアクセストークン周りを取得します。

import tweepy

# 認証キーの設定(ここに生成したAPIキーやアクセストークンを貼り付けます)
consumer_key = "hogehoge"
consumer_secret = "hogehoge"
access_token = "hogehoge"
access_token_secret = "hogehoge"

# OAuth認証
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)

# APIのインスタンスを生成
api = tweepy.API(
    auth,
    wait_on_rate_limit=True,
    wait_on_rate_limit_notify=True
)

今回は自分自身のTwitterアカウント周りのネットワークを取得してみます。この処理では、Webサービスに過度な負荷がかからないようSleep処理が自動的に入るため、気長に待ちましょう。なお、メモリをとても食うので、フォローしている人数が多いとメモリ不足になるかもしれません。

def getFollowers_ids(api, id):
    followers_ids = tweepy.Cursor(api.followers_ids, id=id, cursor=-1).items()
    followers_ids_list = []
    try:
        followers_ids_list=[i for i in followers_ids]
        

    except tweepy.error.TweepError as e:
        print(e.reason)

    return followers_ids_list

from collections import defaultdict
from tqdm import tqdm
center_to_followers = {}
node_attrs = defaultdict(dict)

# center account(ここにTwitterアカウント名を貼り付けます)
CENTER_ACCOUNTS = ['hogehoge',]

for center_screen_name in CENTER_ACCOUNTS:

    # get center account information (node attributes)
    center_info = api.get_user(screen_name=center_screen_name)

    # get id of center account
    center_id = center_info.id

    node_attrs[center_id]['screenName'] = center_screen_name
    node_attrs[center_id]['followersNum'] = center_info.followers_count
    node_attrs[center_id]['followNum'] = center_info.friends_count

    center_to_followers[center_id] = getFollowers_ids(api=api, id=center_screen_name)

    for follower_id in tqdm(center_to_followers[center_id]):    # get center account information (node attributes)
        center_info1 = api.get_user(id=follower_id)

        center_id1 = center_info1.id

        node_attrs[center_id1]['screenName'] = center_info1.name
        node_attrs[center_id1]['followersNum'] = center_info1.followers_count
        node_attrs[center_id1]['followNum'] = center_info1.friends_count

        center_to_followers[center_id1] = getFollowers_ids(api=api, id=center_id1)

これで自分と自分のフォロワーが誰をフォローしているかのネットワークをnodeとattrという属性で取得できました。 次にこれをPythonライブラリであるnetworkxの形に変換します。

import networkx as nx

graph = nx.from_dict_of_lists(center_to_followers)
nx.set_node_attributes(graph, node_attrs)
nx.write_gml(graph, '/path/to/twitter.gml')

これで準備完了です。

ネットワークを使ってnode2vecで学習

次にアルゴリズムnode2vecを使ってネットワークの学習を行います。node2vecの詳細については今回割愛させて頂きますが、ネットワークのノードを高次元のベクトルで表現する技術となります。ベクトル化することで、Twiiterアカウント間の類似度が計算可能となります。自然言語処理データを扱うアルゴリズムWord2vecにピンとくる方、そうです、同じような技術となります。今回、文章や画像の特徴量から類似度を計算するのではなく、ネットワーク(ノード、エッジ)の特徴量を利用します。

node2vecを用いて、準備したネットワークデータを学習してモデルを作成します。学習方法は以下となります。

from node2vec import Node2Vec

n2v_obj = Node2Vec(graph, dimensions=10,
 walk_length=5, num_walks=10, p=1, q=1, workers=1)

model = n2v_obj.fit(window=10, min_count=1, batch_words=4)
# モデルを保存
model.save("/path/to/n2v.model")

自分と関係性の近いTwitterアカウントの探索

学習が完了したので、自分と似ているTwitterアカウントTOP10を探索してみようと思います。自分のTwitterアカウントはざっくり言うと、機械学習系、音楽系、建築系、不動産系、ビジネス系、カルチャー系?をフォローしているので、そういった分野のアカウントの方と近しいと嬉しいですね・・・!

from gensim.models import word2vec

model.most_similar('自分のIDを入力', topn=10)
[('626296060', 0.9729713201522827),
 ('72324159', 0.951846182346344),
 ('125675863', 0.9504321813583374),
 ('395945987', 0.9472029209136963),
 ('75103992', 0.9464631080627441),
 ('1333908731705266176', 0.9450739622116089),
 ('385373934', 0.9444583654403687),
 ('150942062', 0.9442764520645142),
 ('125011829', 0.9436476230621338),
 ('758009011', 0.9436008930206299)]

結果はリスト型(‘類似アカウントのID’,’コサイン類似度’)で返却されます。

TwitterのIDではなく、Twitter内部で管理?しているIDで返却されるので、以下のコードでアカウント名を表示します。

api.get_user(id=IDを入力).name

アカウント名を公表するのは差し控えますが、自分と一番近いアカウントの方は機械学習の研究をやっている方でした!自分は研究しているわけではないので恐れ多いですが、フォローしていない方だったのでこれを機にフォローさせて頂きました。

他にも、コミュニケーションプランナーをしているアカウントの方も類似しているようで、フォローさせて頂きました。こうやって興味ある分野が似ているのに存じ上げない人を発見するのに有効かもしれません。

ですが、残りの8名は量子コンピュータの仕事をしているアカウントや、不満つぶやき用のアカウントなど、自分と似ているのかあやしいアカウントばかりでした。

今回やってみたかったこととして、node2vecによってベクトル表現ができたので、ベクトルの演算をやってみます。Word2vecでいうと、”王様-男+女=女王”のような計算です。今回、自分のアカウントと好きなアカウントを足し算してみたら、どういうアカウントと近いのか試してみようと思います。好きなアカウントとして、知人のギターリストを今回選定してみました。

model.most_similar(positive=['自分のIDを入力', '好きなIDを入力'], negative=[],topn=10)

すると、一番近い人がポーカーをやっているアカウントでした。。

二番目は「モノ」と「コト」を売っているカレー屋アカウント、三番目は「オルタナティブな視点から音楽文化を問い直す」メディアアカウントでした。近いのかは疑問ですが、面白い結果となりました。

フォロワーのコミュニティを可視化

最後に、自分のフォロワーのコミュニティをプロットしてみます。

今回、主成分分析(PCA)と呼ばれる手法で多次元のベクトルを2次元に圧縮して、グラフに描画してみることにします。

from sklearn.decomposition import PCA

vec = model.wv.vectors
wordlist = ["IDを入力","IDを入力","省略"]

pca = PCA(n_components=2)
pca.fit(vec)

# 射影
X_2d = pca.transform(vec)
print(X_2d)

plt.figure(figsize = (10, 10))
wordlen = len(wordlist)
for i in range(wordlen):
	plt.plot(X_2d[i][0], X_2d[i][1], ms=5.0, zorder=2, marker='o')
	plt.annotate(wordlist[i], (X_2d[i][0], X_2d[i][1]))
	
plt.show()

このグラフでは、IDごとにプロットされており、近い距離にいるIDが似ていることを示しています。

人手で分類分けしてみたのですが、緑枠のアカウント群は音楽系、青枠は機械学習系、赤枠はカルチャー系?と近しいID同士で形成されています。ですが、それ以外はなぜこのID間が近いんだろう?とあやしい結果になりました。もう少し、学習するネットワークを増やしてみたりすると、いい結果になるかもしれません。

今回はここまで。

さいごに

いかがでしたでしょうか。ネットワーク表現することでコミュニティを可視化することができ、自分と近いコミュニティにいるご近所さんを発見できるかもしれませんね。また次回も機械学習を用いてなにかやってみようと思います。

エンジョイワークスでは一緒に働くエンジニアを募集しております!
採用情報はこちらWantedlyも覗いてみてください!

一覧へ戻る

最新記事