Hallo, wir werden uns diesmal weiterhin mit der Graphentheorie befassen, einer Netzwerkanalyse im vorherigen Artikel](https://qiita.com/b_aka/items/9020e3237ff1a3e676e4).
Im vorherigen Artikel haben wir das Netzwerk der Pokemon Sword Shield Rank Battle-Partys visualisiert. Dieses Mal werde ich tatsächlich mit der Analyse beginnen.
Der diesmal verwendete Code und die Daten finden Sie in This Github Repository.
Der vollständige Code ist hier [https://github.com/moxak/pokemon-rankbattle-network-analysis/blob/master/002.ipynb]
Wie der Titel schon sagt, möchte ich jeden Knoten des Pokemon Swordsman Party Building Network gruppieren. Wir möchten auch wichtige Knoten erfassen, indem wir das Konzept der Zentralität vor dem Clustering einführen.
Wenn Sie so etwas tun können, haben Sie Ihr Ziel erreicht.
In der Netzwerktheorie gibt es eine Zentralität (Graphentheorie).
Die Zentralität ist ein Indikator zum Bewerten und Vergleichen der Wichtigkeit jedes Scheitelpunkts in einem Netzwerk.
[Network Analysis 2nd Edition Lernen mit R Data Science](https://www.amazon.co.jp/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF % E3% 83% BC% E3% 82% AF% E5% 88% 86% E6% 9E% 90-% E7% AC% AC2% E7% 89% 88-R% E3% 81% A7% E5% AD% A6% E3% 81% B6% E3% 83% 87% E3% 83% BC% E3% 82% BF% E3% 82% B5% E3% 82% A4% E3% 82% A8% E3% 83% B3% E3% 82% B9-% E9% 88% B4% E6% 9C% A8-% E5% 8A% AA / dp / 4320113152 / ref = sr_1_4? __Mk_ja_JP =% E3% 82% AB% E3% 82% BF% E3 % 82% AB% E3% 83% 8A & dchild = 1 & keywords =% E3% 83% 8D% E3% 83% 83% E3% 83% 88% E3% 83% AF% E3% 83% BC% E3% 82% AF% Von E5% 88% 86% E6% 9E% 90 & sr = 8-4)
Dies ist ein Versuch, mathematisch abzuleiten, wie zentral = ** wichtig ** jeder Knoten im Netzwerk ist.
Dieses Mal möchte ich diese Theorie verwenden, um die Wichtigkeit jedes Knotens im Netzwerk zu berechnen.
Es gibt jedoch tatsächlich viele Arten dieser Zentralität.
Die erste Zentralität ist die Ordnungszentralität.
Die Reihenfolge ist die Anzahl der Kanten, die der Knoten hat. Die Anzahl der Bestellungen wird so wie sie ist zentral.
Je mehr Knoten verbunden sind, desto wichtiger ist es! Obwohl es sich um eine grundlegende Zentralität handelt, die auf der Idee basiert, habe ich das Gefühl, dass dies häufig zu Dingen führt, die nicht intuitiv sind.
Als nächstes folgen die Zentralität und Exzentrizität der Nähe, die die Zentralität aus der Entfernung von anderen Knoten ableiten.
Je näher Sie dem Zentrum des Netzwerks sind, desto wichtiger ist es! Das ist die Idee.
Die Näherungszentralität nimmt die Umkehrung der Gesamtentfernung vom eigenen Knoten zu anderen Knoten und die Exzentrizität die Umkehrung der maximalen Entfernung vom eigenen Knoten zu anderen Knoten.
Da die Ergebnisse beider Entfernungsnutzungen sehr ähnlich sind, möchte ich diesmal die Proximity Centrality verwenden.
Die am häufigsten verwendete (glaube ich) ist die vermittelte Zentralität.
Einfach ausgedrückt ist die Idee, dass je häufiger auf der kürzesten Route gelegen, desto wichtiger ist es (Relaisierbarkeit).
Ein Knoten mit einem hohen Vermittlungszentrum in einem Community-Netzwerk bedeutet, dass er nicht in der Lage ist, auf eine andere Community zuzugreifen, ohne diesen Knoten zu durchlaufen, was intuitiv wichtig zu sein scheint. Ich hoffe, dass Sie das verstehen können.
Die Eigenvektorzentralität unterscheidet sich stark von den vier bisher eingeführten Zentralitäten, und es ist eine Zentralität, die die Idee einführt, "mit welchem Knoten verbunden ist".
Unter Einbeziehung der Idee, dass "mit wichtigen Knoten verbundene Knoten wichtiger sind", wird der Prozess des Hinzufügens der Zentralitäten anderer mit sich selbst verbundener Knoten wiederholt und der konvergierte Wert als Zentralität festgelegt.
Von den Google-Gründern Larry Page und Sergei Brin entwickelte Zentralität.
Die Grundidee ist dieselbe wie die Eigenvektorzentralität. Um zu verstehen, was anders ist, müssen wir das Problem der Eigenvektorzentralität kennen.
Angenommen, Sie haben einen Knoten in Ihrem Netzwerk, der keine Kanten von anderen Knoten aufweist. Die Zentralität dieses Knotens ist natürlich 0. Das ist soweit in Ordnung, aber der nächste ist etwas knifflig. Angenommen, Sie haben einen Knoten i, der nur mit einem solchen Knoten verbunden ist. Natürlich ändert sich die Zentralität von i nicht von den verbundenen Knoten, so dass die Zentralität von i auch 0 ist. Ich denke, das ist nicht intuitiv.
Angenommen, Sie haben einen Knoten i, der mit einem Knoten j verbunden ist, der eine enorme Zentralität aufweist. In dem Konzept der Eigenvektorzentralität geht die Zentralität des Knotens j zum Knoten i über, aber der Knoten i ist nur einer von vielen Knoten, an die der Knoten j eine Kante anfügt. Sollte die gesamte Zentralität des Knotens j auf den Knoten i übertragen werden?
Der Seitenrang ist ein Zentralitätsindex, der diese Probleme bis zu einem gewissen Grad löst.
Es wurde zur Grundlage des Google-Suchalgorithmus und wird weiterhin zur Berechnung des Impact Factors von Papieren verwendet.
Die Daten, die verwendet werden, um die Zentralität abzuleiten, sind die Daten "Pokemon-Rangliste, die zusammen übernommen werden sollen" und die Adoptionsrangdaten der Rangschlacht des Pokemon-Schwertschilds aus der vorherigen Zeit. Wir werden das Netzwerk analysieren, das aus den 100 besten Tieren im Rekrutierungsranking besteht.
df = pd.read_csv(FILEPATH_TEMOTI_POKEMON), encoding='utf-8')
df_rank = pd.read_csv(FILEPATH_ADO_RANK, encoding='utf-8')
df.columns = ['Season', 'Rule', 'Pokemon_From', 'Pokemon_To', 'Weight']
df['Weight'] = 10-df['Weight']
df_season11_double = df[(df['Season']==11)&(df['Rule']=='Double')]
df_season11_double = df_season11_double.drop(['Season', 'Rule'], axis=1)
#Begrenzt auf die Top 100 Rekrutierungsraten
df_season11_double = df_season11_double[df_season11_double['Pokemon_From'].isin(list(df_rank['Pokemon'])[:100])]
df_season11_double = df_season11_double[df_season11_double['Pokemon_To'].isin(list(df_rank['Pokemon'])[:100])]
df_season11_double.to_csv(OUTPUT_FILEPATH', index=False)
df_season11_double
index | Pokemon_From | Pokemon_To | Weight |
---|---|---|---|
91394 | Eidechse | Kyukon | 9 |
91395 | Eidechse | Tritodon | 8 |
91396 | Eidechse | Pippi | 7 |
91397 | Eidechse | Terrakion | 6 |
91398 | Eidechse | Yami Lami | 5 |
504 rows × 3 columns
Erstellen Sie ein Netzwerk aus den oben erstellten Daten.
import networkx as nx
network_np = df_season11_double.values
G = nx.DiGraph()
G.add_weighted_edges_from(network_np)
degree_centers = nx.degree_centrality(G)
df_dc = pd.DataFrame(sorted(degree_centers.items(), key=lambda x: x[1], reverse=True), columns=['Pokemon', 'Degree centrality'])
df_dc.head(10)
index | Pokemon | Degree centrality |
---|---|---|
0 | Ulaos | 0.500000 |
1 | Talonflame | 0.490291 |
2 | Achilleine | 0.451456 |
3 | Moro Fass | 0.419903 |
4 | Windig | 0.359223 |
5 | Samayor | 0.308252 |
6 | Oronge | 0.293689 |
7 | Laplace | 0.291262 |
8 | Eidechse | 0.269417 |
9 | Natley | 0.237864 |
close_centers = nx.closeness_centrality(G)
df_cc = pd.DataFrame(sorted(close_centers.items(), key=lambda x: x[1], reverse=True), columns=['Pokemon', 'Closeness centrality'])
df_cc.head(10)
index | Pokemon | Closeness centrality |
---|---|---|
0 | Ulaos | 0.648440 |
1 | Talonflame | 0.646345 |
2 | Achilleine | 0.628081 |
3 | Moro Fass | 0.612691 |
4 | Windig | 0.594483 |
5 | Samayor | 0.572371 |
6 | Laplace | 0.562711 |
7 | Oronge | 0.551085 |
8 | Pippi | 0.545078 |
9 | Natley | 0.545078 |
between_centers = nx.betweenness_centrality(G)
df_bc = pd.DataFrame(sorted(between_centers.items(), key=lambda x: x[1], reverse=True), columns=['Pokemon', 'Betweenness centrality'])
df_bc.head(10)
index | Pokemon | Betweenness centrality |
---|---|---|
0 | Kyukon | 0.046012 |
1 | persisch | 0.036945 |
2 | Tritodon | 0.028901 |
3 | Eidechse | 0.025690 |
4 | Terrakion | 0.021207 |
5 | Gracia | 0.019807 |
6 | Sandbrot | 0.018529 |
7 | Achilleine | 0.013435 |
8 | Nyai King | 0.011381 |
9 | Eleard | 0.009867 |
eigen_centers = nx.eigenvector_centrality_numpy(G)
df_ec = pd.DataFrame(sorted(eigen_centers.items(), key=lambda x: x[1], reverse=True), columns=['Pokemon', 'Eigen centrality'])
df_ec.head(10)
index | Pokemon | Eigen centrality |
---|---|---|
0 | Ulaos | 0.374252 |
1 | Achilleine | 0.362932 |
2 | Talonflame | 0.341690 |
3 | Moro Fass | 0.332555 |
4 | Samayor | 0.297832 |
5 | Windig | 0.292263 |
6 | Patch Ragon | 0.261000 |
7 | Natley | 0.259066 |
8 | Pippi | 0.237895 |
9 | Laplace | 0.218322 |
pageranks = nx.pagerank(G)
df_pr = pd.DataFrame(sorted(pageranks.items(), key=operator.itemgetter(1),reverse = True), columns=['Pokemon', 'Page Rank'])
df_pr.head(10)
Ich habe versucht, die Beschriftungsschrift des Knotens mit großer Zentralität zu erhöhen.
Ich habe die veröffentlichten Rankings und jeden Zentralitätsindex angeordnet.
In der Rangliste, die auf die Top 100 Tiere und die Top 10 Tiere im kombinierten Rang eingegrenzt ist, ist zu sehen, dass Ulaos in jedem Index höher ist als der signifikant veröffentlichte Rang. (Das Gefühl, überbewertet zu sein)
Von nun an werden wir den Seitenrang verwenden.
Es ist endlich vorbei. Ich möchte auf das Clustering von Netzwerkstrukturen eingehen, das Gegenstand dieser Zeit ist.
Es gibt verschiedene Clustering-Methoden (Community-Extraktion), z. B. solche, die die zuvor abgeleitete Mediationszentralität und Eigenvektorzentralität, Informationszentralität, Spinglass-Methode und Random Walk verwenden und diesmal nicht eingeführt werden.
Dieses Mal habe ich der Ableitung der Zentralität eine beträchtliche Menge an Text gewidmet, daher möchte ich die Ausführung der Clusterbildung durch jede Zentralität und den Vergleich der Ergebnisse einer anderen Gelegenheit überlassen.
Beeil dich diesmal. Das Clustering erfolgt mit der hier beschriebenen Methode (Paper, Implementation Library).
Diese Methode ist ein Indikator für die Netzwerkdichte (Modularität. A9% E3% 83% AA% E3% 83% 86% E3% 82% A3))) ist eine Methode zur maximalen Division und unterscheidet sich von k-means dadurch, dass die Anzahl der Cluster nicht im Voraus angegeben werden muss. es gibt.
Gerichtete Diagramme können in dieser Implementierung nicht verwendet werden, daher werden sie in ungerichtete Diagramme konvertiert.
#Konvertieren Sie ein gerichtetes Diagramm in ein ungerichtetes Diagramm
G2 = nx.Graph(G)
import community
partition = community.best_partition(G2)
partition2 = {}
for i in partition.keys():
sub_dict = {'community' : partition[i]}
partition2[i] = sub_dict
labels = dict([(i, str(i)) for i in range(nx.number_of_nodes(G2))])
labels2 = {}
for i in range(len(labels)):
sub_dict = {'labels' : labels[i]}
labels2[list(partition.keys())[i]] = sub_dict
nx.set_node_attributes(G2, labels2)
nx.set_node_attributes(G2, partition2)
nx.write_gml(G2, ".//community.gml")
pd.DataFrame.from_dict(labels2).T.to_csv('.//community_labels.csv')
Als Ergebnis der Clusterbildung wurden 6 Cluster extrahiert. Werfen wir einen Blick auf jeden Cluster.
df_pagerank = pd.DataFrame(sorted(pageranks.items(), key=operator.itemgetter(1),reverse = True), columns=['Pokemon', 'Page Rank'])
df_community = pd.concat([pd.DataFrame.from_dict(labels2).T, pd.DataFrame.from_dict(partition2).T], axis=1)
df_community = df_community.reset_index()
df_community.columns = ['Pokemon', 'label', 'community']
df_pagerank_community = pd.merge(left=df_pagerank, right=df_community, on = 'Pokemon')
Überprüfen Sie die Abbildung unten des in jedem Cluster klassifizierten Pokémon.
df_pagerank_community.groupby('community').count()['Pokemon'].plot.bar(rot=0, alpha=0.75)
Sie können sehen, dass Cluster 3 fast 30% der Gesamtmenge ausmacht.
Werfen wir einen Blick auf den Inhalt jedes Clusters.
df_pagerank_community[df_pagerank_community['community']==0].head(10)
index | Pokemon | Page Rank | label | community |
---|---|---|---|---|
13 | Eidechse | 0.013742 | 0 | 0 |
18 | Tritodon | 0.007309 | 2 | 0 |
19 | Sekitanzan | 0.006604 | 32 | 0 |
20 | Kyukon | 0.006319 | 1 | 0 |
30 | Yami Lami | 0.002842 | 5 | 0 |
42 | Manöver | 0.001501 | 68 | 0 |
46 | Nura | 0.001235 | 55 | 0 |
53 | Kovalon | 0.001133 | 56 | 0 |
61 | Leafia | 0.000935 | 30 | 0 |
69 | Dorf | 0.000789 | 69 | 0 |
Ist es ein sonniger Tag im Zentrum von Lizardon Kyukon? Lizardon steht an erster Stelle in der Zentralität, und Tritodon, das eine hervorragende Kompatibilität mit Lizardon aufweist, steht an zweiter Stelle.
df_pagerank_community[df_pagerank_community['community']==1].head(10)
index | Pokemon | Page Rank | label | community |
---|---|---|---|---|
8 | Pippi | 0.033903 | 3 | 1 |
16 | Polygon Z. | 0.012646 | 27 | 1 |
17 | Terrakion | 0.009129 | 4 | 1 |
41 | persisch | 0.001544 | 33 | 1 |
80 | Rentler | 0.000630 | 64 | 1 |
81 | Ennute | 0.000629 | 92 | 1 |
Als nächstes waren Cluster 1 diese 6 Tiere. Das Polygon Z, das Superwärmeleistung erzeugen kann, wurde nach dem hellen Steinpippi mit extrem hoher Stützleistung und dem Anpassungsdimax klassifiziert. Der Eindruck ist, dass es viele vielseitige Pokémon gibt, die auf jeder Party eingesetzt werden können.
df_pagerank_community[df_pagerank_community['community']==2].head(10)
index | Pokemon | Page Rank | label | community |
---|---|---|---|---|
7 | Natley | 0.038186 | 6 | 2 |
24 | Nymphia | 0.005511 | 20 | 2 |
28 | Peripper | 0.003061 | 57 | 2 |
29 | Wonoragon | 0.002859 | 46 | 2 |
32 | König Dora | 0.002468 | 49 | 2 |
33 | Nyorotono | 0.002321 | 47 | 2 |
35 | Runpapa | 0.002233 | 50 | 2 |
37 | Gamageroge | 0.001736 | 58 | 2 |
38 | Chevalgo | 0.001626 | 59 | 2 |
39 | Matadogas | 0.001572 | 44 | 2 |
Cluster 2 ist leicht zu verstehen, es ist ein Regenpa, das Peripper, Kingdora, Runpapa und so weiter enthält. Die Zentralität des Nutrays, die die Verträglichkeit mit dem Wassertyp hervorragend ergänzt, ist hoch. Auch die Tatsache, dass Pokémon wie Chevalgo, die nicht gut mit Flammentypen umgehen können, aus Regenpas bestehen, entspricht meiner Intuition.
df_pagerank_community[df_pagerank_community['community']==3].head(10)
index | Pokemon | Page Rank | label | community |
---|---|---|---|---|
0 | Achilleine | 0.107503 | 7 | 3 |
1 | Talonflame | 0.093996 | 12 | 3 |
4 | Windig | 0.056541 | 15 | 3 |
5 | Patch Ragon | 0.049160 | 16 | 3 |
14 | Duraldon | 0.013730 | 24 | 3 |
15 | Oronge | 0.013617 | 29 | 3 |
21 | Amarjo | 0.006167 | 17 | 3 |
26 | Wogle | 0.003980 | 23 | 3 |
27 | Genger | 0.003799 | 43 | 3 |
34 | Elf | 0.002254 | 28 | 3 |
Cluster 3 scheint sich auf das oberste Meta der Umgebung zu konzentrieren. Wenn Sie sich die Überlegungen zum Partyaufbau ansehen, die im Netz laufen, können Sie oft die Kombination von Achilleine, Firelow und Patchragon als die Konstruktion sehen, die die Ergebnisse hinterlassen hat, also das Pokémon, das einen großen Einfluss auf die doppelte Umgebung der 11. Staffel hatte Ich denke es gibt viele.
df_pagerank_community[df_pagerank_community['community']==4].head(10)
index | Pokemon | Page Rank | label | community |
---|---|---|---|---|
2 | Moro Fass | 0.083762 | 8 | 4 |
3 | Samayor | 0.061276 | 9 | 4 |
9 | Krempe weiter | 0.026956 | 25 | 4 |
11 | Dosaidon | 0.016228 | 21 | 4 |
12 | Dadarin | 0.014804 | 26 | 4 |
22 | Licht Chu | 0.006124 | 13 | 4 |
25 | Garula | 0.005487 | 19 | 4 |
31 | Rassel | 0.002758 | 39 | 4 |
40 | Yadran | 0.001563 | 40 | 4 |
45 | Stringer | 0.001322 | 82 | 4 |
Dieser Cluster ist auch sehr leicht zu verstehen. Samayor und Brimon, die als Triller-Starter fungieren, Dosaidon, Dadarin und Rassel, die als Triller-Angreifer fungieren, und Morobarrel, der als Unterstützung fungiert, werden klassifiziert.
Wenn wir uns die Zentralität ansehen, können wir sehen, dass Morobarrel eine sehr wichtige Rolle spielt.
df_pagerank_community[df_pagerank_community['community']==5].head(10)
index | Pokemon | Page Rank | label | community |
---|---|---|---|---|
6 | Ulaos | 0.045935 | 10 | 5 |
10 | Laplace | 0.024565 | 22 | 5 |
23 | Kuwawa | 0.005706 | 14 | 5 |
36 | Numergon | 0.002140 | 88 | 5 |
50 | Onburn | 0.001201 | 83 | 5 |
55 | Kamex | 0.001056 | 11 | 5 |
63 | Mahip | 0.000880 | 94 | 5 |
90 | Togedemaru | 0.000463 | 93 | 5 |
Der letzte Cluster sind diese 8 Tiere. Was für eine Versammlung sind diese Pokémon? Es war schwierig, mit meinem Wissen zu interpretieren, deshalb warte ich auf Kommentare.
Visualisieren Sie das Netzwerk abschließend mit Cytoscape, das bei der letzten Verwendung bestätigt wurde.
Laden Sie community.gml
von ** Datei> Importieren> Netzwerk aus Datei ** und ** Tabelle aus Datei importieren ** oben (siehe Abbildung unten).
Laden Sie von community_labels.csv
und stellen Sie das angezeigte Dialogfeld wie folgt ein.
Beachten Sie, dass der rote Teil vom Standard geändert werden muss.
Alles, was Sie tun müssen, ist, die Form und Farbe für jeden Cluster zu ändern, indem Sie ** Continuous Mapping ** auf der Registerkarte ** Style ** vollständig nutzen.
Ich habe versucht, das Netzwerk mit der Schriftfarbe als Cluster und der Schriftgröße als Seitenrang zu visualisieren.
Beim nächsten Mal möchte ich nach der optimalen Clustering-Methode für diese Daten suchen.
Wir sehen uns wieder.
© 2020 Pokémon © 1995-2020 Nintendo / Creatures Inc./GAME FREAK Inc. Pocket Monsters, Pokemon und Pokémon sind eingetragene Marken von Nintendo, Creatures und Game Freak.
Recommended Posts