Je vais vous expliquer comment utiliser la bibliothèque Python NetworkX en utilisant la création d'un graphe de relations de balises attachées aux articles Qiita comme exemple. NetworkX vous permet de dessiner un graphique des nœuds et des arêtes, comme indiqué ci-dessous.
Qiita publie une API pour récupérer les publications, afin que vous puissiez facilement récupérer les publications. Convertissez les données renvoyées au format JSON en un dictionnaire Python avec le code suivant. En cas de non-authentification, il y a une limite de 100 articles par demande et 60 fois par heure. Cette fois, nous ciblerons 100 * 60 = 6000 articles.
import requests
import json
items = []
params = {"page":1, "per_page":100}
for i in range(60):
print("fetching... page " + str(i+1))
params["page"] = i + 1
res = requests.get("https://qiita.com/api/v2/items", params=params)
items.extend(json.loads(res.text))
Pour les données acquises par l'API, seules les balises sont extraites et converties au format «[[tag1, tag2], [tag3], ...]».
tags_list = []
for item in items:
tags = [tag["name"] for tag in item["tags"]]
tags_list.append(tags)
Utilisez également collections.Counter
pour compter le nombre d'occurrences de balises.
A ce moment, le tableau multiple est aplati avec ʻitertools.chain.from_iterable (tags_list) `.
S'il y a trop de nœuds, la figure sera foirée, alors extrayez les 50 premières balises.
import collections
import itertools
tag_count = collections.Counter(itertools.chain.from_iterable(tags_list)).most_common(50)
De là, nous utiliserons NetworkX pour créer un graphique.
Créez un nouveau graphique avec G = nx.Graph ()
et ajoutez des nœuds avec des noms de balises.
Afin de déterminer la taille du nœud au moment du dessin plus tard, le nombre d'occurrences «count» est mis dans l'attribut du nœud.
import networkx as nx
G = nx.Graph()
G.add_nodes_from([(tag, {"count":count}) for tag,count in tag_count])
Si un article contient plusieurs balises, ajoutez des bords à toutes les combinaisons Par exemple, si vous avez un message marqué avec "Python, networkx, Qiita" comme cet article Créez des bords entre les nœuds Python et les nœuds networkx, entre networkx et Qiita, et entre Qiita et Python. Si l'arête existe déjà, augmentez le «poids» de l'arête.
for tags in tags_list:
for node0,node1 in itertools.combinations(tags, 2):
if not G.has_node(node0) or not G.has_node(node1):
continue
if G.has_edge(node0, node1):
G.edge[node0][node1]["weight"] += 1
else:
G.add_edge(node0, node1, {"weight":1})
Trouvons un graphique ici.
%matplotlib inline
import matplotlib.pyplot as plt
plt.figure(figsize=(15,15))
pos = nx.spring_layout(G)
nx.draw_networkx(G,pos)
plt.axis("off")
plt.savefig("default.png ")
plt.show()
J'ai un graphique que je ne comprends pas.
À partir de là, nous effectuerons divers ajustements pour rendre le graphique plus propre.
Supprimez les arêtes qui apparaissent moins fréquemment.
for (u,v,d) in G.edges(data=True):
if d["weight"] <= 4:
G.remove_edge(u, v)
Dans pos = nx.spring_layout (G)
, la position du nœud est déterminée par la force de répulsion entre les nœuds et la force d'attraction due à la taille du "poids" du bord.
La force de répulsion entre les nœuds peut être définie en spécifiant l'argument «k», et plus le «k» est grand, plus la disposition des nœuds est proche d'un cercle.
pos = nx.spring_layout(G, k=0.3)
Plus le "compte" est grand, plus la taille du cercle de nœuds est grande. De plus, dans la sortie de la figure précédente, le japonais n'est pas affiché sous forme de carré, définissez donc une police pouvant afficher le japonais.
node_size = [ d["count"]*20 for (n,d) in G.nodes(data=True)]
nx.draw_networkx_nodes(G, pos, node_color="w",alpha=0.6, node_size=node_size)
nx.draw_networkx_labels(G, pos, fontsize=14, font_family="Yu Gothic", font_weight="bold")
Épaississez le bord en fonction du "poids" du bord.
edge_width = [ d["weight"]*0.2 for (u,v,d) in G.edges(data=True)]
nx.draw_networkx_edges(G, pos, alpha=0.4, edge_color="c", width=edge_width)
Dessinez avec ce code. Essayez de l'exécuter plusieurs fois ou de modifier les paramètres jusqu'à ce que le graphique obtenu soit correct.
%matplotlib inline
import matplotlib.pyplot as plt
import math
for (u,v,d) in G.edges(data=True):
if d["weight"] <= 4:
G.remove_edge(u, v)
plt.figure(figsize=(15,15))
pos = nx.spring_layout(G, k=0.3)
node_size = [ d['count']*20 for (n,d) in G.nodes(data=True)]
nx.draw_networkx_nodes(G, pos, node_color='w',alpha=0.6, node_size=node_size)
nx.draw_networkx_labels(G, pos, fontsize=14, font_family="Yu Gothic", font_weight="bold")
edge_width = [ d['weight']*0.2 for (u,v,d) in G.edges(data=True)]
nx.draw_networkx_edges(G, pos, alpha=0.4, edge_color='C', width=edge_width)
plt.axis('off')
plt.savefig("g2.png ")
plt.show()
Web (Ruby (on Rails), JavaScript, PHP ...) en haut, Python (machine learning) en bas à gauche, iOS lié au milieu, sujets Windows 10 que Bash peut être utilisé en bas à droite ... Comme vous pouvez le voir, nous avons créé un diagramme qui montre les balises populaires et leurs relations.