Bei der Analyse sozialer Netzwerke werden verschiedene Systeme mithilfe der Netzwerktheorie untersucht. Gerade als klar wurde, dass eine große Anzahl bestehender Netzwerke (sozial, wirtschaftlich, biologisch) universelle Eigenschaften hat, wurde es weit verbreitet: Wenn Sie einen Typ untersucht haben, können Sie die Struktur aller anderen Netzwerke verstehen und lernen, daraus Vorhersagen zu treffen.
Jedes Netzwerk besteht aus einzelnen Teilnehmern (Personen oder Dingen im Netzwerk) und den Beziehungen zwischen ihnen. Netzwerke werden sehr oft mithilfe von Diagrammen visualisiert - Strukturen, die aus vielen Punkten und Linien bestehen, die die Verbindungen zwischen diesen Punkten darstellen. Die Teilnehmer werden als Knoten des Netzwerks dargestellt, und ihre Beziehungen werden als Verbindungslinien dargestellt. Eine solche Visualisierung hilft bei der qualitativen und quantitativen Bewertung von Netzwerken:
Zahl: 1. Richtungsdiagramm, das den Geldumsatz zwischen Banken darstellt, die den Devisenmarkt bilden (1). EU-Banken sind rot, Nordamerika - blau und andere Länder - grün markiert.
Zahl: 2. Grafik zur Zusammenarbeit der Prüfungspartner in Dänemark im Zeitraum 2010-2014 (2)
Mithilfe der Analyse sozialer Netzwerke können verschiedene Interaktionen und Austauschprozesse von materiellen und informativen Ressourcen analysiert werden. Durch Analyse des Netzwerks von Transaktionen zwischen Bankkunden (wobei die Knoten die Kunden der Bank sind und die Kanten Übertragungen zwischen ihnen sind) ist es beispielsweise möglich, den Personenkreis zu bestimmen, der an betrügerischen Transaktionen beteiligt ist, oder Verstöße gegen interne Vorschriften durch Bankangestellte zu identifizieren.
Sie können auch ein Netzwerk von Arbeitsbeziehungen aufbauen (am Beispiel verschiedener Arten der Kommunikation zwischen Mitarbeitern), um die soziale Struktur der Organisation und die Position jedes Mitarbeiters in dieser Struktur besser zu verstehen. Anhand der Daten zur Art der Kommunikation für jeden Mitarbeiter kann man sogar analysieren, wie sich Merkmale wie Führung, Mentoring und Zusammenarbeit auf seine Karriere auswirken, und auf der Grundlage des gewonnenen Wissens Karriereziele festlegen und Schulungsprogramme vorschlagen, um diese zu erreichen.
Darüber hinaus können Ereignisse am Beispiel von Netzwerken vorhergesagt werden. Zum Beispiel gibt es Modelle, die die Wahrscheinlichkeit eines Softwarefehlers abschätzen. Einige von ihnen betrachten Menschen als Quelle für Vorhersagen - schließlich sind es Menschen, die Produkte vor der Veröffentlichung entwickeln und testen. Ihre Interaktionen bilden ein Netzwerk: Sie können sich Entwickler als Knoten vorstellen und feststellen, ob sie in derselben Version an derselben Datei zusammengearbeitet haben, als Kanten eines Netzwerks. Das Verständnis der Interaktionen und Informationen zu früheren Fehlern wird viel über die Zuverlässigkeit des Endprodukts aussagen und auf die Dateien hinweisen, die am wahrscheinlichsten ausfallen.
Versuchen wir nun, die Social-Media-Analyse in der Praxis anzuwenden. Dazu verwenden wir die Programmiersprache Python oder vielmehr die networkx-Bibliothek zum Arbeiten mit Diagrammen, die matplotlib-Bibliothek zur Visualisierung und die Community-Bibliothek zum Hervorheben von Communitys innerhalb des Netzwerks. Importieren wir sie:
1. import community
2. import networkx as nx
3. import matplotlib.cm as cm
4. import matplotlib.pyplot as plt
1. Daten importieren und in ein Diagramm umwandeln
Nehmen wir als Datensatz eine E-Mail-Korrespondenz einer großen europäischen Universität, die anonyme Informationen zu allen eingehenden und ausgehenden E-Mail-Nachrichten zwischen Mitgliedern einer Forschungseinrichtung enthält (Link). Das Dataset enthält eine txt-Datei, in der jede Zeile Knotenpaare auflistet, die miteinander in Beziehung stehen.
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
Im obigen Code wurde der Datensatz importiert und in ein Diagramm konvertiert. Dann haben wir nacheinander die Hauptparameter des Diagramms abgeleitet: die Anzahl der Knoten, Kanten und die durchschnittliche Anzahl der Nachbarn der Knoten im Diagramm. Der letzte Parameter gibt an, wie eng die Knoten miteinander verbunden sind.
2. Hauptmerkmale von Graphen
Um zu verstehen, wie Sie mit jedem bestimmten Diagramm arbeiten können, müssen Sie zunächst verstehen, wie es funktioniert. Lassen Sie uns einen kurzen Blick auf die Merkmale werfen, anhand derer Sie die Struktur eines Diagramms verstehen können.
Betrachten Sie zunächst die Konzepte der Konnektivität und Direktionalität. Ein Graph wird als verbunden bezeichnet, wenn jedes Knotenpaar in dem Graph miteinander verbunden ist, d.h. Von jedem Knoten aus können Sie zu jedem anderen Knoten gelangen. Wenn der Graph nicht verbunden ist, kann er in maximal verbundene Untergraphen (als Komponenten bezeichnet) unterteilt werden. Außerdem können Diagramme gerichtet und ungerichtet sein. Dies wird durch das Vorhandensein der Direktionalität der Verbindungen zwischen den beiden Teilnehmern bestimmt. Ein Beispiel für ein gerichtetes Netzwerk sind Transaktionen zwischen Bankkunden, bei denen jeder Kunde sowohl eingehende als auch ausgehende Zahlungen erhalten kann.
Im allgemeinen Fall sind in gerichteten Graphen die Verbindungen nicht wechselseitig, daher werden bei gerichteten Graphen anstelle des Konnektivitätskonzepts die Konzepte von Komponenten schwacher und starker Konnektivität unterschieden. Eine Komponente wird als schwach verbunden betrachtet, wenn das Ignorieren der Richtung zu einem verbundenen Diagramm führt. Eine Komponente starker Konnektivität kann eine solche sein, wenn alle ihre Scheitelpunkte gegenseitig erreichbar sind. Werfen wir einen Blick auf die Struktur des Diagramms aus unserem E-Mail-Datensatz:
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(' .')
Der Graph ist gerichtet und besteht aus mehreren Komponenten.
Hier haben wir die Richtung und Konnektivität des Diagramms überprüft und festgestellt, dass das Diagramm aus dem Datensatz gerichtet ist und mehrere nicht verbundene Komponenten enthält. Schauen wir uns die größten Komponenten starker und schwacher Konnektivität genauer an:
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
Wir haben also die Hauptmerkmale für die schwach verbundene Komponente und für die darin enthaltene stark verbundene Komponente erhalten. Mal sehen, welche Schlussfolgerungen wir in dieser Phase ziehen können. Wir sehen, dass von 1005 Teilnehmern 986 Personen miteinander kommunizieren, während 183 einseitig E-Mails an andere Personen senden und nur 803 Personen eine wechselseitige Kommunikation aufrechterhalten. In 823 Fällen schlug der Versuch, eine Kommunikation per E-Mail herzustellen, fehl. Wir sehen auch, dass die aktivsten Teilnehmer (in der Komponente der starken Verbundenheit enthalten) mit durchschnittlich 30 Personen kommunizieren.
Schauen wir uns andere Schlüsselmerkmale von Diagrammen an, die ihre Struktur definieren. Diagramme gelten als gewichtet, wenn die Beziehungen zwischen den Knoten nicht nur die Existenz der Verbindung widerspiegeln, sondern auch ein bestimmtes Gewicht, das die Stärke dieser Verbindung widerspiegelt. Unser Datensatz mit E-Mails wird nicht gewichtet, da nur die Korrespondenz berücksichtigt wird, nicht jedoch die Anzahl der gesendeten E-Mails.
Darüber hinaus können Knoten und Verbindungen verschiedene Arten von Netzwerken erstellen: monokotyle, dikotyle oder mehrstufige. Monokotyle Netzwerke bestehen aus einer Art von Teilnehmern und den Verbindungen zwischen ihnen. Bipartite Netzwerke bestehen aus zwei verschiedenen Arten von Teilnehmern, wobei ein Knotentyp nur dem anderen Typ zugeordnet ist. Mehrebenen-Netzwerke umfassen auch zwei Arten von Teilnehmern, aber Links können sowohl verschiedene Arten von Teilnehmern als auch dieselbe Art von Teilnehmern verbinden (z. B. Beziehungen zwischen Managern und Beziehungen zwischen Projekten). Der Datensatz, den wir für die Forschung herangezogen haben, ist ein monokotylen Netzwerk, da er nur aus einem Teilnehmertyp und den Verbindungen zwischen ihnen besteht.
3. Grafikvisualisierung
Versuchen wir nun, den von uns aufgenommenen Datensatz zu visualisieren. Dazu benötigen wir die matplotlib-Bibliothek, die wir oben bereits importiert haben:
1. plt.figure(figsize=(15, 15))
2. plt.title('E-mails')
3. nx.draw(G, node_size=5)
4. plt.show()
In der ersten Zeile wird die Größe des zukünftigen Bilds festgelegt, dem dann ein bestimmter Name zugewiesen wird. Die dritte Zeile der Zeichenfunktion übergibt das Diagramm und gibt die Größe der Knoten an. Danach wird das Diagramm angezeigt. Schauen wir uns das an:
Abb. 3. Diagramm der Benutzerinteraktionen mit Informationen zu allen eingehenden und ausgehenden E-Mails zwischen Mitgliedern der Forschungseinrichtung.
In der resultierenden Grafik sehen wir, dass es eine Reihe von Punkten gibt, die nicht mit dem Rest der Kommunikationsteilnehmer verbunden sind. Diese Personen, die nicht mit dem Rest der Teilnehmer verbunden waren, stiegen in die Grafik ein, da sie Briefe ausschließlich an sich selbst schickten. Sie können auch feststellen, dass es an der Peripherie eine Reihe von Punkten gibt, die durch einige eingehende Verbindungen mit dem Rest des Diagramms verbunden sind. Dies sind Teilnehmer, die in die schwach verbundene Komponente für unser Diagramm gefallen sind, aber nicht in die stark verbundene Komponente.
Schauen wir uns auch ein Diagramm an, das die starke Verbundenheitskomponente veranschaulicht - Personen, die wechselseitige Kommunikation mit anderen Mitgliedern der Forschungseinrichtung haben:
Abb. 4. Bestandteil einer starken Konnektivität mit Informationen über alle eingehenden und ausgehenden E-Mails zwischen Mitgliedern der Forschungseinrichtung...
4. Knotengrad und Verteilung der Knotengrade
Nachdem wir die Struktur unseres Diagramms kennen und visualisieren können, gehen wir zu einer detaillierteren Analyse über. Jeder Knoten im Diagramm hat einen Grad - die Anzahl der nächsten Nachbarn dieses Knotens. In gerichteten Netzwerken kann man sowohl den Eintrittsgrad (die Anzahl der eingehenden Verbindungen zum Knoten) als auch den Grad des Austritts (die Anzahl der vom Knoten ausgehenden Verbindungen) unterscheiden. Wenn wir den Grad für jeden Knoten des Diagramms berechnen, können wir die Verteilung der Grade der Knoten bestimmen. Schauen wir uns das E-Mail-Diagramm an:
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()
Zahl: 5. Gradverteilung in einem Diagramm mit Informationen zu allen eingehenden und ausgehenden E-Mails zwischen Mitgliedern der Forschungseinrichtung.
In dem resultierenden Diagramm sehen wir die Verteilung der Gradgrade von Knoten: Eine große Anzahl von Knoten hat nur wenige Verbindungen zu Nachbarn, aber es gibt eine kleine Anzahl von großen Knoten, die eine Anzahl von Verbindungen zu anderen haben Teilnehmer ist riesig. Dieser Trend wird als Potenzgesetz der Verteilung bezeichnet und ist sehr typisch für große Netze. Dieses Gesetz kann die Verteilung der Bevölkerung in verschiedenen Städten, die Rangfolge der Websites im Internet und sogar die Verteilung des Wohlstands unter den Menschen beschreiben.
5. Pfad, Durchmesser und durchschnittliche Entfernung in der Grafik
Lassen Sie uns nun feststellen, wie verbunden die Mitglieder unseres Diagramms sind. Lassen Sie uns zunächst über die verschiedenen Arten des Knotenabstands sprechen.
Jede Folge von Kanten, die Knoten verbindet, wird als Pfad bezeichnet. In den meisten Fällen wird in der Forschung ein einfacher Pfad betrachtet, dh ein Pfad ohne Zyklen und sich wiederholende Knoten. Der kürzeste Weg zwischen zwei Knoten wird als geodätische Entfernung bezeichnet. Der längste kürzeste Weg in einem Diagramm wird als Durchmesser bezeichnet, ist jedoch sehr empfindlich gegenüber Abweichungen (eine Kette in einem Diagramm mit mehreren Millionen Dollar kann seinen Durchmesser ändern). In gerichteten Graphen kann das Konzept des Durchmessers nur für die Komponente starker Konnektivität verwendet werden, da zur Berechnung des Durchmessers für jedes Knotenpaar ein Pfad zwischen ihnen vorhanden sein muss. In ungerichteten Diagrammen ist es ausreichend, dass die betrachtete Komponente verbunden ist.
Ein weiteres sehr informatives Merkmal ist der durchschnittliche Abstand zwischen Knoten, der erhalten werden kann, indem der Durchschnitt aller kürzesten Pfade im Diagramm genommen wird. Die durchschnittliche Entfernung wird durch die Struktur des Diagramms bestimmt: Wenn das Diagramm in Form einer Kette erstellt wird, ist es groß. Je näher die Knoten miteinander verbunden sind, desto kleiner wird die durchschnittliche Entfernung. Der durchschnittliche Abstand kann sowohl für die stark verbundene Komponente als auch für die schwach verbundene Komponente berechnet werden:
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
Werfen wir einen Blick auf die Ergebnisse. Der Durchmesser zeigt in diesem Fall den maximalen Abstand zwischen zwei Fremden, und hier beträgt dieser Abstand, wie in der bekannten Theorie von sechs Handshakes, 6. Der durchschnittliche Abstand in den Komponenten ist ebenfalls gering, durchschnittlich reichen zwei „Handshakes“ für zwei Fremde. Hier ist auch ein interessantes Phänomen zu erkennen: Der durchschnittliche Abstand in der stark verbundenen Komponente ist geringfügig geringer als in der schwach verbundenen Komponente. Dies kann durch die Tatsache erklärt werden, dass die Richtung der Bindungen für die schwach verbundene Komponente nicht berücksichtigt wird (nur die Tatsache ihres Vorhandenseins). Aus diesem Grund erscheint die Verbindung in der schwachen Komponente dort, wo sie für die starke Komponente nicht vorhanden war.
6. Clustering und Allokation von Communities
Nachdem wir die Abstände zwischen den Teilnehmern herausgefunden haben, gehen wir zu anderen Phänomenen über, die widerspiegeln, wie die Teilnehmer im Diagramm miteinander verbunden sind: Clustering und Communitys.
Der Clusterkoeffizient zeigt, dass zwei Elemente des Graphen, die durch das dritte Element mit hoher Wahrscheinlichkeit verbunden sind, miteinander verbunden sind. Selbst wenn sie nicht verknüpft sind, ist die Wahrscheinlichkeit, dass sie in Zukunft verknüpft werden, viel höher als bei den beiden anderen zufällig ausgewählten Knoten. Dieses Phänomen, das als Clustering oder Transitivität bezeichnet wird, ist in sozialen Graphen äußerst häufig.
Graphen mit einem hohen Grad an Clusterbildung sind durch das Vorhandensein einer signifikanten Anzahl verbundener Tripletts (drei miteinander verbundene Knoten) gekennzeichnet. Sie sind der Baustein vieler sozialer Netzwerke, in denen die Anzahl solcher Dreiecke sehr groß ist. Oft erscheinen nicht einmal Dreiecke, sondern ganze Clusterformationen, sogenannte Communities, die enger miteinander verwandt sind als mit dem Rest des Diagramms.
Schauen wir uns die Clusterbildung und den Clusterkoeffizienten für die schwach verbundene Komponente an:
1. print (': ', nx.transitivity(G_strong))
2. print (' : ', nx.average_clustering(G_strong))
: 0.2201493109315837
: 0.37270757578876434
Für eine Komponente mit starker Konnektivität können wir dieselben Eigenschaften erhalten und auch die Anzahl der zentralen Knoten (Knoten, die am engsten mit dem Rest verwandt sind) und die Anzahl der Knoten an der Peripherie des Diagramms bestimmen:
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
Im zweiten Fall nahmen die Clusterbildung und der Clusterkoeffizient zu, was darauf zurückzuführen ist, dass die stark verbundene Komponente eine größere Anzahl verbundener Tripletts enthält. Versuchen wir gemeinsam, die Hauptgemeinschaften in der lose gekoppelten Komponente zu definieren:
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
In der Spalte mit E-Mails können also 8 Communities unterschieden werden, die enger miteinander verwandt sind als mit dem Rest der Spalte. Die kleinste der Gemeinden hat 54 Mitglieder und die größte 188 Mitglieder. Bei Netzwerken mit überlappenden oder verschachtelten Communitys kann es schwieriger sein, die optimale Partitionierung zu ermitteln. Daher kann sich die Zusammensetzung der Communitys bei jeder Ausführung des Codes unterscheiden. Sehen wir uns die Visualisierung für die Aufteilung an, die wir erhalten haben:
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()
Zahl: 6. Anzeige verschiedener Communities in einer lose gekoppelten Komponente mit Informationen zu allen eingehenden und ausgehenden E-Mails zwischen Mitgliedern der Forschungseinrichtung.
In der obigen Grafik sehen wir die Verteilung der Teilnehmer nach Community, wobei die Farbe der Knoten die Zugehörigkeit zu einer bestimmten Community beschreibt.
7. Gegenseitigkeit der Bindungen
Neben den bereits beschriebenen Eigenschaften gibt es auch eine Reziprozität in einem gerichteten Netzwerk. Diese Eigenschaft beschreibt, wie viel Prozent der ausgehenden Links eine eingehende Rückmeldung haben. Um dies herauszufinden, verwenden wir die Sonderfunktion total_reciprocity der networkx-Bibliothek und untersuchen den Grad der Reziprozität im Diagramm und seinen Komponenten:
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
In 71% der Fälle erhielten Benutzer Antworten auf ihre Nachrichten in der Komponente für starke Konnektivität. Für die schwach verbundene Komponente und den gesamten Graphen insgesamt ist der Pegel vorhersehbar niedriger.
8. Universelle Eigenschaften von Netzwerken
Zusammenfassend lässt sich sagen, dass komplexe Netzwerke im Allgemeinen bestimmte Eigenschaften aufweisen und einige für viele Netzwerke charakteristisch sind. Unsere Analyse des E-Mail-Datensatzes unterstützt diese Trends gut:
- . , , . : web-, , , (Wikipedia, Microsoft). , .
- . , , « ». : , .
- , , : 80% , . – , , . , , .
- , . , .
Wir haben alle oben aufgeführten Trends für einen Datensatz mit E-Mail-Korrespondenz analysiert und bestätigt: In der Grafik wurde eine große verbundene Komponente gefunden, die mehr als 80% aller Knoten enthält. Innerhalb dieser Komponente waren die meisten Knoten durch eine kleine Anzahl gekennzeichnet, es gab jedoch einen kleinen Prozentsatz von Teilnehmern, die eine große Anzahl von Nachbarn hatten. Wir haben auch gesehen, dass der Durchmesser und der durchschnittliche Abstand zwischen den Teilnehmern in der Grafik gering sind: Der durchschnittliche Abstand in der schwach verbundenen Komponente mit 986 Teilnehmern betrug nur 2,1, was bedeutet, dass die meisten Teilnehmer nach nur zwei "Handshakes" miteinander verbunden sind. Darüber hinaus zeichnet sich die Grafik durch ein hohes Maß an Reziprozität aus: 69% aller Teilnehmer pflegten einen wechselseitigen Kontakt miteinander.
Anmerkungen
Der vollständige Text der Studie ist im Buch von Nikolai Viktorovich Ursul "Die ganze Wahrheit über Forex" (2019) zu finden.
Die Forschung wird im Artikel "Die Anwendung der Analyse sozialer Netzwerke auf Rechnungslegung und Abschlussprüfung" beschrieben. Slobodan Kacanski, Dean Lusher (2017, Link ).