L'analyse des réseaux sociaux est le processus d'exploration de divers systèmes à l'aide de la théorie des réseaux. Il a commencé à être largement utilisé précisément lorsqu'il est devenu clair qu'un grand nombre de réseaux existants (sociaux, économiques, biologiques) avaient des propriétés universelles: après avoir étudié un type, vous pouvez comprendre la structure de tous les autres réseaux et apprendre à en faire des prévisions.
Tout réseau se compose de participants individuels (personnes ou éléments du réseau) et des relations entre eux. Les réseaux sont très souvent visualisés à l'aide de graphiques - des structures composées de nombreux points et lignes qui représentent les connexions entre ces points. Les participants sont représentés comme des nœuds du réseau et leurs relations sont représentées par des lignes les reliant. Une telle visualisation permet d'obtenir une évaluation qualitative et quantitative des réseaux:
Figure: 1. Graphique directionnel illustrant la rotation monétaire entre les banques qui forment le marché des changes (1). Les banques de l'UE sont marquées en rouge, l'Amérique du Nord - en bleu et les autres pays - en vert.
Figure: 2. Graphique montrant la coopération des partenaires d'audit au Danemark en 2010-2014 (2)
En utilisant l'analyse des réseaux sociaux, il est possible d'analyser une variété d'interactions et de processus d'échange de ressources, à la fois matérielles et informatives. Par exemple, en analysant le réseau de transactions entre clients bancaires (où les nœuds sont les clients de la banque, et les bords sont les transferts entre eux), il est possible de déterminer le cercle des personnes impliquées dans des transactions frauduleuses, ou d'identifier les violations de la réglementation interne par les employés de la banque.
Vous pouvez également construire un réseau de relations de travail (en utilisant l'exemple de différents types de communication entre employés), ce qui peut aider à comprendre la structure sociale de l'organisation et la position de chaque employé dans cette structure. Compte tenu des données sur le type de communication pour chaque employé, on peut même analyser comment des caractéristiques telles que le leadership, le mentorat et la coopération affectent sa carrière, et en fonction des connaissances acquises, déterminer les objectifs de carrière et proposer des programmes de formation pour les atteindre.
De plus, les événements peuvent être prédits à l'aide de l'exemple des réseaux. Par exemple, il existe des modèles qui estiment la probabilité d'une défaillance logicielle, certains d'entre eux considèrent les personnes comme une source de prédictions - après tout, ce sont les personnes qui développent et testent les produits avant leur sortie. Leurs interactions forment un réseau: vous pouvez considérer les développeurs comme des nœuds, et s'ils ont travaillé ensemble sur le même fichier dans la même version, comme les bords d'un réseau. Comprendre les interactions et les informations sur les échecs précédents en dira long sur la fiabilité du produit final et indiquera les fichiers les plus susceptibles d'échouer.
Essayons maintenant d'appliquer l'analyse des médias sociaux dans la pratique. Pour ce faire, nous utiliserons le langage de programmation Python, ou plutôt la bibliothèque networkx pour travailler avec les graphes, la bibliothèque matplotlib pour la visualisation et la bibliothèque communautaire pour mettre en évidence les communautés au sein du réseau. Importons-les:
1. import community
2. import networkx as nx
3. import matplotlib.cm as cm
4. import matplotlib.pyplot as plt
1. Importer des données et les transformer en graphique
En tant qu'ensemble de données, prenons une correspondance par e-mail d'une grande université européenne, qui contient des informations anonymes sur tous les e-mails entrants et sortants entre les membres d'une institution de recherche (lien). L'ensemble de données contient un fichier txt dans lequel chaque ligne répertorie des paires de nœuds liés les uns aux autres.
1. G = nx.read_edgelist('email-Eu-core.txt', create_using=nx.DiGraph())
2. print(' : {}'.format(G.number_of_nodes()))
3. print(' : {}'.format(G. number_of_edges()))
4. print(' : {}'.format(round(G.number_of_edges() / float(G.number_of_nodes()), 4)))
: 1005
: 25571
: 25.4438
Dans le code ci-dessus, l'ensemble de données a été importé et converti en graphique. Ensuite, nous avons déduit séquentiellement les principaux paramètres du graphe: le nombre de nœuds, d'arêtes et le nombre moyen de voisins des nœuds dans le graphe. Le dernier paramètre reflète à quel point les nœuds sont connectés les uns aux autres.
2. Principales caractéristiques des graphiques
Afin de comprendre comment vous pouvez travailler avec chaque graphique spécifique, vous devez d'abord comprendre comment cela fonctionne. Jetons un coup d'œil aux caractéristiques par lesquelles vous pouvez comprendre la structure d'un graphe.
Tout d'abord, considérons les concepts de connectivité et de directivité. Un graphique est appelé connecté si chaque paire de nœuds du graphique est interconnectée, c'est-à-dire à partir de n'importe quel nœud, vous pouvez accéder à n'importe quel autre nœud. Si le graphe est déconnecté, il peut être divisé en sous-graphes connectés au maximum (appelés composants). De plus, les graphiques peuvent être dirigés et non dirigés. Ceci est déterminé par la présence de l'orientation de la relation entre les deux participants. Un exemple de réseau dirigé est les transactions entre clients bancaires, où chaque client peut avoir à la fois des paiements entrants et sortants.
Dans le cas général, dans les graphes orientés, les connexions ne sont pas mutuelles, par conséquent, pour les graphes orientés, au lieu du concept de connectivité, les concepts de composants de connectivité faible et forte sont distingués. Un composant est considéré comme faiblement connecté si l'ignorance de la direction donne un graphe connecté. Un composant de forte connectivité peut être tel si tous ses sommets sont mutuellement accessibles. Jetons un coup d'œil à la structure du graphique à partir de notre ensemble de données de messagerie:
1. if nx.is_directed(G):
2. if nx.is_weakly_connected(G):
3. print(' .')
4. else:
5. print(' .')
6. else:
7. if nx.is_connected(G):
8. print(' .')
9. else:
10. print(' .')
Le graphique est directionnel et se compose de plusieurs composants.
Ici, nous avons vérifié la directionnalité et la connectivité du graphique et avons découvert que le graphique de l'ensemble de données est dirigé et contient plusieurs composants déconnectés. Examinons de plus près les composants les plus importants d'une connectivité forte et faible:
1. G_weak = G.subgraph(max(nx.weakly_connected_components(G), key=len))
2. print(' : {}'.format(G_weak.number_of_nodes()))
3. print(' : {}'.format(G_weak.number_of_edges()))
4. print(' : {}'.format(round(G_weak.number_of_edges() / float(G_weak.number_of_nodes()), 4)))
5.
6. G_strong = G.subgraph(max(nx.strongly_connected_components(G), key=len))
7. print(' : {}'.format(G_strong.number_of_nodes()))
8. print(' : {}'.format(G_strong.number_of_edges()))
9. print(' : {}'.format(round(G_strong.number_of_edges() / float(G_strong.number_of_nodes()), 4)))
: 986
: 25552
: 25.9148
: 803
: 24729
: 30.7958
Ainsi, nous avons obtenu les principales caractéristiques pour le composant faiblement connecté et pour le composant fortement connecté inclus dans celui-ci. Voyons quelles conclusions nous pouvons tirer à ce stade. Nous voyons que sur 1005 participants, 986 personnes communiquent entre elles, tandis que 183 personnes ont envoyé des courriels à d'autres personnes unilatéralement, et seulement 803 personnes ont maintenu une communication bidirectionnelle. Dans 823 cas, la tentative d'établissement de la communication par e-mail a échoué. Nous constatons également que les participants les plus actifs (inclus dans la composante forte connectivité) communiquent avec une moyenne de 30 personnes.
Examinons d'autres caractéristiques clés des graphiques qui définissent leur structure. Les graphes sont considérés pondérés si les relations entre les nœuds reflètent non seulement l'existence même de la connexion, mais aussi un certain poids, reflétant la force de cette connexion. Notre jeu de données avec les e-mails n'est pas pondéré, car il ne prend en compte que le fait de la correspondance, mais pas le nombre d'e-mails envoyés.
De plus, les nœuds et les liens peuvent créer différents types de réseaux: monocotylédones, dicotylédones ou multi-niveaux. Les réseaux monocotylédones se composent d'un type de participants et des connexions entre eux. Les réseaux bipartites se composent de deux types différents de participants, où l'un des types de nœuds est associé uniquement à l'autre type. Les réseaux à plusieurs niveaux incluent également deux types de participants, mais les liens peuvent relier à la fois différents types de participants et le même type de participants (par exemple, les relations entre les gestionnaires et les relations entre les projets). L'ensemble de données que nous avons pris pour la recherche est un réseau monocotylédone, car il ne comprend qu'un seul type de participants et les connexions entre eux.
3. Visualisation graphique
Essayons maintenant de visualiser l'ensemble de données que nous avons pris. Pour cela, nous avons besoin de la bibliothèque matplotlib, que nous avons déjà importée ci-dessus:
1. plt.figure(figsize=(15, 15))
2. plt.title('E-mails')
3. nx.draw(G, node_size=5)
4. plt.show()
La première ligne définit la taille de la future image, qui reçoit ensuite un nom spécifique. La troisième ligne de la fonction de dessin passe le graphique et spécifie la taille des nœuds, après quoi le graphique est affiché. Jetons un coup d'œil:
Fig. 3. Graphique des interactions des utilisateurs avec des informations sur tous les e-mails entrants et sortants entre les membres de l'institution de recherche.
Sur le graphique résultant, nous voyons qu'il y a un certain nombre de points qui ne sont pas liés au reste des participants à la communication. Ces personnes, sans lien avec le reste des participants, se sont mises sur le graphique, puisqu'elles ont envoyé des lettres exclusivement à elles-mêmes. Vous pouvez également remarquer qu'à la périphérie, il y a un certain nombre de points qui sont connectés au reste du graphique par quelques connexions entrantes - ce sont des participants qui sont tombés dans le composant faiblement connecté de notre graphique, mais qui ne sont pas tombés dans le composant fortement connecté.
Examinons également un graphique qui illustre la forte composante de connectivité - les personnes qui ont une communication bidirectionnelle avec d'autres membres de l'institution de recherche:
Fig. 4. Composante de forte connectivité avec des informations sur tous les e-mails entrants et sortants entre les membres de l'institution de recherche...
4. Degré de nœud et répartition des degrés de nœuds
Maintenant que nous connaissons la structure de notre graphe et que nous pouvons le visualiser, passons à une analyse plus détaillée. Chaque nœud du graphique a un degré - le nombre de voisins les plus proches de ce nœud. Dans les réseaux dirigés, on peut distinguer à la fois le degré d'entrée (le nombre de connexions entrantes vers le nœud) et le degré de sortie (le nombre de connexions sortantes depuis le nœud). Si nous calculons le degré pour chaque nœud du graphique, nous pouvons déterminer la distribution des degrés des nœuds. Jetons un coup d'œil sur le graphique des e-mails:
1. degree = dict(G.degree())
2. degree_values = sorted(set(degree.values()))
3. hist = [list(degree.values()).count(x) for x in degree_values]
4. plt.figure(figsize=(10, 10))
5. plt.plot(degree_values, hist, 'ro-')
6. plt.legend(['Degree'])
7. plt.xlabel('Degree')
8. plt.ylabel('Number of nodes')
9. plt.show()
Figure: 5. Répartition des degrés dans un graphique avec des informations sur tous les e-mails entrants et sortants entre les membres de l'institution de recherche
Sur le graphique résultant, nous voyons la distribution des degrés de nœuds: un grand nombre de nœuds ont peu de connexions avec des voisins, mais il y a un petit nombre de grands nœuds qui ont un certain nombre de connexions avec d'autres les participants sont énormes. Cette tendance est appelée loi de distribution de puissance et est très typique des grands réseaux. Cette loi peut décrire la répartition de la population des différentes villes, le classement des sites sur Internet et même la répartition de la richesse entre les personnes.
5. Chemin, diamètre et distance moyenne dans le graphique
Déterminons maintenant à quel point les membres de notre graphique sont connectés. Tout d'abord, parlons des différents types d'espacement des nœuds.
Toute séquence d'arêtes qui relie des nœuds est appelée un chemin. Le plus souvent, la recherche considère un chemin simple, c'est-à-dire un chemin sans cycles et sans nœuds répétitifs. Le chemin le plus court entre deux nœuds est appelé distance géodésique. Le plus long chemin le plus court d'un graphique s'appelle son diamètre, mais il est très sensible aux écarts (une chaîne dans un graphique de plusieurs millions de dollars peut changer son diamètre). Dans les graphes orientés, le concept de diamètre ne peut être appliqué que pour la composante de forte connectivité, car pour calculer le diamètre, il est nécessaire que pour chaque paire de nœuds, il y ait un chemin entre eux. Dans les graphes non orientés, il suffit que le composant considéré soit connecté.
Une autre caractéristique très informative est la distance moyenne entre les nœuds, qui peut être obtenue en prenant la moyenne de tous les chemins les plus courts du graphique. La distance moyenne est déterminée par la structure du graphe: si le graphe est construit sous la forme d'une chaîne, il sera grand, mais plus les nœuds sont proches, plus la distance moyenne devient petite. La distance moyenne peut être calculée pour le composant connecté fort et le composant faiblement connecté:
1. print (': ', nx.diameter(G_strong))
2. print (' : ', nx.average_shortest_path_length(G_strong))
3. print (' : ', nx.average_shortest_path_length(G_weak))
: 6
: 2.5474824768713336
: 2.164486568301397
Jetons un coup d'œil aux résultats. Le diamètre dans ce cas nous montre la distance maximale entre deux étrangers, et ici, comme dans la théorie bien connue des six poignées de main, cette distance est de 6. La distance moyenne dans les composants est également petite, en moyenne deux «poignées de main» suffisent pour deux étrangers. Un phénomène intéressant peut également être observé ici: la distance moyenne dans le composant connecté fort est légèrement inférieure à celle du composant faiblement connecté. Ceci peut s'expliquer par le fait que la direction des liaisons n'est pas prise en compte pour le composant faiblement connecté (uniquement du fait même de sa présence). Pour cette raison, la connexion dans le composant faible apparaît là où elle était absente pour le composant fort.
6. Regroupement et répartition des communautés
Après avoir compris les distances entre les participants, passons à d'autres phénomènes qui reflètent la façon dont les participants du graphique sont connectés les uns aux autres: le regroupement et les communautés.
Le coefficient de cluster montre que deux éléments du graphique, connectés via le troisième élément, avec un degré de probabilité élevé sont connectés entre eux. Même s'ils ne sont pas liés, la probabilité qu'ils soient liés à l'avenir est beaucoup plus élevée que les deux autres nœuds pris au hasard. Ce phénomène, appelé clustering ou transitivité, est extrêmement courant dans les graphes sociaux.
Les graphes avec un degré élevé d'agrégation sont caractérisés par la présence d'un nombre important de triplets connectés (trois nœuds connectés les uns aux autres). Ils sont la pierre angulaire de nombreux réseaux sociaux, où le nombre de ces triangles est très important. Souvent, il n'y a même pas de triangles, mais des formations de grappes entières, appelées communautés, qui sont plus étroitement liées les unes aux autres qu'au reste du graphique.
Regardons le clustering et le coefficient de cluster pour le composant faiblement connecté:
1. print (': ', nx.transitivity(G_strong))
2. print (' : ', nx.average_clustering(G_strong))
: 0.2201493109315837
: 0.37270757578876434
Pour un composant de forte connectivité, on peut obtenir les mêmes caractéristiques, et aussi déterminer le nombre de nœuds centraux (nœuds les plus étroitement liés au reste) et le nombre de nœuds à la périphérie du graphe:
1. print (': ', nx.transitivity(G_strong))
2. print (' : ', nx.average_clustering(G_strong))
3. print (' : ', len(nx.center(G_strong)))
4. print (' : ', len(nx.periphery(G_strong)))
: 0.2328022090200813
: 0.3905903756516427
: 46
: 3
Dans le second cas, le coefficient de clustering et de clustering a augmenté, reflétant que le composant connecté fort contient un plus grand nombre de triplets liés. Essayons ensemble de définir les principales communautés dans le composant faiblement couplé:
1. G_undirected = G_weak.to_undirected()
2. partition = community.best_partition(G_undirected)
3. communities = set(partition.values())
4. communities_dict = {c: [k for k, v in partition.items() if v == c] for c in communities}
5. highest_degree = {k: sorted(v, key=lambda x: G.degree(x))[-5:] for k, v in communities_dict.items()}
6. print(' : ', len(highest_degree))
7. print(' :', ', '.join([str(len(highest_degree[key])) for key in highest_degree]))
: 8
: 113, 114, 125, 131, 169, 188, 54, 92
Ainsi, dans la colonne avec correspondance électronique, on distingue 8 communautés, qui sont plus étroitement liées les unes aux autres qu'au reste de la colonne. La plus petite des communautés compte 54 membres et la plus grande compte 188 membres. Pour les réseaux contenant des communautés qui se chevauchent ou imbriquées, il peut être plus difficile de déterminer le partitionnement optimal. Par conséquent, chaque fois que vous exécutez le code, la composition des communautés peut différer. Voyons la visualisation de la division que nous avons obtenue:
1. pos = nx.spring_layout(G)
2. plt.figure(figsize=(15, 15))
3. cmap = cm.get_cmap('gist_rainbow', max(partition.values()) + 1)
4. nx.draw_networkx_nodes(G, pos, partition.keys(), node_size=20, cmap=cmap, node_color=list(partition.values()))
5. nx.draw_networkx_edges(G, pos, alpha=0.5)
6. plt.show()
Figure: 6. Affichage de diverses communautés dans un composant faiblement couplé avec des informations sur tous les e-mails entrants et sortants entre les membres de l'institution de recherche.
Dans le graphique ci-dessus, nous voyons la répartition des participants par communauté, où la couleur des nœuds décrit l'appartenance à une communauté particulière.
7. Réciprocité des liens
En plus des propriétés déjà décrites, il existe aussi une réciprocité dans un réseau dirigé. Cette caractéristique décrit le pourcentage de liens sortants ayant un lien de retour, un lien entrant. Pour le savoir, nous utilisons la fonction spéciale global_reciprocity de la bibliothèque networkx et regardons le niveau de réciprocité dans le graphe et ses composants:
1. print (' : ', nx.overall_reciprocity(G))
2. print (' : ', nx.overall_reciprocity(G_weak))
3. print (' : ', nx.overall_reciprocity(G_strong))
: 0.6933635759258535
: 0.6938791484032562
: 0.7169719762222492
Dans 71% des cas, les utilisateurs ont reçu des réponses à leurs messages dans le composant de forte connectivité. Pour le composant faiblement connecté et le graphe entier dans son ensemble, le niveau est prévisible plus bas.
8. Propriétés universelles des réseaux
Pour résumer, les réseaux complexes ont en général certaines propriétés et certaines sont caractéristiques de nombreux réseaux. Notre analyse de l'ensemble de données des e-mails soutient bien ces tendances:
- . , , . : web-, , , (Wikipedia, Microsoft). , .
- . , , « ». : , .
- , , : 80% , . – , , . , , .
- , . , .
Nous avons analysé et confirmé toutes les tendances énumérées ci-dessus pour un ensemble de données avec correspondance par courrier électronique: un gros composant connecté a été trouvé dans le graphique, contenant plus de 80% de tous les nœuds. Dans cette composante, la plupart des nœuds étaient caractérisés par un petit nombre, cependant, il y avait un petit pourcentage de participants qui avaient un grand nombre de voisins. Nous avons également vu que le diamètre et la distance moyenne entre les participants dans le graphique sont petits: la distance moyenne dans le composant faiblement connecté contenant 986 participants n'était que de 2,1, ce qui signifie que la plupart des participants sont connectés les uns aux autres après seulement deux «poignées de main». De plus, le graphique se caractérise par un degré élevé de réciprocité: 69% de tous les participants ont maintenu un contact bidirectionnel les uns avec les autres.
Remarques
Le texte intégral de la recherche se trouve dans le livre de Nikolai Viktorovich Ursul "Toute la vérité sur le Forex" (2019).
La recherche est décrite dans l'article «L'application de l'analyse des réseaux sociaux à la comptabilité et à l'audit» Slobodan Kacanski, Dean Lusher (2017, lien ).