-
Notifications
You must be signed in to change notification settings - Fork 26
Description
Hi,
first thanks for developing this new approach for network analysis. I am a big fan of the "certainty paradox" that you identified in biological systems.
As I was implementing your scripts to test some ideas, I realized that the function causal_emergence_spectral() returns a graph of Effective Information = 0 if a directed graph is given, which was unexpected since I assumed that G_macro would be exactly the same as G_micro if no better mapping had been found. Differently, causal_emergence() is able to find a macro mapping with a higher EI.
Here is the code to reproduce the issue:
import numpy as np
import networkx as nx
import einet.code.ce_net as ce_net
# generate sample graph
N = 100
G = nx.scale_free_graph(N, alpha=0.2, beta=0.55, gamma=0.25, seed=123)
# nx.draw(G, alpha=0.5)
# undirected causal emergence
ce_cg = ce_net.causal_emergence(nx.Graph(G), printt=False)
ce_spec = ce_net.causal_emergence_spectral(nx.Graph(G))
print('Undirected CE')
print('EI_micro='+str(np.round(ce_cg['EI_micro'],2))+' | EI_macro_cg='+str(np.round(ce_cg['EI_macro'],2))+' | EI_macro_spec='+str(np.round(ce_spec['EI_macro'],2)) )
print('N_micro_cg=',str(len(ce_cg['G_micro'].nodes)),'|','N_macro_cg=',str(len(ce_cg['G_macro'].nodes)))
print('N_micro_spec=',str(len(ce_spec['G_micro'].nodes)),'|','N_macro_spec=',str(len(ce_spec['G_macro'].nodes)))
# directed causal emergence
ce_cg = ce_net.causal_emergence(nx.DiGraph(G), printt=False)
ce_spec = ce_net.causal_emergence_spectral(nx.DiGraph(G))
print('Directed CE')
print('EI_micro='+str(np.round(ce_cg['EI_micro'],2))+' | EI_macro_cg='+str(np.round(ce_cg['EI_macro'],2))+' | EI_macro_spec='+str(np.round(ce_spec['EI_macro'],2)) )
print('N_micro_cg=',str(len(ce_cg['G_micro'].nodes)),'|','N_macro_cg=',str(len(ce_cg['G_macro'].nodes)))
print('N_micro_spec=',str(len(ce_spec['G_micro'].nodes)),'|','N_macro_spec=',str(len(ce_spec['G_macro'].nodes)))[OUTPUT]
Undirected CE
EI_micro=3.9 | EI_macro_cg=4.34 | EI_macro_spec=4.32
N_micro_cg= 100 | N_macro_cg= 59
N_micro_spec= 100 | N_macro_spec= 66
Directed CE
EI_micro=3.16 | EI_macro_cg=3.88 | EI_macro_spec=0.0
N_micro_cg= 100 | N_macro_cg= 62
N_micro_spec= 100 | N_macro_spec= 1
After reading and testing the functions a bit more, I understood that the main issue was at the spectral decomposition level, since only 2 eigenvalues were higher than 0 in this case, and therefore everything was put into the same cluster / macronode afterwards.
So, my question is: how could one implement your causal_emergence_spectral() in a directed graph?
In the same line of thought of adding dist_add to the nodes that are not in the Markov blanket of each node, I tried adding dist_add to the positions of the distance matrix that correspond to the edges that appear in the undirected adjacency matrix, but not in the directed adjacency matrix. Although I could get a network with a higher EI, I think it does not make sense mathematically since I would be decomposing the undirected Wout and not the directed Wout, and therefore one may not get rid of the degenerated parts of the graph.
Have you implemented other approaches yet?
Thanks in advance!
Miquel