Introduction to Network Analysis - Application (Python)#

Roman Jurowetzki

!pip uninstall python-louvain
Found existing installation: python-louvain 0.16
Uninstalling python-louvain-0.16:
  Would remove:
    /usr/local/bin/community
    /usr/local/lib/python3.7/dist-packages/community/*
    /usr/local/lib/python3.7/dist-packages/python_louvain-0.16.dist-info/*
  Would not remove (might be manually added):
    /usr/local/lib/python3.7/dist-packages/community/app.py
Proceed (y/n)? y
  Successfully uninstalled python-louvain-0.16
!pip install -U python-louvain
Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/
Collecting python-louvain
  Downloading python-louvain-0.16.tar.gz (204 kB)
     |β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ| 204 kB 5.4 MB/s 
?25hRequirement already satisfied: networkx in /usr/local/lib/python3.7/dist-packages (from python-louvain) (2.6.3)
Requirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (from python-louvain) (1.21.6)
Building wheels for collected packages: python-louvain
  Building wheel for python-louvain (setup.py) ... ?25l?25hdone
  Created wheel for python-louvain: filename=python_louvain-0.16-py3-none-any.whl size=9408 sha256=e5fc5bfa9cc9b9a28a194faf4119a7e8db45dba433ad3fb576a7d6903dabce24
  Stored in directory: /root/.cache/pip/wheels/f6/23/43/a714ed84811240ec3e8e709b8594ecdfbc8ad36ca5d949e38e
Successfully built python-louvain
Installing collected packages: python-louvain
Successfully installed python-louvain-0.16
import networkx as nx
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

sns.set()

Network data structures#

  • Below an example of a minimal edge list created by zipping together two lists into a list of tuples.

  • In this case, let us assume this network to be unweighted, meaning a connection can be eiter tresent or absent.

origin = [1, 2, 2, 1, 4]
target = [2, 3, 4, 5, 1]
edge_list = list(zip(origin, target))

print(edge_list)
[(1, 2), (2, 3), (2, 4), (1, 5), (4, 1)]

This can of cause also be a DataFrame where columns indicate origin and target

df = pd.DataFrame({'origin':origin, 'target':target})
df
origin target
0 1 2
1 2 3
2 2 4
3 1 5
4 4 1

The NetowrkX library allows us to do many network-related things in Python. While there are other packages for that, NetworkX remains the most popular choice.

A network can be initiated from a list of tuples (more basic) from numpy arrays or from DataFrames

G = nx.Graph()
G.add_edges_from(edge_list)
G_from_df = nx.from_pandas_edgelist(df, source = 'origin', target = 'target')
print(G.nodes() == G_from_df.nodes())
print(G.edges() == G_from_df.edges())
True
True

Adjacency Matrix#

  • A second popular form of network representation is the adjacency-matrix (also called socio-matrix).

  • It is represented as a \(n*n\) matrix, where \(n\) stands for the number of elements of which their relationships should be represented.

  • The value in the cell that intercepts row \(n\) and column \(m\) indicates if an edge is present (=1) or absent (=0).

  • Tip: Given an edgelist, an adjacency matrix can easily be produced by crosstabulating:

df_cros = pd.crosstab(df.origin, df.target)
df_cros
target 1 2 3 4 5
origin
1 0 1 0 0 1
2 0 0 1 1 0
4 1 0 0 0 0
idx = df_cros.columns.union(df_cros.index)
df_adj_asy = df_cros.reindex(index = idx, columns=idx, fill_value=0)
df_adj_asy
1 2 3 4 5
1 0 1 0 0 1
2 0 0 1 1 0
3 0 0 0 0 0
4 1 0 0 0 0
5 0 0 0 0 0
nx.to_pandas_adjacency(G)
1 2 3 4 5
1 0.0 1.0 0.0 1.0 1.0
2 1.0 0.0 1.0 1.0 0.0
3 0.0 1.0 0.0 0.0 0.0
4 1.0 1.0 0.0 0.0 0.0
5 1.0 0.0 0.0 0.0 0.0
df_adj_asy + df_adj_asy.T
1 2 3 4 5
1 0 1 0 1 1
2 1 0 1 1 0
3 0 1 0 0 0
4 1 1 0 0 0
5 1 0 0 0 0
from scipy import sparse
sparse_df = sparse.csr_matrix(df_adj_asy)
print(sparse_df)
  (0, 1)	1
  (0, 4)	1
  (1, 2)	1
  (1, 3)	1
  (3, 0)	1
edge_list
[(1, 2), (2, 3), (2, 4), (1, 5), (4, 1)]

Nodelists#

  • Edgelists as well as adjacency matrices only stores connectivity pattern between nodes, but due to their structure cannot store informations on the nodes in which we might be interested.

  • Therefore, we in many cases also provide a a node list with these informations (such as the names of the nodes or any kind of groupings).

name = ["Jesper", "Pernille", "Jacob", "Dorte", "Donald"]
sex = ["M", "F", "M", "F", "M"]
group = ["A", "B", "B", "A", "C"]

node_list = pd.DataFrame({'name':name, 'sex':sex, 'group':group})
node_list
name sex group
0 Jesper M A
1 Pernille F B
2 Jacob M B
3 Dorte F A
4 Donald M C

NetworkX Graphs#

We have already seen a sneak-preview of NetworkX functionality

There are many weays to create various types of Graph objects in NetworkX and I’d advise you to have a look at the documentation

Let’s combine the data from above and create a graph. While it is easy to create a graph from an edgelist it cannot be inferred from a nodelist directly.

dict(enumerate(name))
{0: 'Jesper', 1: 'Pernille', 2: 'Jacob', 3: 'Dorte', 4: 'Donald'}
mapper = dict(enumerate(name, 1))

print(mapper)
{1: 'Jesper', 2: 'Pernille', 3: 'Jacob', 4: 'Dorte', 5: 'Donald'}
print([mapper[x] for x in origin])

origin = [mapper[x] for x in origin]
target = [mapper[x] for x in target]
['Jesper', 'Pernille', 'Pernille', 'Jesper', 'Dorte']
edge_list = list(zip(origin, target))

print(edge_list)
[('Jesper', 'Pernille'), ('Pernille', 'Jacob'), ('Pernille', 'Dorte'), ('Jesper', 'Donald'), ('Dorte', 'Jesper')]
G = nx.Graph()
G.add_edges_from(edge_list)
node_attr = node_list.set_index('name').to_dict('index')
node_attr
{'Jesper': {'sex': 'M', 'group': 'A'},
 'Pernille': {'sex': 'F', 'group': 'B'},
 'Jacob': {'sex': 'M', 'group': 'B'},
 'Dorte': {'sex': 'F', 'group': 'A'},
 'Donald': {'sex': 'M', 'group': 'C'}}
nx.set_node_attributes(G, node_attr)
G.nodes(data=True)
NodeDataView({'Jesper': {'sex': 'M', 'group': 'A'}, 'Pernille': {'sex': 'F', 'group': 'B'}, 'Jacob': {'sex': 'M', 'group': 'B'}, 'Dorte': {'sex': 'F', 'group': 'A'}, 'Donald': {'sex': 'M', 'group': 'C'}})
G.edges()
EdgeView([('Jesper', 'Pernille'), ('Jesper', 'Donald'), ('Jesper', 'Dorte'), ('Pernille', 'Jacob'), ('Pernille', 'Dorte')])
len(G.nodes())
5
# Not pretty at all
plt.figure(figsize=(5,5)) 
nx.draw_kamada_kawai(G, with_labels = True)
../_images/networks_hands_on_in_python_42_0.png
G['Jacob']
AtlasView({'Pernille': {}})
G['Jesper']
AtlasView({'Pernille': {}, 'Donald': {}, 'Dorte': {}})
G.nodes()['Jesper']
{'sex': 'M', 'group': 'A'}
[node for node, data in G.nodes(data=True) if data['sex'] == 'F']
['Pernille', 'Dorte']
node_list[node_list.sex == 'F'].name
1    Pernille
3       Dorte
Name: name, dtype: object
G_sub = nx.subgraph(G, node_list[node_list.sex == 'F'].name)
pd.DataFrame.from_dict(dict(G.nodes(data=True)), orient='index')
sex group
Jesper M A
Pernille F B
Jacob M B
Dorte F A
Donald M C

Network analysis and measures#

# Generate sample small world network
g = nx.watts_strogatz_graph(200, 3 , 5)
# Quick visualization
nx.draw(g, with_labels = False, node_size=10)
../_images/networks_hands_on_in_python_52_0.png

Node level measures#

Centralities can be easily created on node level various centrality algorithms.

centrality_dgr = nx.degree_centrality(g)
centrality_eigen = nx.eigenvector_centrality_numpy(g)
centrality_between = nx.betweenness_centrality(g)
nd_attrb_df = pd.DataFrame({'centrality_dgr':centrality_dgr,
                           'centrality_eigen':centrality_eigen,
                           'centrality_between':centrality_between})
nd_attrb = nd_attrb_df.to_dict('index')
nx.set_node_attributes(g, nd_attrb)
# Degree centrality
nx.draw(g, with_labels = False, node_size=[v * 5000 for v in centrality_dgr.values()])
../_images/networks_hands_on_in_python_58_0.png
# Eigenvalue centrality
nx.draw(g, with_labels = False, node_size=[v * 500 for v in centrality_eigen.values()])
../_images/networks_hands_on_in_python_59_0.png
# Betweenness centrality
nx.draw(g, with_labels = False, node_size=[v * 500 for v in centrality_between.values()])
../_images/networks_hands_on_in_python_60_0.png

Clustering (Community detection)#

  • Clustering algorithms are similar to UML algorithms in traditional ML - there are many diffrent approaches and the data structure is often the determinant of what is makes sense and should be used.

  • While there are several community detection algorithms in the NetworkX library, one of the most known and used - the Louvain algorithm is maintained as an own package (http://python-louvain.readthedocs.io/)

  • It is used in a very similar fashion to other functions in NetworkX and returns similar objects.

G = nx.random_partition_graph(np.random.randint(15,18,5), 0.75, 0.05)
nx.draw_kamada_kawai(G, node_size=10)
../_images/networks_hands_on_in_python_63_0.png
import community as community_louvain
partition = community_louvain.best_partition(G)
nx.set_node_attributes(G, partition, 'partition')
nx.draw_kamada_kawai(G, node_color=list(partition.values()))
../_images/networks_hands_on_in_python_67_0.png

Neighborhood of a Node#

  • Lets check the size of all nodes neighborhood at distance 2.

g1 = nx.ego_graph(G, 1, radius=2)
g50 = nx.ego_graph(G, 50, radius=2)
g1_df = pd.DataFrame.from_dict(dict(g1.nodes(data=True)), orient='index')
g50_df = pd.DataFrame.from_dict(dict(g50.nodes(data=True)), orient='index')
nx.draw_kamada_kawai(g1, node_color=g1_df.partition)
../_images/networks_hands_on_in_python_71_0.png
nx.draw_kamada_kawai(g50, node_color=g50_df.partition)
../_images/networks_hands_on_in_python_72_0.png

(Global) Network structure#

  • Finally, it is often also informative to look at the overal characteristics of the network. We will do this in more detail next time, but just so you know:

  • The density of a measure represents the share of all connected to all possible connections in the network

nx.density(G)
0.18337850045167117

Transistivity, also called the Clustering Cefficient indicates how much the network tends to be locally clustered.

  • That is measured by the share of closed triplets. Again, we will dig into that next time.

nx.transitivity(G)
0.499595235341737
  • The diameter is the longest of the shortest paths between two nodes of the network.

nx.diameter(G)
3
  • Finally, the mean distance, or average path lenght represents the mean of all shortest paths between all nodes. It is a measure of diffusion potential within a network.

nx.average_shortest_path_length(G)
2.0499849442938873

Case: Networks are coming…#

  • So, lets get serious. Appropriate for the weather these days in Denmark, the theme is β€œwinter is comming…”.

  • Therefore, we will have some fun analysing the Game of Thrones data provided by Andrew Beveridge.

  • It is a Character Interaction Networks for George R. R. Martin’s β€œA Song of Ice and Fire” saga (yes, we are talking about the books…).

  • These networks were created by connecting two characters whenever their names (or nicknames) appeared within 15 words of one another in one of the books in β€œA Song of Ice and Fire.”

  • The edge weight corresponds to the number of interactions.

  • This is a nice skill you will have after the second part of M2 on your own.

Build the graph#

  • First, we load all nodes, representing all characters appearing in the books:

edges = pd.read_csv('https://sds-aau.github.io/SDS-master/00_data/GoT_network/asoiaf-all-edges.csv')
edges.head()
Source Target Type id weight
0 Addam-Marbrand Brynden-Tully Undirected 0 3
1 Addam-Marbrand Cersei-Lannister Undirected 1 3
2 Addam-Marbrand Gyles-Rosby Undirected 2 3
3 Addam-Marbrand Jaime-Lannister Undirected 3 14
4 Addam-Marbrand Jalabhar-Xho Undirected 4 3
edges.columns = [w.lower() for w in edges.columns]
  • So, that’s what we have, a classical edgelist, with id1 in column 1 and id2 in column2.

  • Note, the edges are in this case weighted.

Ok, lets see how many characters we have overall.

pd.concat([edges['source'],edges['target']], axis=0).nunique()
796
len(set(edges['source']) | set(edges['target']))
796
  • Because there are so many characters in the books, many of them minor,

  • I am subsetting the data to the 100 characters with the most interactions across all books.

  • The edges are undirected, therefore there are no redundant Source-Target combinations.

  • Because of this, I pivot Source and Target data before summing up the weights.

edges_melt = pd.melt(edges, id_vars=['id','weight'], value_vars=['source', 'target'], 
        var_name='role', value_name='name')

edges_melt.head()
id weight role name
0 0 3 source Addam-Marbrand
1 1 3 source Addam-Marbrand
2 2 3 source Addam-Marbrand
3 3 14 source Addam-Marbrand
4 4 3 source Addam-Marbrand
edges_melt.groupby('name').weight.sum().sort_values(ascending=False)
name
Tyrion-Lannister      2873
Jon-Snow              2757
Cersei-Lannister      2232
Joffrey-Baratheon     1762
Eddard-Stark          1649
                      ... 
Garth-Tyrell             3
Hugh                     3
Old-Bill-Bone            3
Owen-Merryweather        3
Torwold-Browntooth       3
Name: weight, Length: 796, dtype: int64
chars_main = edges_melt.groupby('name').weight.sum().sort_values(ascending=False).index[:100]
  • So far so good, if we only go by edge weights,

  • Lets reduce our edgelist to this main characters, just to warm up and keep the overview.

edges = edges[(edges.source.isin(chars_main)) & (edges.target.isin(chars_main))]

Now we can convert that into a NetowkrX graph

g = nx.from_pandas_edgelist(edges, source='source', target='target', edge_attr='weight')
# no need to filter for parallel edges and seems there are no isolates (degree 0 nodes)
list(nx.isolates(g))
[]
g.edges(data=True)
EdgeDataView([('Aemon-Targaryen-(Maester-Aemon)', 'Alliser-Thorne', {'weight': 7}), ('Aemon-Targaryen-(Maester-Aemon)', 'Bowen-Marsh', {'weight': 4}), ('Aemon-Targaryen-(Maester-Aemon)', 'Eddison-Tollett', {'weight': 3}), ('Aemon-Targaryen-(Maester-Aemon)', 'Gilly', {'weight': 20}), ('Aemon-Targaryen-(Maester-Aemon)', 'Grenn', {'weight': 5}), ('Aemon-Targaryen-(Maester-Aemon)', 'Janos-Slynt', {'weight': 5}), ('Aemon-Targaryen-(Maester-Aemon)', 'Jeor-Mormont', {'weight': 25}), ('Aemon-Targaryen-(Maester-Aemon)', 'Jon-Snow', {'weight': 110}), ('Aemon-Targaryen-(Maester-Aemon)', 'Mance-Rayder', {'weight': 5}), ('Aemon-Targaryen-(Maester-Aemon)', 'Pypar', {'weight': 5}), ('Aemon-Targaryen-(Maester-Aemon)', 'Robert-Baratheon', {'weight': 5}), ('Aemon-Targaryen-(Maester-Aemon)', 'Samwell-Tarly', {'weight': 99}), ('Aemon-Targaryen-(Maester-Aemon)', 'Stannis-Baratheon', {'weight': 12}), ('Alliser-Thorne', 'Bowen-Marsh', {'weight': 3}), ('Alliser-Thorne', 'Grenn', {'weight': 3}), ('Alliser-Thorne', 'Janos-Slynt', {'weight': 13}), ('Alliser-Thorne', 'Jeor-Mormont', {'weight': 13}), ('Alliser-Thorne', 'Joffrey-Baratheon', {'weight': 4}), ('Alliser-Thorne', 'Jon-Snow', {'weight': 63}), ('Alliser-Thorne', 'Mance-Rayder', {'weight': 6}), ('Alliser-Thorne', 'Pypar', {'weight': 4}), ('Alliser-Thorne', 'Qhorin-Halfhand', {'weight': 4}), ('Alliser-Thorne', 'Samwell-Tarly', {'weight': 12}), ('Alliser-Thorne', 'Stannis-Baratheon', {'weight': 3}), ('Alliser-Thorne', 'Tyrion-Lannister', {'weight': 15}), ('Bowen-Marsh', 'Eddison-Tollett', {'weight': 12}), ('Bowen-Marsh', 'Janos-Slynt', {'weight': 10}), ('Bowen-Marsh', 'Jeor-Mormont', {'weight': 16}), ('Bowen-Marsh', 'Jon-Snow', {'weight': 60}), ('Bowen-Marsh', 'Mance-Rayder', {'weight': 5}), ('Bowen-Marsh', 'Samwell-Tarly', {'weight': 10}), ('Bowen-Marsh', 'Stannis-Baratheon', {'weight': 3}), ('Bowen-Marsh', 'Tormund', {'weight': 5}), ('Eddison-Tollett', 'Craster', {'weight': 6}), ('Eddison-Tollett', 'Gilly', {'weight': 3}), ('Eddison-Tollett', 'Grenn', {'weight': 13}), ('Eddison-Tollett', 'Janos-Slynt', {'weight': 4}), ('Eddison-Tollett', 'Jeor-Mormont', {'weight': 9}), ('Eddison-Tollett', 'Jon-Snow', {'weight': 41}), ('Eddison-Tollett', 'Pypar', {'weight': 5}), ('Eddison-Tollett', 'Samwell-Tarly', {'weight': 19}), ('Gilly', 'Craster', {'weight': 24}), ('Gilly', 'Jojen-Reed', {'weight': 3}), ('Gilly', 'Jon-Snow', {'weight': 33}), ('Gilly', 'Mance-Rayder', {'weight': 9}), ('Gilly', 'Meera-Reed', {'weight': 3}), ('Gilly', 'Melisandre', {'weight': 7}), ('Gilly', 'Samwell-Tarly', {'weight': 84}), ('Grenn', 'Craster', {'weight': 3}), ('Grenn', 'Jeor-Mormont', {'weight': 13}), ('Grenn', 'Jon-Snow', {'weight': 64}), ('Grenn', 'Pypar', {'weight': 63}), ('Grenn', 'Samwell-Tarly', {'weight': 57}), ('Janos-Slynt', 'Cersei-Lannister', {'weight': 13}), ('Janos-Slynt', 'Eddard-Stark', {'weight': 11}), ('Janos-Slynt', 'Joffrey-Baratheon', {'weight': 14}), ('Janos-Slynt', 'Jon-Snow', {'weight': 26}), ('Janos-Slynt', 'Mance-Rayder', {'weight': 6}), ('Janos-Slynt', 'Petyr-Baelish', {'weight': 8}), ('Janos-Slynt', 'Pycelle', {'weight': 3}), ('Janos-Slynt', 'Robert-Baratheon', {'weight': 4}), ('Janos-Slynt', 'Samwell-Tarly', {'weight': 7}), ('Janos-Slynt', 'Sansa-Stark', {'weight': 3}), ('Janos-Slynt', 'Stannis-Baratheon', {'weight': 4}), ('Janos-Slynt', 'Tyrion-Lannister', {'weight': 31}), ('Janos-Slynt', 'Varys', {'weight': 7}), ('Jeor-Mormont', 'Bran-Stark', {'weight': 4}), ('Jeor-Mormont', 'Craster', {'weight': 30}), ('Jeor-Mormont', 'Jon-Snow', {'weight': 174}), ('Jeor-Mormont', 'Jorah-Mormont', {'weight': 3}), ('Jeor-Mormont', 'Mance-Rayder', {'weight': 4}), ('Jeor-Mormont', 'Qhorin-Halfhand', {'weight': 21}), ('Jeor-Mormont', 'Robert-Baratheon', {'weight': 4}), ('Jeor-Mormont', 'Samwell-Tarly', {'weight': 51}), ('Jeor-Mormont', 'Tyrion-Lannister', {'weight': 27}), ('Jon-Snow', 'Arya-Stark', {'weight': 71}), ('Jon-Snow', 'Bran-Stark', {'weight': 90}), ('Jon-Snow', 'Catelyn-Stark', {'weight': 14}), ('Jon-Snow', 'Cersei-Lannister', {'weight': 7}), ('Jon-Snow', 'Craster', {'weight': 36}), ('Jon-Snow', 'Eddard-Stark', {'weight': 65}), ('Jon-Snow', 'Jaime-Lannister', {'weight': 3}), ('Jon-Snow', 'Joffrey-Baratheon', {'weight': 14}), ('Jon-Snow', 'Jory-Cassel', {'weight': 3}), ('Jon-Snow', 'Luwin', {'weight': 10}), ('Jon-Snow', 'Mance-Rayder', {'weight': 112}), ('Jon-Snow', 'Melisandre', {'weight': 57}), ('Jon-Snow', 'Mordane', {'weight': 4}), ('Jon-Snow', 'Pypar', {'weight': 77}), ('Jon-Snow', 'Qhorin-Halfhand', {'weight': 73}), ('Jon-Snow', 'Rickon-Stark', {'weight': 16}), ('Jon-Snow', 'Robb-Stark', {'weight': 91}), ('Jon-Snow', 'Robert-Baratheon', {'weight': 29}), ('Jon-Snow', 'Rodrik-Cassel', {'weight': 3}), ('Jon-Snow', 'Samwell-Tarly', {'weight': 228}), ('Jon-Snow', 'Sansa-Stark', {'weight': 11}), ('Jon-Snow', 'Selyse-Florent', {'weight': 38}), ('Jon-Snow', 'Stannis-Baratheon', {'weight': 91}), ('Jon-Snow', 'Theon-Greyjoy', {'weight': 16}), ('Jon-Snow', 'Tormund', {'weight': 73}), ('Jon-Snow', 'Tyrion-Lannister', {'weight': 56}), ('Jon-Snow', 'Ygritte', {'weight': 80}), ('Mance-Rayder', 'Arya-Stark', {'weight': 3}), ('Mance-Rayder', 'Craster', {'weight': 10}), ('Mance-Rayder', 'Joffrey-Baratheon', {'weight': 5}), ('Mance-Rayder', 'Melisandre', {'weight': 6}), ('Mance-Rayder', 'Pypar', {'weight': 4}), ('Mance-Rayder', 'Qhorin-Halfhand', {'weight': 13}), ('Mance-Rayder', 'Ramsay-Snow', {'weight': 7}), ('Mance-Rayder', 'Samwell-Tarly', {'weight': 10}), ('Mance-Rayder', 'Stannis-Baratheon', {'weight': 16}), ('Mance-Rayder', 'Theon-Greyjoy', {'weight': 9}), ('Mance-Rayder', 'Tormund', {'weight': 32}), ('Mance-Rayder', 'Ygritte', {'weight': 14}), ('Pypar', 'Samwell-Tarly', {'weight': 29}), ('Robert-Baratheon', 'Aerys-II-Targaryen', {'weight': 35}), ('Robert-Baratheon', 'Arya-Stark', {'weight': 17}), ('Robert-Baratheon', 'Asha-Greyjoy', {'weight': 4}), ('Robert-Baratheon', 'Balon-Greyjoy', {'weight': 8}), ('Robert-Baratheon', 'Barristan-Selmy', {'weight': 51}), ('Robert-Baratheon', 'Beric-Dondarrion', {'weight': 5}), ('Robert-Baratheon', 'Bran-Stark', {'weight': 11}), ('Robert-Baratheon', 'Brienne-of-Tarth', {'weight': 3}), ('Robert-Baratheon', 'Catelyn-Stark', {'weight': 27}), ('Robert-Baratheon', 'Cersei-Lannister', {'weight': 134}), ('Robert-Baratheon', 'Daenerys-Targaryen', {'weight': 26}), ('Robert-Baratheon', 'Doran-Martell', {'weight': 3}), ('Robert-Baratheon', 'Drogo', {'weight': 3}), ('Robert-Baratheon', 'Eddard-Stark', {'weight': 334}), ('Robert-Baratheon', 'Gendry', {'weight': 3}), ('Robert-Baratheon', 'Gregor-Clegane', {'weight': 4}), ('Robert-Baratheon', 'Ilyn-Payne', {'weight': 4}), ('Robert-Baratheon', 'Jaime-Lannister', {'weight': 69}), ('Robert-Baratheon', 'Joffrey-Baratheon', {'weight': 64}), ('Robert-Baratheon', 'Jon-Arryn', {'weight': 39}), ('Robert-Baratheon', 'Jon-Connington', {'weight': 8}), ('Robert-Baratheon', 'Jorah-Mormont', {'weight': 10}), ('Robert-Baratheon', 'Jory-Cassel', {'weight': 7}), ('Robert-Baratheon', 'Lancel-Lannister', {'weight': 7}), ('Robert-Baratheon', 'Loras-Tyrell', {'weight': 7}), ('Robert-Baratheon', 'Lysa-Arryn', {'weight': 8}), ('Robert-Baratheon', 'Margaery-Tyrell', {'weight': 5}), ('Robert-Baratheon', 'Meryn-Trant', {'weight': 3}), ('Robert-Baratheon', 'Mordane', {'weight': 7}), ('Robert-Baratheon', 'Myrcella-Baratheon', {'weight': 3}), ('Robert-Baratheon', 'Petyr-Baelish', {'weight': 30}), ('Robert-Baratheon', 'Pycelle', {'weight': 29}), ('Robert-Baratheon', 'Renly-Baratheon', {'weight': 80}), ('Robert-Baratheon', 'Rhaegar-Targaryen', {'weight': 48}), ('Robert-Baratheon', 'Robb-Stark', {'weight': 9}), ('Robert-Baratheon', 'Sandor-Clegane', {'weight': 14}), ('Robert-Baratheon', 'Sansa-Stark', {'weight': 35}), ('Robert-Baratheon', 'Stannis-Baratheon', {'weight': 68}), ('Robert-Baratheon', 'Tommen-Baratheon', {'weight': 12}), ('Robert-Baratheon', 'Tyrion-Lannister', {'weight': 42}), ('Robert-Baratheon', 'Tywin-Lannister', {'weight': 29}), ('Robert-Baratheon', 'Varys', {'weight': 44}), ('Robert-Baratheon', 'Viserys-Targaryen', {'weight': 16}), ('Samwell-Tarly', 'Bran-Stark', {'weight': 11}), ('Samwell-Tarly', 'Craster', {'weight': 48}), ('Samwell-Tarly', 'Jojen-Reed', {'weight': 10}), ('Samwell-Tarly', 'Meera-Reed', {'weight': 5}), ('Samwell-Tarly', 'Melisandre', {'weight': 7}), ('Samwell-Tarly', 'Qhorin-Halfhand', {'weight': 6}), ('Samwell-Tarly', 'Robb-Stark', {'weight': 4}), ('Samwell-Tarly', 'Stannis-Baratheon', {'weight': 37}), ('Stannis-Baratheon', 'Asha-Greyjoy', {'weight': 16}), ('Stannis-Baratheon', 'Balon-Greyjoy', {'weight': 8}), ('Stannis-Baratheon', 'Brienne-of-Tarth', {'weight': 5}), ('Stannis-Baratheon', 'Bronn', {'weight': 3}), ('Stannis-Baratheon', 'Catelyn-Stark', {'weight': 24}), ('Stannis-Baratheon', 'Cersei-Lannister', {'weight': 42}), ('Stannis-Baratheon', 'Davos-Seaworth', {'weight': 131}), ('Stannis-Baratheon', 'Eddard-Stark', {'weight': 32}), ('Stannis-Baratheon', 'Jaime-Lannister', {'weight': 12}), ('Stannis-Baratheon', 'Joffrey-Baratheon', {'weight': 45}), ('Stannis-Baratheon', 'Jon-Arryn', {'weight': 13}), ('Stannis-Baratheon', 'Jory-Cassel', {'weight': 3}), ('Stannis-Baratheon', 'Kevan-Lannister', {'weight': 3}), ('Stannis-Baratheon', 'Loras-Tyrell', {'weight': 4}), ('Stannis-Baratheon', 'Lysa-Arryn', {'weight': 4}), ('Stannis-Baratheon', 'Mace-Tyrell', {'weight': 12}), ('Stannis-Baratheon', 'Melisandre', {'weight': 87}), ('Stannis-Baratheon', 'Myrcella-Baratheon', {'weight': 3}), ('Stannis-Baratheon', 'Petyr-Baelish', {'weight': 8}), ('Stannis-Baratheon', 'Pycelle', {'weight': 12}), ('Stannis-Baratheon', 'Ramsay-Snow', {'weight': 8}), ('Stannis-Baratheon', 'Renly-Baratheon', {'weight': 110}), ('Stannis-Baratheon', 'Robb-Stark', {'weight': 22}), ('Stannis-Baratheon', 'Roose-Bolton', {'weight': 18}), ('Stannis-Baratheon', 'Sansa-Stark', {'weight': 11}), ('Stannis-Baratheon', 'Selyse-Florent', {'weight': 41}), ('Stannis-Baratheon', 'Shae', {'weight': 3}), ('Stannis-Baratheon', 'Theon-Greyjoy', {'weight': 10}), ('Stannis-Baratheon', 'Tommen-Baratheon', {'weight': 16}), ('Stannis-Baratheon', 'Tyrion-Lannister', {'weight': 52}), ('Stannis-Baratheon', 'Tywin-Lannister', {'weight': 30}), ('Stannis-Baratheon', 'Varys', {'weight': 10}), ('Aeron-Greyjoy', 'Asha-Greyjoy', {'weight': 7}), ('Aeron-Greyjoy', 'Balon-Greyjoy', {'weight': 17}), ('Aeron-Greyjoy', 'Euron-Greyjoy', {'weight': 27}), ('Aeron-Greyjoy', 'Theon-Greyjoy', {'weight': 20}), ('Aeron-Greyjoy', 'Victarion-Greyjoy', {'weight': 20}), ('Asha-Greyjoy', 'Balon-Greyjoy', {'weight': 15}), ('Asha-Greyjoy', 'Euron-Greyjoy', {'weight': 23}), ('Asha-Greyjoy', 'Theon-Greyjoy', {'weight': 48}), ('Asha-Greyjoy', 'Victarion-Greyjoy', {'weight': 10}), ('Balon-Greyjoy', 'Catelyn-Stark', {'weight': 3}), ('Balon-Greyjoy', 'Eddard-Stark', {'weight': 7}), ('Balon-Greyjoy', 'Euron-Greyjoy', {'weight': 23}), ('Balon-Greyjoy', 'Robb-Stark', {'weight': 11}), ('Balon-Greyjoy', 'Theon-Greyjoy', {'weight': 30}), ('Balon-Greyjoy', 'Tywin-Lannister', {'weight': 4}), ('Balon-Greyjoy', 'Victarion-Greyjoy', {'weight': 17}), ('Euron-Greyjoy', 'Theon-Greyjoy', {'weight': 4}), ('Euron-Greyjoy', 'Victarion-Greyjoy', {'weight': 50}), ('Theon-Greyjoy', 'Arya-Stark', {'weight': 7}), ('Theon-Greyjoy', 'Bran-Stark', {'weight': 64}), ('Theon-Greyjoy', 'Brynden-Tully', {'weight': 6}), ('Theon-Greyjoy', 'Catelyn-Stark', {'weight': 14}), ('Theon-Greyjoy', 'Eddard-Stark', {'weight': 31}), ('Theon-Greyjoy', 'Jaime-Lannister', {'weight': 4}), ('Theon-Greyjoy', 'Jory-Cassel', {'weight': 3}), ('Theon-Greyjoy', 'Luwin', {'weight': 27}), ('Theon-Greyjoy', 'Ramsay-Snow', {'weight': 101}), ('Theon-Greyjoy', 'Rickon-Stark', {'weight': 20}), ('Theon-Greyjoy', 'Robb-Stark', {'weight': 76}), ('Theon-Greyjoy', 'Rodrik-Cassel', {'weight': 21}), ('Theon-Greyjoy', 'Roose-Bolton', {'weight': 14}), ('Theon-Greyjoy', 'Tyrion-Lannister', {'weight': 3}), ('Theon-Greyjoy', 'Tywin-Lannister', {'weight': 3}), ('Theon-Greyjoy', 'Victarion-Greyjoy', {'weight': 3}), ('Theon-Greyjoy', 'Walder-Frey', {'weight': 4}), ('Victarion-Greyjoy', 'Daenerys-Targaryen', {'weight': 7}), ('Aerys-II-Targaryen', 'Barristan-Selmy', {'weight': 4}), ('Aerys-II-Targaryen', 'Brienne-of-Tarth', {'weight': 3}), ('Aerys-II-Targaryen', 'Cersei-Lannister', {'weight': 3}), ('Aerys-II-Targaryen', 'Eddard-Stark', {'weight': 15}), ('Aerys-II-Targaryen', 'Jaime-Lannister', {'weight': 37}), ('Aerys-II-Targaryen', 'Joffrey-Baratheon', {'weight': 6}), ('Aerys-II-Targaryen', 'Jon-Arryn', {'weight': 3}), ('Aerys-II-Targaryen', 'Rhaegar-Targaryen', {'weight': 14}), ('Aerys-II-Targaryen', 'Tyrion-Lannister', {'weight': 9}), ('Aerys-II-Targaryen', 'Tywin-Lannister', {'weight': 26}), ('Aerys-II-Targaryen', 'Viserys-Targaryen', {'weight': 3}), ('Barristan-Selmy', 'Belwas', {'weight': 14}), ('Barristan-Selmy', 'Boros-Blount', {'weight': 3}), ('Barristan-Selmy', 'Cersei-Lannister', {'weight': 17}), ('Barristan-Selmy', 'Daario-Naharis', {'weight': 18}), ('Barristan-Selmy', 'Daenerys-Targaryen', {'weight': 83}), ('Barristan-Selmy', 'Eddard-Stark', {'weight': 28}), ('Barristan-Selmy', 'Hizdahr-zo-Loraq', {'weight': 42}), ('Barristan-Selmy', 'Jaime-Lannister', {'weight': 8}), ('Barristan-Selmy', 'Joffrey-Baratheon', {'weight': 13}), ('Barristan-Selmy', 'Jon-Arryn', {'weight': 4}), ('Barristan-Selmy', 'Jorah-Mormont', {'weight': 5}), ('Barristan-Selmy', 'Meryn-Trant', {'weight': 3}), ('Barristan-Selmy', 'Petyr-Baelish', {'weight': 7}), ('Barristan-Selmy', 'Pycelle', {'weight': 8}), ('Barristan-Selmy', 'Quentyn-Martell', {'weight': 22}), ('Barristan-Selmy', 'Renly-Baratheon', {'weight': 13}), ('Barristan-Selmy', 'Rhaegar-Targaryen', {'weight': 3}), ('Barristan-Selmy', 'Sandor-Clegane', {'weight': 3}), ('Barristan-Selmy', 'Sansa-Stark', {'weight': 3}), ('Barristan-Selmy', 'Tyrion-Lannister', {'weight': 3}), ('Barristan-Selmy', 'Varys', {'weight': 15}), ('Brienne-of-Tarth', 'Catelyn-Stark', {'weight': 53}), ('Brienne-of-Tarth', 'Cersei-Lannister', {'weight': 8}), ('Brienne-of-Tarth', 'Edmure-Tully', {'weight': 3}), ('Brienne-of-Tarth', 'Gendry', {'weight': 6}), ('Brienne-of-Tarth', 'Jaime-Lannister', {'weight': 111}), ('Brienne-of-Tarth', 'Joffrey-Baratheon', {'weight': 4}), ('Brienne-of-Tarth', 'Loras-Tyrell', {'weight': 6}), ('Brienne-of-Tarth', 'Lysa-Arryn', {'weight': 3}), ('Brienne-of-Tarth', 'Podrick-Payne', {'weight': 36}), ('Brienne-of-Tarth', 'Renly-Baratheon', {'weight': 37}), ('Brienne-of-Tarth', 'Robb-Stark', {'weight': 5}), ('Brienne-of-Tarth', 'Roose-Bolton', {'weight': 11}), ('Brienne-of-Tarth', 'Sandor-Clegane', {'weight': 12}), ('Brienne-of-Tarth', 'Sansa-Stark', {'weight': 24}), ('Brienne-of-Tarth', 'Tommen-Baratheon', {'weight': 3}), ('Brienne-of-Tarth', 'Tyrion-Lannister', {'weight': 7}), ('Brienne-of-Tarth', 'Tywin-Lannister', {'weight': 3}), ('Cersei-Lannister', 'Arya-Stark', {'weight': 25}), ('Cersei-Lannister', 'Boros-Blount', {'weight': 23}), ('Cersei-Lannister', 'Bran-Stark', {'weight': 6}), ('Cersei-Lannister', 'Bronn', {'weight': 23}), ('Cersei-Lannister', 'Catelyn-Stark', {'weight': 30}), ('Cersei-Lannister', 'Daenerys-Targaryen', {'weight': 3}), ('Cersei-Lannister', 'Doran-Martell', {'weight': 3}), ('Cersei-Lannister', 'Dunsen', {'weight': 16}), ('Cersei-Lannister', 'Eddard-Stark', {'weight': 91}), ('Cersei-Lannister', 'Gregor-Clegane', {'weight': 21}), ('Cersei-Lannister', 'Ilyn-Payne', {'weight': 34}), ('Cersei-Lannister', 'Jaime-Lannister', {'weight': 130}), ('Cersei-Lannister', 'Joffrey-Baratheon', {'weight': 173}), ('Cersei-Lannister', 'Jon-Arryn', {'weight': 7}), ('Cersei-Lannister', 'Jory-Cassel', {'weight': 5}), ('Cersei-Lannister', 'Kevan-Lannister', {'weight': 24}), ('Cersei-Lannister', 'Lancel-Lannister', {'weight': 38}), ('Cersei-Lannister', 'Loras-Tyrell', {'weight': 24}), ('Cersei-Lannister', 'Lysa-Arryn', {'weight': 9}), ('Cersei-Lannister', 'Mace-Tyrell', {'weight': 26}), ('Cersei-Lannister', 'Margaery-Tyrell', {'weight': 79}), ('Cersei-Lannister', 'Meryn-Trant', {'weight': 46}), ('Cersei-Lannister', 'Mordane', {'weight': 3}), ('Cersei-Lannister', 'Myrcella-Baratheon', {'weight': 19}), ('Cersei-Lannister', 'Oberyn-Martell', {'weight': 9}), ('Cersei-Lannister', 'Osmund-Kettleblack', {'weight': 37}), ('Cersei-Lannister', 'Petyr-Baelish', {'weight': 27}), ('Cersei-Lannister', 'Polliver', {'weight': 9}), ('Cersei-Lannister', 'Pycelle', {'weight': 34}), ('Cersei-Lannister', 'Rafford', {'weight': 16}), ('Cersei-Lannister', 'Renly-Baratheon', {'weight': 12}), ('Cersei-Lannister', 'Rhaegar-Targaryen', {'weight': 8}), ('Cersei-Lannister', 'Robb-Stark', {'weight': 15}), ('Cersei-Lannister', 'Sandor-Clegane', {'weight': 19}), ('Cersei-Lannister', 'Sansa-Stark', {'weight': 95}), ('Cersei-Lannister', 'Shae', {'weight': 9}), ('Cersei-Lannister', 'Tickler', {'weight': 11}), ('Cersei-Lannister', 'Tommen-Baratheon', {'weight': 111}), ('Cersei-Lannister', 'Tyrion-Lannister', {'weight': 209}), ('Cersei-Lannister', 'Tywin-Lannister', {'weight': 57}), ('Cersei-Lannister', 'Varys', {'weight': 53}), ('Cersei-Lannister', 'Walder-Frey', {'weight': 5}), ('Eddard-Stark', 'Arya-Stark', {'weight': 46}), ('Eddard-Stark', 'Beric-Dondarrion', {'weight': 3}), ('Eddard-Stark', 'Bran-Stark', {'weight': 34}), ('Eddard-Stark', 'Catelyn-Stark', {'weight': 88}), ('Eddard-Stark', 'Daenerys-Targaryen', {'weight': 5}), ('Eddard-Stark', 'Davos-Seaworth', {'weight': 4}), ('Eddard-Stark', 'Edmure-Tully', {'weight': 3}), ('Eddard-Stark', 'Gendry', {'weight': 3}), ('Eddard-Stark', 'Gregor-Clegane', {'weight': 13}), ('Eddard-Stark', 'Ilyn-Payne', {'weight': 11}), ('Eddard-Stark', 'Jaime-Lannister', {'weight': 33}), ('Eddard-Stark', 'Joffrey-Baratheon', {'weight': 41}), ('Eddard-Stark', 'Jon-Arryn', {'weight': 51}), ('Eddard-Stark', 'Jory-Cassel', {'weight': 32}), ('Eddard-Stark', 'Loras-Tyrell', {'weight': 12}), ('Eddard-Stark', 'Luwin', {'weight': 19}), ('Eddard-Stark', 'Lysa-Arryn', {'weight': 12}), ('Eddard-Stark', 'Mordane', {'weight': 11}), ('Eddard-Stark', 'Petyr-Baelish', {'weight': 85}), ('Eddard-Stark', 'Pycelle', {'weight': 36}), ('Eddard-Stark', 'Ramsay-Snow', {'weight': 4}), ('Eddard-Stark', 'Renly-Baratheon', {'weight': 38}), ('Eddard-Stark', 'Rhaegar-Targaryen', {'weight': 10}), ('Eddard-Stark', 'Rickon-Stark', {'weight': 15}), ('Eddard-Stark', 'Robb-Stark', {'weight': 46}), ('Eddard-Stark', 'Rodrik-Cassel', {'weight': 7}), ('Eddard-Stark', 'Roose-Bolton', {'weight': 5}), ('Eddard-Stark', 'Sandor-Clegane', {'weight': 14}), ('Eddard-Stark', 'Sansa-Stark', {'weight': 43}), ('Eddard-Stark', 'Tyrion-Lannister', {'weight': 40}), ('Eddard-Stark', 'Tywin-Lannister', {'weight': 18}), ('Eddard-Stark', 'Varys', {'weight': 64}), ('Jaime-Lannister', 'Arya-Stark', {'weight': 13}), ('Jaime-Lannister', 'Beric-Dondarrion', {'weight': 7}), ('Jaime-Lannister', 'Boros-Blount', {'weight': 9}), ('Jaime-Lannister', 'Brynden-Tully', {'weight': 29}), ('Jaime-Lannister', 'Catelyn-Stark', {'weight': 59}), ('Jaime-Lannister', 'Edmure-Tully', {'weight': 35}), ('Jaime-Lannister', 'Gregor-Clegane', {'weight': 15}), ('Jaime-Lannister', 'Ilyn-Payne', {'weight': 30}), ('Jaime-Lannister', 'Joffrey-Baratheon', {'weight': 45}), ('Jaime-Lannister', 'Jon-Arryn', {'weight': 5}), ('Jaime-Lannister', 'Jory-Cassel', {'weight': 4}), ('Jaime-Lannister', 'Kevan-Lannister', {'weight': 13}), ('Jaime-Lannister', 'Lancel-Lannister', {'weight': 22}), ('Jaime-Lannister', 'Lem', {'weight': 6}), ('Jaime-Lannister', 'Loras-Tyrell', {'weight': 37}), ('Jaime-Lannister', 'Lysa-Arryn', {'weight': 9}), ('Jaime-Lannister', 'Mace-Tyrell', {'weight': 5}), ('Jaime-Lannister', 'Margaery-Tyrell', {'weight': 10}), ('Jaime-Lannister', 'Meryn-Trant', {'weight': 9}), ('Jaime-Lannister', 'Oberyn-Martell', {'weight': 3}), ('Jaime-Lannister', 'Osmund-Kettleblack', {'weight': 22}), ('Jaime-Lannister', 'Petyr-Baelish', {'weight': 11}), ('Jaime-Lannister', 'Pycelle', {'weight': 10}), ('Jaime-Lannister', 'Rafford', {'weight': 3}), ('Jaime-Lannister', 'Renly-Baratheon', {'weight': 28}), ('Jaime-Lannister', 'Rhaegar-Targaryen', {'weight': 7}), ('Jaime-Lannister', 'Robb-Stark', {'weight': 41}), ('Jaime-Lannister', 'Rodrik-Cassel', {'weight': 3}), ('Jaime-Lannister', 'Roose-Bolton', {'weight': 17}), ('Jaime-Lannister', 'Sandor-Clegane', {'weight': 21}), ('Jaime-Lannister', 'Sansa-Stark', {'weight': 23}), ('Jaime-Lannister', 'Tommen-Baratheon', {'weight': 36}), ('Jaime-Lannister', 'Tyrion-Lannister', {'weight': 113}), ('Jaime-Lannister', 'Tywin-Lannister', {'weight': 51}), ('Jaime-Lannister', 'Varys', {'weight': 19}), ('Jaime-Lannister', 'Walder-Frey', {'weight': 5}), ('Joffrey-Baratheon', 'Arya-Stark', {'weight': 53}), ('Joffrey-Baratheon', 'Beric-Dondarrion', {'weight': 3}), ('Joffrey-Baratheon', 'Boros-Blount', {'weight': 14}), ('Joffrey-Baratheon', 'Bran-Stark', {'weight': 6}), ('Joffrey-Baratheon', 'Bronn', {'weight': 12}), ('Joffrey-Baratheon', 'Catelyn-Stark', {'weight': 11}), ('Joffrey-Baratheon', 'Davos-Seaworth', {'weight': 10}), ('Joffrey-Baratheon', 'Dunsen', {'weight': 9}), ('Joffrey-Baratheon', 'Gregor-Clegane', {'weight': 12}), ('Joffrey-Baratheon', 'Ilyn-Payne', {'weight': 26}), ('Joffrey-Baratheon', 'Kevan-Lannister', {'weight': 11}), ('Joffrey-Baratheon', 'Lancel-Lannister', {'weight': 4}), ('Joffrey-Baratheon', 'Loras-Tyrell', {'weight': 18}), ('Joffrey-Baratheon', 'Mace-Tyrell', {'weight': 17}), ('Joffrey-Baratheon', 'Margaery-Tyrell', {'weight': 56}), ('Joffrey-Baratheon', 'Melisandre', {'weight': 4}), ('Joffrey-Baratheon', 'Meryn-Trant', {'weight': 34}), ('Joffrey-Baratheon', 'Mordane', {'weight': 9}), ('Joffrey-Baratheon', 'Myrcella-Baratheon', {'weight': 30}), ('Joffrey-Baratheon', 'Oberyn-Martell', {'weight': 8}), ('Joffrey-Baratheon', 'Osmund-Kettleblack', {'weight': 18}), ('Joffrey-Baratheon', 'Petyr-Baelish', {'weight': 39}), ('Joffrey-Baratheon', 'Polliver', {'weight': 9}), ('Joffrey-Baratheon', 'Pycelle', {'weight': 19}), ('Joffrey-Baratheon', 'Rafford', {'weight': 9}), ('Joffrey-Baratheon', 'Renly-Baratheon', {'weight': 25}), ('Joffrey-Baratheon', 'Robb-Stark', {'weight': 49}), ('Joffrey-Baratheon', 'Rodrik-Cassel', {'weight': 9}), ('Joffrey-Baratheon', 'Sandor-Clegane', {'weight': 71}), ('Joffrey-Baratheon', 'Sansa-Stark', {'weight': 222}), ('Joffrey-Baratheon', 'Selyse-Florent', {'weight': 3}), ('Joffrey-Baratheon', 'Shae', {'weight': 3}), ('Joffrey-Baratheon', 'Tickler', {'weight': 10}), ('Joffrey-Baratheon', 'Tommen-Baratheon', {'weight': 77}), ('Joffrey-Baratheon', 'Tyrion-Lannister', {'weight': 219}), ('Joffrey-Baratheon', 'Tywin-Lannister', {'weight': 37}), ('Joffrey-Baratheon', 'Varys', {'weight': 37}), ('Jon-Arryn', 'Bran-Stark', {'weight': 7}), ('Jon-Arryn', 'Catelyn-Stark', {'weight': 11}), ('Jon-Arryn', 'Lysa-Arryn', {'weight': 19}), ('Jon-Arryn', 'Petyr-Baelish', {'weight': 7}), ('Jon-Arryn', 'Pycelle', {'weight': 11}), ('Jon-Arryn', 'Robert-Arryn', {'weight': 3}), ('Jon-Arryn', 'Tyrion-Lannister', {'weight': 8}), ('Jon-Arryn', 'Varys', {'weight': 5}), ('Rhaegar-Targaryen', 'Daenerys-Targaryen', {'weight': 27}), ('Rhaegar-Targaryen', 'Jon-Connington', {'weight': 7}), ('Rhaegar-Targaryen', 'Jorah-Mormont', {'weight': 14}), ('Rhaegar-Targaryen', 'Sansa-Stark', {'weight': 3}), ('Rhaegar-Targaryen', 'Tywin-Lannister', {'weight': 4}), ('Rhaegar-Targaryen', 'Viserys-Targaryen', {'weight': 15}), ('Tyrion-Lannister', 'Arya-Stark', {'weight': 11}), ('Tyrion-Lannister', 'Boros-Blount', {'weight': 14}), ('Tyrion-Lannister', 'Bran-Stark', {'weight': 31}), ('Tyrion-Lannister', 'Bronn', {'weight': 137}), ('Tyrion-Lannister', 'Brynden-Tully', {'weight': 4}), ('Tyrion-Lannister', 'Catelyn-Stark', {'weight': 69}), ('Tyrion-Lannister', 'Daenerys-Targaryen', {'weight': 17}), ('Tyrion-Lannister', 'Doran-Martell', {'weight': 13}), ('Tyrion-Lannister', 'Gregor-Clegane', {'weight': 30}), ('Tyrion-Lannister', 'Ilyn-Payne', {'weight': 6}), ('Tyrion-Lannister', 'Jon-Connington', {'weight': 37}), ('Tyrion-Lannister', 'Jorah-Mormont', {'weight': 27}), ('Tyrion-Lannister', 'Kevan-Lannister', {'weight': 30}), ('Tyrion-Lannister', 'Lancel-Lannister', {'weight': 18}), ('Tyrion-Lannister', 'Loras-Tyrell', {'weight': 21}), ('Tyrion-Lannister', 'Luwin', {'weight': 10}), ('Tyrion-Lannister', 'Lysa-Arryn', {'weight': 36}), ('Tyrion-Lannister', 'Mace-Tyrell', {'weight': 18}), ('Tyrion-Lannister', 'Margaery-Tyrell', {'weight': 10}), ('Tyrion-Lannister', 'Meryn-Trant', {'weight': 12}), ('Tyrion-Lannister', 'Myrcella-Baratheon', {'weight': 21}), ('Tyrion-Lannister', 'Oberyn-Martell', {'weight': 41}), ('Tyrion-Lannister', 'Osmund-Kettleblack', {'weight': 18}), ('Tyrion-Lannister', 'Petyr-Baelish', {'weight': 71}), ('Tyrion-Lannister', 'Podrick-Payne', {'weight': 40}), ('Tyrion-Lannister', 'Pycelle', {'weight': 33}), ('Tyrion-Lannister', 'Renly-Baratheon', {'weight': 23}), ('Tyrion-Lannister', 'Rickon-Stark', {'weight': 4}), ('Tyrion-Lannister', 'Robb-Stark', {'weight': 44}), ('Tyrion-Lannister', 'Robert-Arryn', {'weight': 9}), ('Tyrion-Lannister', 'Rodrik-Cassel', {'weight': 10}), ('Tyrion-Lannister', 'Roose-Bolton', {'weight': 6}), ('Tyrion-Lannister', 'Sandor-Clegane', {'weight': 25}), ('Tyrion-Lannister', 'Sansa-Stark', {'weight': 118}), ('Tyrion-Lannister', 'Shae', {'weight': 68}), ('Tyrion-Lannister', 'Tommen-Baratheon', {'weight': 26}), ('Tyrion-Lannister', 'Tywin-Lannister', {'weight': 117}), ('Tyrion-Lannister', 'Varys', {'weight': 107}), ('Tyrion-Lannister', 'Viserys-Targaryen', {'weight': 4}), ('Tywin-Lannister', 'Arya-Stark', {'weight': 13}), ('Tywin-Lannister', 'Bronn', {'weight': 7}), ('Tywin-Lannister', 'Brynden-Tully', {'weight': 10}), ('Tywin-Lannister', 'Catelyn-Stark', {'weight': 21}), ('Tywin-Lannister', 'Doran-Martell', {'weight': 4}), ('Tywin-Lannister', 'Edmure-Tully', {'weight': 11}), ('Tywin-Lannister', 'Gregor-Clegane', {'weight': 20}), ('Tywin-Lannister', 'Jon-Connington', {'weight': 4}), ('Tywin-Lannister', 'Kevan-Lannister', {'weight': 32}), ('Tywin-Lannister', 'Lysa-Arryn', {'weight': 4}), ('Tywin-Lannister', 'Mace-Tyrell', {'weight': 14}), ('Tywin-Lannister', 'Oberyn-Martell', {'weight': 9}), ('Tywin-Lannister', 'Petyr-Baelish', {'weight': 5}), ('Tywin-Lannister', 'Podrick-Payne', {'weight': 4}), ('Tywin-Lannister', 'Pycelle', {'weight': 13}), ('Tywin-Lannister', 'Renly-Baratheon', {'weight': 3}), ('Tywin-Lannister', 'Robb-Stark', {'weight': 30}), ('Tywin-Lannister', 'Roose-Bolton', {'weight': 13}), ('Tywin-Lannister', 'Sansa-Stark', {'weight': 6}), ('Tywin-Lannister', 'Tommen-Baratheon', {'weight': 11}), ('Tywin-Lannister', 'Varys', {'weight': 9}), ('Tywin-Lannister', 'Walder-Frey', {'weight': 12}), ('Viserys-Targaryen', 'Daenerys-Targaryen', {'weight': 55}), ('Viserys-Targaryen', 'Doran-Martell', {'weight': 3}), ('Viserys-Targaryen', 'Drogo', {'weight': 26}), ('Viserys-Targaryen', 'Irri', {'weight': 5}), ('Viserys-Targaryen', 'Jorah-Mormont', {'weight': 15}), ('Viserys-Targaryen', 'Oberyn-Martell', {'weight': 4}), ('Qhorin-Halfhand', 'Ygritte', {'weight': 5}), ('Arianne-Martell', 'Doran-Martell', {'weight': 26}), ('Arianne-Martell', 'Myrcella-Baratheon', {'weight': 16}), ('Arianne-Martell', 'Oberyn-Martell', {'weight': 3}), ('Arianne-Martell', 'Quentyn-Martell', {'weight': 8}), ('Doran-Martell', 'Daenerys-Targaryen', {'weight': 3}), ('Doran-Martell', 'Gregor-Clegane', {'weight': 11}), ('Doran-Martell', 'Myrcella-Baratheon', {'weight': 15}), ('Doran-Martell', 'Oberyn-Martell', {'weight': 14}), ('Doran-Martell', 'Quentyn-Martell', {'weight': 4}), ('Doran-Martell', 'Varys', {'weight': 4}), ('Myrcella-Baratheon', 'Arya-Stark', {'weight': 13}), ('Myrcella-Baratheon', 'Mordane', {'weight': 12}), ('Myrcella-Baratheon', 'Robb-Stark', {'weight': 3}), ('Myrcella-Baratheon', 'Robert-Arryn', {'weight': 4}), ('Myrcella-Baratheon', 'Sandor-Clegane', {'weight': 4}), ('Myrcella-Baratheon', 'Sansa-Stark', {'weight': 18}), ('Myrcella-Baratheon', 'Tommen-Baratheon', {'weight': 36}), ('Oberyn-Martell', 'Bronn', {'weight': 4}), ('Oberyn-Martell', 'Gregor-Clegane', {'weight': 42}), ('Oberyn-Martell', 'Mace-Tyrell', {'weight': 15}), ('Oberyn-Martell', 'Sansa-Stark', {'weight': 3}), ('Quentyn-Martell', 'Belwas', {'weight': 3}), ('Quentyn-Martell', 'Daario-Naharis', {'weight': 5}), ('Quentyn-Martell', 'Daenerys-Targaryen', {'weight': 58}), ('Quentyn-Martell', 'Hizdahr-zo-Loraq', {'weight': 15}), ('Arya-Stark', 'Beric-Dondarrion', {'weight': 28}), ('Arya-Stark', 'Bran-Stark', {'weight': 40}), ('Arya-Stark', 'Brynden-Tully', {'weight': 4}), ('Arya-Stark', 'Catelyn-Stark', {'weight': 8}), ('Arya-Stark', 'Dunsen', {'weight': 6}), ('Arya-Stark', 'Gendry', {'weight': 82}), ('Arya-Stark', 'Gregor-Clegane', {'weight': 10}), ('Arya-Stark', 'Hot-Pie', {'weight': 76}), ('Arya-Stark', 'Ilyn-Payne', {'weight': 8}), ('Arya-Stark', 'Jory-Cassel', {'weight': 12}), ('Arya-Stark', 'Lem', {'weight': 24}), ('Arya-Stark', 'Melisandre', {'weight': 4}), ('Arya-Stark', 'Meryn-Trant', {'weight': 7}), ('Arya-Stark', 'Mordane', {'weight': 39}), ('Arya-Stark', 'Petyr-Baelish', {'weight': 3}), ('Arya-Stark', 'Polliver', {'weight': 14}), ('Arya-Stark', 'Rafford', {'weight': 10}), ('Arya-Stark', 'Ramsay-Snow', {'weight': 5}), ('Arya-Stark', 'Rickon-Stark', {'weight': 20}), ('Arya-Stark', 'Robb-Stark', {'weight': 44}), ('Arya-Stark', 'Rodrik-Cassel', {'weight': 3}), ('Arya-Stark', 'Roose-Bolton', {'weight': 21}), ('Arya-Stark', 'Sandor-Clegane', {'weight': 58}), ('Arya-Stark', 'Sansa-Stark', {'weight': 155}), ('Arya-Stark', 'Tickler', {'weight': 5}), ('Arya-Stark', 'Tommen-Baratheon', {'weight': 5}), ('Beric-Dondarrion', 'Catelyn-Stark', {'weight': 3}), ('Beric-Dondarrion', 'Gendry', {'weight': 4}), ('Beric-Dondarrion', 'Gregor-Clegane', {'weight': 9}), ('Beric-Dondarrion', 'Lem', {'weight': 14}), ('Beric-Dondarrion', 'Loras-Tyrell', {'weight': 5}), ('Beric-Dondarrion', 'Sandor-Clegane', {'weight': 18}), ('Beric-Dondarrion', 'Sansa-Stark', {'weight': 4}), ('Bran-Stark', 'Catelyn-Stark', {'weight': 24}), ('Bran-Stark', 'Hodor', {'weight': 209}), ('Bran-Stark', 'Jojen-Reed', {'weight': 112}), ('Bran-Stark', 'Jory-Cassel', {'weight': 11}), ('Bran-Stark', 'Luwin', {'weight': 116}), ('Bran-Stark', 'Meera-Reed', {'weight': 123}), ('Bran-Stark', 'Petyr-Baelish', {'weight': 3}), ('Bran-Stark', 'Ramsay-Snow', {'weight': 7}), ('Bran-Stark', 'Renly-Baratheon', {'weight': 3}), ('Bran-Stark', 'Rickon-Stark', {'weight': 129}), ('Bran-Stark', 'Robb-Stark', {'weight': 169}), ('Bran-Stark', 'Rodrik-Cassel', {'weight': 40}), ('Bran-Stark', 'Sansa-Stark', {'weight': 25}), ('Bran-Stark', 'Tommen-Baratheon', {'weight': 8}), ('Brynden-Tully', 'Catelyn-Stark', {'weight': 29}), ('Brynden-Tully', 'Edmure-Tully', {'weight': 24}), ('Brynden-Tully', 'Lysa-Arryn', {'weight': 10}), ('Brynden-Tully', 'Robb-Stark', {'weight': 27}), ('Brynden-Tully', 'Walder-Frey', {'weight': 7}), ('Catelyn-Stark', 'Bronn', {'weight': 6}), ('Catelyn-Stark', 'Edmure-Tully', {'weight': 42}), ('Catelyn-Stark', 'Loras-Tyrell', {'weight': 6}), ('Catelyn-Stark', 'Luwin', {'weight': 14}), ('Catelyn-Stark', 'Lysa-Arryn', {'weight': 55}), ('Catelyn-Stark', 'Margaery-Tyrell', {'weight': 4}), ('Catelyn-Stark', 'Petyr-Baelish', {'weight': 31}), ('Catelyn-Stark', 'Renly-Baratheon', {'weight': 55}), ('Catelyn-Stark', 'Rickon-Stark', {'weight': 6}), ('Catelyn-Stark', 'Robb-Stark', {'weight': 128}), ('Catelyn-Stark', 'Robert-Arryn', {'weight': 3}), ('Catelyn-Stark', 'Rodrik-Cassel', {'weight': 28}), ('Catelyn-Stark', 'Roose-Bolton', {'weight': 10}), ('Catelyn-Stark', 'Sansa-Stark', {'weight': 32}), ('Catelyn-Stark', 'Varys', {'weight': 10}), ('Catelyn-Stark', 'Walder-Frey', {'weight': 38}), ('Dunsen', 'Gregor-Clegane', {'weight': 21}), ('Dunsen', 'Ilyn-Payne', {'weight': 16}), ('Dunsen', 'Meryn-Trant', {'weight': 16}), ('Dunsen', 'Polliver', {'weight': 16}), ('Dunsen', 'Rafford', {'weight': 23}), ('Dunsen', 'Sandor-Clegane', {'weight': 10}), ('Dunsen', 'Tickler', {'weight': 12}), ('Gendry', 'Hot-Pie', {'weight': 53}), ('Gendry', 'Lem', {'weight': 9}), ('Gendry', 'Sandor-Clegane', {'weight': 5}), ('Gregor-Clegane', 'Bronn', {'weight': 4}), ('Gregor-Clegane', 'Ilyn-Payne', {'weight': 17}), ('Gregor-Clegane', 'Loras-Tyrell', {'weight': 10}), ('Gregor-Clegane', 'Meryn-Trant', {'weight': 16}), ('Gregor-Clegane', 'Petyr-Baelish', {'weight': 3}), ('Gregor-Clegane', 'Polliver', {'weight': 16}), ('Gregor-Clegane', 'Pycelle', {'weight': 6}), ('Gregor-Clegane', 'Rafford', {'weight': 25}), ('Gregor-Clegane', 'Robb-Stark', {'weight': 4}), ('Gregor-Clegane', 'Sandor-Clegane', {'weight': 31}), ('Gregor-Clegane', 'Sansa-Stark', {'weight': 5}), ('Gregor-Clegane', 'Tickler', {'weight': 17}), ('Hot-Pie', 'Lem', {'weight': 7}), ('Ilyn-Payne', 'Edmure-Tully', {'weight': 4}), ('Ilyn-Payne', 'Loras-Tyrell', {'weight': 3}), ('Ilyn-Payne', 'Meryn-Trant', {'weight': 22}), ('Ilyn-Payne', 'Polliver', {'weight': 8}), ('Ilyn-Payne', 'Rafford', {'weight': 16}), ('Ilyn-Payne', 'Sandor-Clegane', {'weight': 13}), ('Ilyn-Payne', 'Sansa-Stark', {'weight': 18}), ('Ilyn-Payne', 'Tickler', {'weight': 11}), ('Ilyn-Payne', 'Varys', {'weight': 5}), ('Jory-Cassel', 'Mordane', {'weight': 3}), ('Jory-Cassel', 'Petyr-Baelish', {'weight': 8}), ('Jory-Cassel', 'Robb-Stark', {'weight': 9}), ('Jory-Cassel', 'Rodrik-Cassel', {'weight': 5}), ('Jory-Cassel', 'Sansa-Stark', {'weight': 9}), ('Lem', 'Sandor-Clegane', {'weight': 5}), ('Melisandre', 'Davos-Seaworth', {'weight': 64}), ('Melisandre', 'Renly-Baratheon', {'weight': 4}), ('Melisandre', 'Selyse-Florent', {'weight': 26}), ('Melisandre', 'Ygritte', {'weight': 3}), ('Meryn-Trant', 'Boros-Blount', {'weight': 31}), ('Meryn-Trant', 'Osmund-Kettleblack', {'weight': 21}), ('Meryn-Trant', 'Polliver', {'weight': 8}), ('Meryn-Trant', 'Rafford', {'weight': 16}), ('Meryn-Trant', 'Sandor-Clegane', {'weight': 19}), ('Meryn-Trant', 'Sansa-Stark', {'weight': 8}), ('Meryn-Trant', 'Tickler', {'weight': 11}), ('Mordane', 'Petyr-Baelish', {'weight': 3}), ('Mordane', 'Sansa-Stark', {'weight': 47}), ('Petyr-Baelish', 'Edmure-Tully', {'weight': 4}), ('Petyr-Baelish', 'Loras-Tyrell', {'weight': 5}), ('Petyr-Baelish', 'Lysa-Arryn', {'weight': 47}), ('Petyr-Baelish', 'Podrick-Payne', {'weight': 4}), ('Petyr-Baelish', 'Pycelle', {'weight': 26}), ('Petyr-Baelish', 'Renly-Baratheon', {'weight': 17}), ('Petyr-Baelish', 'Robb-Stark', {'weight': 6}), ('Petyr-Baelish', 'Robert-Arryn', {'weight': 26}), ('Petyr-Baelish', 'Rodrik-Cassel', {'weight': 7}), ('Petyr-Baelish', 'Roose-Bolton', {'weight': 3}), ('Petyr-Baelish', 'Sandor-Clegane', {'weight': 3}), ('Petyr-Baelish', 'Sansa-Stark', {'weight': 61}), ('Petyr-Baelish', 'Varys', {'weight': 60}), ('Polliver', 'Rafford', {'weight': 17}), ('Polliver', 'Sandor-Clegane', {'weight': 22}), ('Polliver', 'Sansa-Stark', {'weight': 3}), ('Polliver', 'Tickler', {'weight': 19}), ('Rafford', 'Sandor-Clegane', {'weight': 10}), ('Rafford', 'Tickler', {'weight': 14}), ('Ramsay-Snow', 'Robb-Stark', {'weight': 7}), ('Ramsay-Snow', 'Rodrik-Cassel', {'weight': 5}), ('Ramsay-Snow', 'Roose-Bolton', {'weight': 23}), ('Rickon-Stark', 'Hodor', {'weight': 11}), ('Rickon-Stark', 'Jojen-Reed', {'weight': 5}), ('Rickon-Stark', 'Luwin', {'weight': 21}), ('Rickon-Stark', 'Meera-Reed', {'weight': 6}), ('Rickon-Stark', 'Robb-Stark', {'weight': 53}), ('Rickon-Stark', 'Rodrik-Cassel', {'weight': 3}), ('Rickon-Stark', 'Sansa-Stark', {'weight': 20}), ('Robb-Stark', 'Davos-Seaworth', {'weight': 3}), ('Robb-Stark', 'Edmure-Tully', {'weight': 51}), ('Robb-Stark', 'Hodor', {'weight': 5}), ('Robb-Stark', 'Luwin', {'weight': 26}), ('Robb-Stark', 'Renly-Baratheon', {'weight': 25}), ('Robb-Stark', 'Rodrik-Cassel', {'weight': 27}), ('Robb-Stark', 'Roose-Bolton', {'weight': 24}), ('Robb-Stark', 'Sansa-Stark', {'weight': 44}), ('Robb-Stark', 'Varys', {'weight': 3}), ('Robb-Stark', 'Walder-Frey', {'weight': 40}), ('Rodrik-Cassel', 'Bronn', {'weight': 4}), ('Rodrik-Cassel', 'Hodor', {'weight': 3}), ('Rodrik-Cassel', 'Loras-Tyrell', {'weight': 3}), ('Rodrik-Cassel', 'Luwin', {'weight': 21}), ('Rodrik-Cassel', 'Roose-Bolton', {'weight': 4}), ('Roose-Bolton', 'Walder-Frey', {'weight': 3}), ('Sandor-Clegane', 'Loras-Tyrell', {'weight': 4}), ('Sandor-Clegane', 'Renly-Baratheon', {'weight': 7}), ('Sandor-Clegane', 'Sansa-Stark', {'weight': 53}), ('Sandor-Clegane', 'Tickler', {'weight': 23}), ('Sandor-Clegane', 'Tommen-Baratheon', {'weight': 5}), ('Sansa-Stark', 'Boros-Blount', {'weight': 14}), ('Sansa-Stark', 'Kevan-Lannister', {'weight': 5}), ('Sansa-Stark', 'Lancel-Lannister', {'weight': 3}), ('Sansa-Stark', 'Loras-Tyrell', {'weight': 27}), ('Sansa-Stark', 'Lysa-Arryn', {'weight': 41}), ('Sansa-Stark', 'Mace-Tyrell', {'weight': 9}), ('Sansa-Stark', 'Margaery-Tyrell', {'weight': 41}), ('Sansa-Stark', 'Osmund-Kettleblack', {'weight': 8}), ('Sansa-Stark', 'Podrick-Payne', {'weight': 7}), ('Sansa-Stark', 'Pycelle', {'weight': 8}), ('Sansa-Stark', 'Renly-Baratheon', {'weight': 16}), ('Sansa-Stark', 'Robert-Arryn', {'weight': 17}), ('Sansa-Stark', 'Shae', {'weight': 8}), ('Sansa-Stark', 'Tommen-Baratheon', {'weight': 13}), ('Sansa-Stark', 'Varys', {'weight': 8}), ('Tommen-Baratheon', 'Boros-Blount', {'weight': 14}), ('Tommen-Baratheon', 'Bronn', {'weight': 7}), ('Tommen-Baratheon', 'Edmure-Tully', {'weight': 4}), ('Tommen-Baratheon', 'Kevan-Lannister', {'weight': 20}), ('Tommen-Baratheon', 'Loras-Tyrell', {'weight': 13}), ('Tommen-Baratheon', 'Luwin', {'weight': 3}), ('Tommen-Baratheon', 'Mace-Tyrell', {'weight': 10}), ('Tommen-Baratheon', 'Margaery-Tyrell', {'weight': 51}), ('Tommen-Baratheon', 'Osmund-Kettleblack', {'weight': 6}), ('Belwas', 'Daenerys-Targaryen', {'weight': 46}), ('Belwas', 'Hizdahr-zo-Loraq', {'weight': 11}), ('Belwas', 'Jhiqui', {'weight': 3}), ('Belwas', 'Jorah-Mormont', {'weight': 22}), ('Boros-Blount', 'Loras-Tyrell', {'weight': 5}), ('Boros-Blount', 'Osmund-Kettleblack', {'weight': 8}), ('Daario-Naharis', 'Daenerys-Targaryen', {'weight': 65}), ('Daario-Naharis', 'Drogo', {'weight': 3}), ('Daario-Naharis', 'Hizdahr-zo-Loraq', {'weight': 14}), ('Daario-Naharis', 'Irri', {'weight': 10}), ('Daario-Naharis', 'Jhiqui', {'weight': 5}), ('Daario-Naharis', 'Jorah-Mormont', {'weight': 10}), ('Daenerys-Targaryen', 'Drogo', {'weight': 123}), ('Daenerys-Targaryen', 'Hizdahr-zo-Loraq', {'weight': 96}), ('Daenerys-Targaryen', 'Irri', {'weight': 73}), ('Daenerys-Targaryen', 'Jhiqui', {'weight': 65}), ('Daenerys-Targaryen', 'Jon-Connington', {'weight': 6}), ('Daenerys-Targaryen', 'Jorah-Mormont', {'weight': 161}), ('Daenerys-Targaryen', 'Mace-Tyrell', {'weight': 3}), ('Daenerys-Targaryen', 'Varys', {'weight': 8}), ('Hizdahr-zo-Loraq', 'Irri', {'weight': 3}), ('Hizdahr-zo-Loraq', 'Jhiqui', {'weight': 3}), ('Jorah-Mormont', 'Drogo', {'weight': 28}), ('Jorah-Mormont', 'Irri', {'weight': 7}), ('Jorah-Mormont', 'Jhiqui', {'weight': 9}), ('Pycelle', 'Kevan-Lannister', {'weight': 8}), ('Pycelle', 'Mace-Tyrell', {'weight': 4}), ('Pycelle', 'Osmund-Kettleblack', {'weight': 3}), ('Pycelle', 'Renly-Baratheon', {'weight': 7}), ('Pycelle', 'Varys', {'weight': 35}), ('Pycelle', 'Walder-Frey', {'weight': 3}), ('Renly-Baratheon', 'Davos-Seaworth', {'weight': 6}), ('Renly-Baratheon', 'Loras-Tyrell', {'weight': 27}), ('Renly-Baratheon', 'Mace-Tyrell', {'weight': 4}), ('Renly-Baratheon', 'Margaery-Tyrell', {'weight': 19}), ('Renly-Baratheon', 'Varys', {'weight': 18}), ('Varys', 'Bronn', {'weight': 12}), ('Varys', 'Jon-Connington', {'weight': 6}), ('Varys', 'Kevan-Lannister', {'weight': 8}), ('Varys', 'Lancel-Lannister', {'weight': 3}), ('Varys', 'Margaery-Tyrell', {'weight': 3}), ('Varys', 'Shae', {'weight': 27}), ('Jhiqui', 'Drogo', {'weight': 5}), ('Jhiqui', 'Irri', {'weight': 56}), ('Loras-Tyrell', 'Mace-Tyrell', {'weight': 9}), ('Loras-Tyrell', 'Margaery-Tyrell', {'weight': 31}), ('Loras-Tyrell', 'Osmund-Kettleblack', {'weight': 17}), ('Osmund-Kettleblack', 'Lancel-Lannister', {'weight': 13}), ('Osmund-Kettleblack', 'Margaery-Tyrell', {'weight': 8}), ('Tormund', 'Craster', {'weight': 3}), ('Tormund', 'Ygritte', {'weight': 11}), ('Hodor', 'Jojen-Reed', {'weight': 38}), ('Hodor', 'Luwin', {'weight': 27}), ('Hodor', 'Meera-Reed', {'weight': 59}), ('Jojen-Reed', 'Craster', {'weight': 3}), ('Jojen-Reed', 'Luwin', {'weight': 7}), ('Jojen-Reed', 'Meera-Reed', {'weight': 73}), ('Luwin', 'Meera-Reed', {'weight': 4}), ('Edmure-Tully', 'Lysa-Arryn', {'weight': 5}), ('Edmure-Tully', 'Walder-Frey', {'weight': 13}), ('Lysa-Arryn', 'Robert-Arryn', {'weight': 23}), ('Podrick-Payne', 'Bronn', {'weight': 20}), ('Bronn', 'Shae', {'weight': 3}), ('Margaery-Tyrell', 'Mace-Tyrell', {'weight': 11}), ('Kevan-Lannister', 'Lancel-Lannister', {'weight': 17}), ('Kevan-Lannister', 'Mace-Tyrell', {'weight': 5}), ('Drogo', 'Irri', {'weight': 12}), ('Davos-Seaworth', 'Selyse-Florent', {'weight': 6})])
weights = [z['weight'] for x,y,z in g.edges(data=True)]
sns.displot(weights)
<seaborn.axisgrid.FacetGrid at 0x7fbcf5ec4d50>
../_images/networks_hands_on_in_python_98_1.png

We see a right skewed distribution with many weak and some very strong edges. Lets take a look what are the edges with the highest weight (meaning here: the characters with most intraction).

centrality_dgr = nx.degree_centrality(g)
centrality_eigen = nx.eigenvector_centrality_numpy(g, weight='weight')
centrality_between = nx.betweenness_centrality(g, weight='weight')
nx.set_node_attributes(g, centrality_dgr, 'centrality_dgr')
nx.set_node_attributes(g, centrality_eigen, 'centrality_eigen')
nx.set_node_attributes(g, centrality_between, 'centrality_between')
g.nodes(data=True)['Tyrion-Lannister']
{'centrality_dgr': 0.5454545454545455,
 'centrality_eigen': 0.3789114457918316,
 'centrality_between': 0.03467326324469181}
g.degree(weight='weight')['Tyrion-Lannister']
2170

Communities & Groups#

partition = community_louvain.best_partition(g)
nx.set_node_attributes(g, partition, 'community')
nodes_df = pd.DataFrame.from_dict(dict(g.nodes(data=True)),orient='index')
nodes_df.groupby('community')['centrality_eigen'].nlargest(5)
community                                 
0          Jon-Snow                           0.165477
           Samwell-Tarly                      0.059171
           Jeor-Mormont                       0.048872
           Janos-Slynt                        0.036871
           Aemon-Targaryen-(Maester-Aemon)    0.031288
1          Robb-Stark                         0.174454
           Catelyn-Stark                      0.165325
           Bran-Stark                         0.127022
           Rickon-Stark                       0.048728
           Theon-Greyjoy                      0.048281
2          Robert-Baratheon                   0.287403
           Eddard-Stark                       0.286136
           Stannis-Baratheon                  0.152189
           Varys                              0.139816
           Petyr-Baelish                      0.136667
3          Arya-Stark                         0.146023
           Mordane                            0.031440
           Gendry                             0.016195
           Beric-Dondarrion                   0.013795
           Hot-Pie                            0.012714
4          Barristan-Selmy                    0.048767
           Daenerys-Targaryen                 0.030154
           Rhaegar-Targaryen                  0.025899
           Jorah-Mormont                      0.020294
           Viserys-Targaryen                  0.009412
5          Tyrion-Lannister                   0.378911
           Cersei-Lannister                   0.360116
           Joffrey-Baratheon                  0.346213
           Sansa-Stark                        0.276120
           Jaime-Lannister                    0.215525
Name: centrality_eigen, dtype: float64

Network Visualization I#

Ok, lets give it a first minimal shot:

nx.draw(g, with_labels = True, node_size=10)
../_images/networks_hands_on_in_python_110_0.png
!pip install -qq holoviews
!pip install -qq -U bokeh
!pip install -qq datashader
     |β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ| 18.5 MB 365 kB/s 
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
panel 0.12.1 requires bokeh<2.4.0,>=2.3.0, but you have bokeh 2.4.3 which is incompatible.
     |β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ| 18.2 MB 862 kB/s 
     |β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ| 76 kB 4.5 MB/s 
?25h  Building wheel for datashape (setup.py) ... ?25l?25hdone
# Import the libraries and link to the bokeh backend
import holoviews as hv
from holoviews import opts
hv.extension('bokeh')
from bokeh.plotting import show
kwargs = dict(width=800, height=800, xaxis=None, yaxis=None)
opts.defaults(opts.Nodes(**kwargs), opts.Graph(**kwargs))
# Create and save a layout.
g_layout = nx.layout.spring_layout(g) 
g_plot = hv.Graph.from_networkx(g, g_layout).opts(tools=['hover'], node_color='community')
labels = hv.Labels(g_plot.nodes, ['x', 'y'], 'index')
from holoviews.operation.datashader import datashade, bundle_graph
bundled = bundle_graph(g_plot)
show(hv.render(bundled * labels.opts(text_font_size='6pt', text_color='white', bgcolor='gray')))