Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

question - causal_emergence_spectral() for directed graphs #2

Open
MiqG opened this issue May 30, 2020 · 0 comments
Open

question - causal_emergence_spectral() for directed graphs #2

MiqG opened this issue May 30, 2020 · 0 comments

Comments

@MiqG
Copy link

MiqG commented May 30, 2020

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant