En esta sesión aprenderemos a utilizar la librería "Networkx" (http://networkx.readthedocs.io/en/networkx-1.11/index.html) que es una librería de Python para la creación, manipulación y estudio de la estructura, dinámicas y función de redes complejas.
Las redes complejas son conjuntos de muchos nodos conectados que interactúan de alguna forma. A los nodos de una red también se les llama vértices o elementos y los representaremos por los símbolos v1, v2, ..., vN , donde N es el número total de nodos en la red. Si un nodo vi está conectado con otro nodo vj, esta conexión se representa por una pareja ordenada (vi, vj ).
In [1]:
%matplotlib inline
import networkx as nx
import matplotlib.pyplot as gr
import scipy as sc
In [2]:
G=nx.Graph()
G.graph
Out[2]:
In [3]:
"""
Uno a uno
"""
G.add_node(1)
"""
O en forma de lista
"""
G.add_nodes_from([2,3,4,5])
G.node
Out[3]:
In [4]:
G.graph
Out[4]:
In [5]:
"""
Uno a uno
"""
G.remove_node(3)
G.node
Out[5]:
In [6]:
"""
Todos
"""
G.clear()
G.node
Out[6]:
In [7]:
"""
Podemos añadir nodos a partir de una variable
"""
H=[5, 6, 7, 8, 9, 12]
G.add_nodes_from(H)
G.node
Out[7]:
In [8]:
H=nx.path_graph(10)
G.add_nodes_from(H)
G.node
#print (H)
Out[8]:
In [10]:
H.graph
Out[10]:
In [11]:
GPL=nx.Graph(Name=["Pyladies"], librería= "Scipy")
GPL.graph
Out[11]:
In [12]:
"""
Ahora vamos a editar el atributo
"""
GPL.graph['librería']='Networkx'
GPL.graph
Out[12]:
In [13]:
"""
Empecemos a añadir los nodos
"""
GPL.add_node('Erika')
GPL.add_nodes_from("Ale", edad = 30 ) # que pasa si hacemos esto???
GPL.nodes(data=True)
Out[13]:
Ups!! ahora hay que borrar esos nodos!.. como lo hacemos??
Tip: remove_nodes_from
In [15]:
GPL.remove_nodes_from("Ale")
In [ ]:
In [ ]:
GPL.remove_nodes_from(['A','l','e'])
GPL.node
In [16]:
GPL.add_node("Ale", edad = 30 )
GPL.node["Ale"]
Out[16]:
In [17]:
GPL.node['Ale']['entidad'] = 'IFC'
GPL.node
Out[17]:
In [18]:
GPL.number_of_nodes()
Out[18]:
In [19]:
names = ['Araceli', 'Erika', 'Desiré', 'Isaac']
ages = ['27', '30', 'x', '28']
GPL.add_nodes_from(names, edad = ages, entidad = 'UNAM')
Ejemplo:
In [20]:
GPL.node
Out[20]:
In [21]:
GPL.add_node('Jane Doe', edad = 25, entidad = 'Ciencias')
In [22]:
GPL.nodes(data=True)
Out[22]:
In [23]:
GPL.add_edge('Ale','Erika')
GPL.edge
Out[23]:
In [24]:
e=('Erika','Jane Doe')
GPL.add_edge(*e)
GPL.edge
Out[24]:
In [25]:
GPL.add_edges_from([('Isaac','Ale'),('Ale','Marco')])
GPL.number_of_edges()
# ¿pero que pasó aqui? Marco no estaba incluido en los nodos del grupo Pyladies
Out[25]:
In [26]:
GPL.node
Out[26]:
In [27]:
GPL.add_edge(2,5, weight=2)
GPL.add_edges_from([['Erika','Jane Doe'],['Jane Doe','Ale']], color='red')
GPL.add_edges_from([('Ale','Marco',{'color':'blue'}), ('Erika','Erin',{'weight':8}), (3,5,{'weight':8})])
GPL['Ale']['Erika']['weight'] = 3
GPL.edge['Ale']['Marco']['weight'] = 4
GPL.edge
Out[27]:
In [28]:
GPL.neighbors('Erika')
Out[28]:
In [29]:
GPL.degree('Erika')
Out[29]:
In [ ]:
La distribución de conexiones (o vecinos) P (k): Es la probabilidad de que un nodo escogido al azar tenga k conexiones (o vecinos). (degree distribution) Por ejemplo, en una red de contactos sexuales P (k) es la probabilidad de que una persona escogida al azar en una sociedad haya tenido k parejas sexuales distintas a lo largo de su vida.
El coeficiente de agrupamiento (C): Es la probabilidad de que dos nodos estén conectados directamente a un tercer nodo, estén conectados entre sí. (clustering coefficient) Por ejemplo, en una red de amistades, es la probabilidad de que dos de mis amigos sean ellos mismos amigos uno del otro.
La longitud mínima entre dos nodos vi y vj: Es el número mínimo de “brincos”que se tienen que dar para llegar de un nodo vi de la red a otro nodo vj de la red. (path lenght)
La longitud promedio de la red (L): Es el promedio de las longitudes mínimas entre todas las posibles parejas de nodos (vi, vj) de la red.
http://networkx.readthedocs.io/en/networkx-1.11/reference/algorithms.html
http://networkx.readthedocs.io/en/networkx-1.11/reference/functions.html
Podemos usar varios algoritmos y funciones que nos dan información acerca de la red, por ejemplo:
average_clustering(G, nodes=None, weight=None, count_zeros=True) : Es el coeficiente de agrupamiento. Compute the average clustering coefficient for the graph G.
shortest_path_length(G[, source, target, weight]) Encuentra el camino mas corto entre los nodos Compute shortest path lengths in the graph.
degree_histogram(G) Return a list of the frequency of each degree value.
info(G[, n]) Print short summary of information for the graph G or the node n.
Ejemplos:
In [30]:
nx.info(GPL)
#nx.info(GPL, 'Ale')
Out[30]:
In [31]:
nx.get_node_attributes(GPL,'Erika')
Out[31]:
In [32]:
nx.clustering(GPL)
Out[32]:
In [33]:
nx.degree(GPL)
Out[33]:
In [34]:
nx.degree_histogram(GPL)
Out[34]:
In [ ]:
degree=list();
clustering=list();
for n in sc.arange(len(GPL.node)): # Some properties of the graph
degree.append(sorted(nx.degree(GPL,[n]).values())) # así nos regresa solo los valores de grado
#degree.append(nx.degree(GPL,[n]))
#así nos regresa los nodos con su correspondiente valor de grado de conectividad
clustering.append(nx.clustering(GPL,[n]))
print(degree)
print(clustering)
#¿que pasó aqui?... no esta accesando a la informacion de los nodos que son strings y no números... cuidado con eso!
In [38]:
sorted(GPL.degree().values())
Out[38]:
In [41]:
sorted(nx.degree(GPL).values())
Out[41]:
In [ ]:
In [ ]:
G=nx.Graph()
e=[('a','b',0.3),('b','c',0.9),('a','c',0.5),('c','d',1.2)]
G.add_weighted_edges_from(e)
nx.dijkstra_path(G,'a','d') # encuentra el camino mas corto y con mayor peso entre los nodos
In [ ]:
A = nx.to_scipy_sparse_matrix(GPL)
print(A.todense())
In [ ]:
A = nx.to_numpy_matrix(GPL)
print(A)
In [ ]:
A = nx.to_pandas_dataframe(GPL)
print(A)
In [42]:
import pandas as pd
import numpy as np
r = np.random.RandomState(seed=5)
ints = r.randint(1, 10, size=(3,2))
a = ['A', 'B', 'C']
b = ['D', 'A', 'E']
df = pd.DataFrame(ints, columns=['weight', 'cost'])
df['a'] = a
df['b'] = b
df
Out[42]:
In [43]:
G=nx.from_pandas_dataframe(df, 'a', 'b', ['weight', 'cost'])
nx.info(G)
Out[43]:
In [44]:
G['E']['C']['cost']
Out[44]:
In [ ]:
http://networkx.readthedocs.io/en/networkx-1.11/reference/readwrite.html
Archivos como éste los podemos descargar de http://openconnecto.me/graph-services/download/
In [45]:
RB=nx.read_leda('rhesus_brain_2.leda')
#RB=nx.read_graphml('rhesus_brain_2.graphml')
nx.info(RB)
Out[45]:
In [46]:
RB.node
Out[46]:
In [47]:
nx.is_directed(RB)
Out[47]:
In [48]:
RB.neighbors('VIP')
Out[48]:
In [49]:
RB.node['VIP']
Out[49]:
In [50]:
RB.edge['VIP']
Out[50]:
In [51]:
nx.flow_hierarchy(RB)
#Returns the flow hierarchy of a directed network.
#Flow hierarchy is defined as the fraction of edges not participating in cycles in a directed graph
Out[51]:
In [52]:
largest_sc = sorted(nx.strongly_connected_components(RB))
#largest_sc = max(nx.strongly_connected_components(RB))
largest_sc
Out[52]:
In [53]:
AttarctComp=sorted(nx.attracting_components(RB))
AttarctComp
Out[53]:
In [54]:
degree=(nx.degree_histogram(RB))
degreeX=(sc.arange(len(degree)))
gr.bar(degreeX, degree)
gr.title("Degree Histogram")
gr.xlabel("k")
gr.ylabel("Frequency")
fig = gr.gcf()
In [ ]:
In [55]:
degree_sequence=sorted(degree,reverse=True) # degree sequence
#print "Degree sequence", degree_sequence
dmax=max(degree_sequence)
gr.loglog(degree_sequence,'b-',marker='o')
gr.title("Degree rank plot")
gr.ylabel("degree")
gr.xlabel("rank")
#gr.savefig("degree_histogram.png")
gr.show()
barbell_graph(m1, m2[, create_using]) Return the Barbell Graph: two complete graphs connected by a path.
complete_graph(n[, create_using]) Return the complete graph K_n with n nodes.
complete_multipartite_graph(*block_sizes) Returns the complete multipartite graph with the specified block sizes.
dorogovtsev_goltsev_mendes_graph(n[, ...]) Return the hierarchically constructed Dorogovtsev-Goltsev-Mendes graph.
grid_graph(dim[, periodic]) Return the n-dimensional grid graph.
hypercube_graph(n) Return the n-dimensional hypercube.
lollipop_graph(m, n[, create_using]) Return the Lollipop Graph; Km connected to Pm.
path_graph(n[, create_using]) Return the Path graph P_n of n nodes linearly connected by n-1 edges.
wheel_graph(n[, create_using]) Return the wheel graph: a single hub node connected to each node of the (n-1)-node cycle graph
In [ ]:
W=nx.wheel_graph(10)
W.edge
In [ ]:
G=nx.complete_graph(8)
G.edge
In [ ]:
petersen=nx.petersen_graph()
tutte=nx.tutte_graph()
maze=nx.sedgewick_maze_graph()
tet=nx.tetrahedral_graph()
In [ ]:
er=nx.erdos_renyi_graph(100,0.15)
ws=nx.watts_strogatz_graph(30,3,0.1)
ba=nx.barabasi_albert_graph(100,5)
red=nx.random_lobster(100,0.9,0.9)
In [ ]:
ba=nx.barabasi_albert_graph(40,5)
nx.draw(ba, node_size=80,node_color="blue", alpha=0.5)
#nx.draw_circular(ba, node_size=80,node_color="blue", alpha=0.5)
gr.title('Barabasi Albert Graph', fontsize= 18) # Se requiere de matplotlib... aqui esta importada como gr
gr.show()
In [56]:
ba=nx.barabasi_albert_graph(40,5)
#nx.draw(ba, node_size=80,node_color="blue", alpha=0.5)
nx.draw_circular(ba, node_size=80,node_color="blue", alpha=0.5)
gr.title('Barabasi Albert Graph', fontsize= 18) # Se requiere de matplotlib... aqui esta importada como gr
gr.show()
In [ ]:
nx.average_shortest_path_length(ba)
In [57]:
Out[57]:
In [ ]:
nx.draw(ws, node_size=80,node_color="blue", alpha=0.5)
gr.title('Watts Strogatz Grap', fontsize= 18) # Se requiere de matplotlib... aqui esta importada como gr
gr.show()
In [ ]:
nx.average_shortest_path_length(ws)
In [ ]:
In [ ]:
In [ ]:
nx.draw(W, node_size=50,node_color="green", alpha=0.5)
gr.title('Wheel graph', fontsize= 18)
gr.show()
In [ ]:
nx.average_shortest_path_length(W)
In [ ]:
Hyp=nx.hypercube_graph(6)
nx.draw(Hyp, node_size=50,node_color="orange", alpha=0.5)
gr.title('Otra gráfica', fontsize= 18)
gr.show()
In [ ]:
In [ ]:
lollipop=nx.lollipop_graph(10,20)
nx.draw(lollipop, node_size=50,node_color="orange", alpha=0.5)
gr.title('Otra gráfica', fontsize= 18)
gr.show()
In [ ]:
nx.average_shortest_path_length(lollipop)
In [ ]:
nx.draw(GPL, node_size=100, node_color="pink", alpha=0.5)
gr.title('Pyladies graph', fontsize= 18)
gr.show()
In [ ]:
nx.average_shortest_path_length(GPL)
In [ ]:
nx.draw_random(RB, node_size=100, node_color="RED", alpha=0.5)
gr.title('RHESUS BRAIN graph', fontsize= 18)
gr.show()
In [ ]:
nx.average_shortest_path_length(RB)
In [ ]:
In [ ]:
In [ ]: