実現したいこと
- ツイッターのフォロワーのネットワークを描写したい。
- そのために、nx.pagerankのエラーを解決するか、代替策を講じたい。
前提
pythonでツイッターのあるアカウントのフォロワーのつながりについて、ネットワークを描写したいです。https://mangalab.hatenablog.com/entry/MangaAnimeNetworkのコードを真似したのですが、networkのpagerankが上手く機能しません
google colaboratoryで動かしています。
発生している問題・エラーメッセージ
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-15-3c1c903d9ca2> in <module> 93 94 #中心性(Pagerank)を計算 ---> 95 pr = nx.pagerank(G) 96 97 #グラフ描画用にprの値を調節 3 frames /usr/local/lib/python3.8/dist-packages/networkx/classes/backends.py in wrapper(*args, **kwds) 143 f"'{name}' not implemented by {plugin_name}" 144 ) --> 145 return func(*args, **kwds) 146 147 _register_algo(name, wrapper) /usr/local/lib/python3.8/dist-packages/networkx/algorithms/link_analysis/pagerank_alg.py in pagerank(G, alpha, personalization, max_iter, tol, nstart, weight, dangling) 107 108 """ --> 109 return _pagerank_scipy( 110 G, alpha, personalization, max_iter, tol, nstart, weight, dangling 111 ) /usr/local/lib/python3.8/dist-packages/networkx/algorithms/link_analysis/pagerank_alg.py in _pagerank_scipy(G, alpha, personalization, max_iter, tol, nstart, weight, dangling) 457 458 nodelist = list(G) --> 459 A = nx.to_scipy_sparse_array(G, nodelist=nodelist, weight=weight, dtype=float) 460 S = A.sum(axis=1) 461 S[S != 0] = 1.0 / S[S != 0] /usr/local/lib/python3.8/dist-packages/networkx/convert_matrix.py in to_scipy_sparse_array(G, nodelist, dtype, weight, format) 591 r += diag_index 592 c += diag_index --> 593 A = sp.sparse.coo_array((d, (r, c)), shape=(nlen, nlen), dtype=dtype) 594 try: 595 return A.asformat(format) AttributeError: module 'scipy.sparse' has no attribute 'coo_array'
該当のソースコード
python
1import tweepy 2from tqdm import tqdm 3import pandas as pd 4import networkx as nx 5from networkx.algorithms import community 6from pyvis.network import Network 7import collections 8import itertools 9 10consumer_key = ' 11consumer_secret = 12access_token = ' 13access_token_secret = ' 14 15auth = tweepy.OAuthHandler(consumer_key, consumer_secret) 16auth.set_access_token(access_token, access_token_secret) 17 18api = tweepy.API(auth, wait_on_rate_limit=True) 19 20col_names_st = ["source","target"] 21col_names_stw = ["source","target","weight"] 22 23sources = ["@"] 24 25nodelist = [] 26 27image_dict = {} 28name_dict = {} 29 30for source in sources: 31 for friend_id in tweepy.Cursor(api.friends_ids, screen_name=source, count=200).items(1000): 32 friend = api.get_user(friend_id) 33 nodelist.append(friend.screen_name) 34 image_dict[friend.screen_name] = friend.profile_image_url 35 name_dict[friend.screen_name] = friend.name 36 37nodelist = set(nodelist) 38 39df_check = pd.DataFrame(columns=col_names_st) 40 41for node in tqdm(nodelist): 42 node_mentions = [] 43 try: 44 for status in api.user_timeline(screen_name=node, count=200): 45 node_mention = status.entities['user_mentions'] 46 try: 47 node_mentions.append(node_mention[0]['screen_name']) 48 except Exception as e: 49 pass 50 except Exception as e: 51 pass 52 53 node_mentions_dict = collections.Counter(node_mentions) 54 55 date_add = [node,node_mentions_dict] 56 df_add = pd.DataFrame([date_add], columns=col_names_st) 57 df_check = pd.concat([df_check, df_add]) 58 59df_all = pd.DataFrame(columns=col_names_stw) 60 61for node in tqdm(nodelist): 62 group1_dict = df_check[df_check['source']==node]['target'].iloc[-1] 63 64 for key1,value1 in group1_dict.items(): 65 if key1 in nodelist: 66 group2_dict = df_check[df_check['source']==key1]['target'].iloc[-1] 67 68 for key2,value2 in group2_dict.items(): 69 if key2 == node: 70 score = min([value1,value2]) 71 72 if score > 0: 73 date_add = [node,key1,score] 74 df_add = pd.DataFrame([date_add], columns=col_names_stw) 75 df_all = pd.concat([df_all, df_add]) 76 77df_all['value'] = df_all['weight'] 78df_all['length'] = (1/df_all['weight']*50) 79 80G = nx.convert_matrix.from_pandas_edgelist(df_all, edge_attr=True) 81 82G.remove_edges_from(nx.selfloop_edges(G)) 83 84G_rem=[] 85for v in G: 86 G_deg=G.degree(v) 87 if G_deg==0: 88 G_rem.append(v) 89 90G.remove_nodes_from(G_rem) 91 92 93 94#中心性(Pagerank)を計算 95pr = nx.pagerank(G) 96 97#グラフ描画用にprの値を調節 98mn = min(list(pr.values())) 99mx = max(list(pr.values())) 100for key, val in pr.items(): 101 pr[key] = (1+((val-mn)/(mx-mn))*4) 102 #クラスタリング 103k = 8 #クラスタ数 104 105comp = community.girvan_newman(G) 106community_list = [] 107for communities in itertools.islice(comp, k-1): 108 community_list.append(tuple(sorted(c) for c in communities)) 109 110community_list = list(community_list[k-2]) 111 112#ノード属性を指定するためのデータフレーム(名前・ラベル・サイズ・形・画像URL・色) 113df_nodes = pd.DataFrame(columns=['name','label','size','shape','image','color']) 114 115for node in G: 116 if node in community_list[0]: 117 c = 'orange' 118 elif node in community_list[1]: 119 c = 'gold' 120 elif node in community_list[2]: 121 c = 'pink' 122 elif node in community_list[3]: 123 c = 'salmon' 124 elif node in community_list[4]: 125 c = 'yellowgreen' 126 elif node in community_list[5]: 127 c = 'sandybrown' 128 elif node in community_list[6]: 129 c = 'violet' 130 else: 131 c = 'pink' 132 133 134 #ノード属性を追加 135 date_add = [node,name_dict[node],pr[node]*10,"image",image_dict[node],c] 136 df_add = pd.DataFrame([date_add], columns=['name','label','size','shape','image','color']) 137 df_nodes = pd.concat([df_nodes, df_add]) 138 139#ノード属性をネットワークに反映 140nodes_attr = df_nodes.set_index('name').to_dict(orient = 'index') 141nx.set_node_attributes(G, nodes_attr) 142# networkxグラフをpyvisグラフに変換 143g = Network(width="100%", height="100%") #画面サイズに対する比率を設定 144g.from_nx(G) #NetworkXのグラフをPyvisに変換 145 146# グラフをhtmlで出力 147g.show_buttons() 148g.show("network.html")
試したこと
pageRankを手動で指定しようとしてみましたが、2.0とか適当に指定しても上手くいきませんでした。
TypeError Traceback (most recent call last) <ipython-input-16-a53a64347d7a> in <module> 127 128 #ノード属性を追加 --> 129 date_add = [node,name_dict[node],pr[node]*10,"image",image_dict[node],c] 130 df_add = pd.DataFrame([date_add], columns=['name','label','size','shape','image','color']) 131 df_nodes = pd.concat([df_nodes, df_add]) TypeError: 'float' object is not subscriptable
chatGPTなどに手伝ってもらっても上手くいかず、調べて出てきたpagerank_numpyなどを試しても上手くいかず、八方ふさがりになっていしまいました。
coo_array() が追加されたのは Scipy 1.8.0rc1 なので、そちらの環境にインストールされている Scipy の version が 1.8.0 よりも前のものなのではないでしょうか。
Add an array API to scipy.sparse · scipy/scipy@82071b2
https://github.com/scipy/scipy/commit/82071b2120b1a54e5235a6940b02b0d9c6184594
使用されているモジュールのバージョンを質問に追記ください。
ありがとうございます。1.8.0rc1にversionを変えたら出来ました。

回答1件
あなたの回答
tips
プレビュー