Hálózatelemzés Pythonban – Ki a legfontosabb karakter a Trónok Harcában?5 perc olvasás

Ma a Trónok Harca rajongóinak és a hálózatok iránt érdeklődőnek fogunk érdekességekkel szolgálni. A cikk alapjául szolgált a DataCamp projektje, az adatok pedig ezen a Github repo-n érhetőek el.

A Trónok Harca legfontosabb szereplőjének meghatárázáshoz először is tisztában kell lennünk néhány hálózatelemzéssel kapcsolatos alapfogalommal. Egy hálózat pontokból és az azokat összekötő élekből. A Trónok Harca esetében a pontok a karakterek, az élek pedig az ismeretségi szálak a karakterek között. Az adatbázis készítője akkor nyilvánított két karaktert egymás ismerősének, hogyha a könyvekben a neveik legalább egyszer megjelentek 15 szónyi távolságra egymástól.

Az elemzés legelső lépése a szükséges package-ek importálása és az adatok betöltése. Pythonban hálózatok elemzéséhez a NetworkX könyvtárat tudjuk használni.


import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt

df = pd.read_csv('asoiaf-all-edges.csv')
#Az adatbázisban a neveket kötőjelek választják el, ezt szóközre cserélem
df['Source']=[i.replace('-',' ') for i in df['Source']]
df['Target']=[i.replace('-',' ') for i in df['Target']]

A kapott DataFramebe a df.sample(5) segítségével tudunk betekinteni. Látható, hogy a kapcsolatok típusa Undirected, tehát azt feltételezzük, hogy az ismeretségek kölcsönösek. Directed, azaz irányított gráfról beszélnénk például Twitter követések esetében, ahol a kapcsolatok nem feltétlenül kölcsönösek.

Térjünk rá a cikkben feltett kérdésünkre, hogy ki a Trónok Harca legfontosabb karaktere. Első megközelítésünk az lehet, hogy a legfontosabb karakternek van a legtöbb ismeretsége a sorozat karakterei közül. Ha ezzel definiáljuk a fontosságot, akkor a fokszám-központiság (degree centrality) mérőszám segítségével haszonlíthatjuk össze a karaktereket. Egy pont fokszám-központisága a pont szomszédjainak számának és az összes lehetséges szomszéd számának a hányadosa. (Egy pont szomszédjai azok a pontok, amikkel egy él köti össze). A fokszám-központiság kiszámolásának menete, majd nagyság szerinti rendezése és ábrázolása Pythonban a következőképp kivitelezhető:

#Először egy üres gráfot inicializálunk,
G = nx.Graph() 
#majd beletöltjük az adatokat.
for index, row in df.iterrows():
    G.add_edge(row['Source'],row['Target'],weight=row['weight'])

#Kiszámítjuk a fokszám-központiságot a gráf minden pontjára,
deg_cen= nx.degree_centrality(G)
#majd kiválasztjuk a 10 legnagyobb pontot.
sorted_deg_cen = sorted(deg_cen.items(), key=lambda x: x[1],reverse=True)[0:10]

#Végül pedig ábrázoljuk az értékeket egy oszlopdiagramon
plt.bar(range(len(sorted_deg_cen)), [val[1] for val in sorted_deg_cen], align='center',color='#99b1ff')
plt.xticks(range(len(sorted_deg_cen)), [val[0] for val in sorted_deg_cen])
plt.xticks(rotation=70)

Az ismeretségek számát tekintve tehát Tyrion Lannister a könyvsorozat főszereplője.

A közöttiség (betwenness centrality) egy kicsit más szempontból közelíti meg a fontosság kérdését. A közöttiség mérőszám a ponton áthaladó legrövidebb utak számának és a ponton áthaladó összes utak számának a hányadása. Eszerint a mérőszám szerint azok a pontok számítanak fontosnak, amelyek összekötő kapocsként szolgálnak a többi pont között. Például ha a Lannister család nem hajlandó beszélni a Stark családdal és fordítva, viszont mindkét család hajlandó beszélni Lord Baelish-sel, akkor minden kommunikáció (minden legrövidebb út) a két család között Lord Baelish-en keresztül fog eljutni. Így Lord Baelish-nek magas lenne közöttiség mérőszáma. A betweennes centrality szerint azok a karakterek lesznek fontosak, akik összekötnek más, egymást nem ismerő karaktereket vagy csoportokat.

Az ábráról látható, hogy a közöttiség szemponjából Jon Snow a Trónok Harca legfontosabb karaktere.

Végül pedig használjuk a Networkx beépített funkcióit arra, hogy ábrázoljuk a Trónok Harca legfontosabb szereplőjének kapcsolatait. Itt a fontosságot a fokszám-központiság fogalmával határoztam meg és a 30 legfontosabb szereplőt szerepeltetem az ábrán. Ennél sokkal több (vagy az összes) karakter megjelenítése egy nehezen olvasható és értelmezhető ábrát eredményezne.

#Nagyság szerint rendezzük az előzőleg létrehozott dicionary-t, amiből a 30 legnagyobb elemre vagyunk kíváncsiak
main_char_deg_cen = sorted(deg_cen.items(), key=lambda x: x[1],reverse=True)[0:30]
#A kapott dictionary-ből csak a nevekre van szükségünk
main_chars = [x[0] for x in main_char_deg_cen]

#Létrehozzuk eredeti gráf algráfját, amiben csak az előre meghatározott pontok, azaz a fontos karakterek szerepelnek
main_chars_graph=G.subgraph(main_chars)

#Majd ábrázoljuk az algráfot. A beállítások azt a célt szolgálják, hogy könnyen olvasható legyen az ábra
plt.figure(figsize=(30,20))
nx.draw(main_chars_graph,node_size=500,width=0.4,with_labels=True,alpha=0.6,font_size=36,\
    pos=nx.spring_layout(main_chars_graph,k=1.3,iterations=50),node_color="#99b1ff")

A kapott ábra a Trónok Harca legfontosabb szereplőinek egymással való kapcsolatait szemlélteti.

Leave a Reply

Your email address will not be published. Required fields are marked *