Skip to content

Commit

Permalink
Merge pull request #238 from GiulioRossetti/community_events
Browse files Browse the repository at this point in the history
Community events
  • Loading branch information
GiulioRossetti authored May 21, 2024
2 parents 3258210 + 0fcf910 commit 8a2b3fc
Show file tree
Hide file tree
Showing 48 changed files with 4,264 additions and 578 deletions.
3 changes: 2 additions & 1 deletion cdlib/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
__version__ = '0.3.1'
__version__ = "0.4.0"
from cdlib.classes.node_clustering import NodeClustering
from cdlib.classes.edge_clustering import EdgeClustering
from cdlib.classes.fuzzy_node_clustering import FuzzyNodeClustering
from cdlib.classes.attr_node_clustering import AttrNodeClustering
from cdlib.classes.bipartite_node_clustering import BiNodeClustering
from cdlib.classes.temporal_clustering import TemporalClustering
from cdlib.classes.named_clustering import NamedClustering
from cdlib.lifecycles import LifeCycle, CommunityEvent
24 changes: 18 additions & 6 deletions cdlib/algorithms/crisp_partition.py
Original file line number Diff line number Diff line change
Expand Up @@ -517,13 +517,12 @@ def louvain(
========== ======== ========
:param g_original: a networkx/igraph object
:param partition : NodeClustering object, optional the algorithm will start using this partition of the nodes.
:param weight: str, optional the key in graph to use as weight. Default to 'weight'
:param partition: NodeClustering object, optional the algorithm will start using this partition of the nodes
:param weight: str, optional the key in graph to use as weight. Default to "weight"
:param resolution: double, optional Will change the size of the communities, default to 1.
:param randomize: int, RandomState instance or None, optional (default=None). If int, random_state is the seed used by the random number generator; If RandomState instance, random_state is the random number generator; If None, the random number generator is the RandomState instance used by `np.random`.
:param randomize: int, RandomState instance or None, optional (default=None).
:return: NodeClustering object
:Example:
>>> from cdlib import algorithms
Expand All @@ -536,6 +535,7 @@ def louvain(
Blondel, Vincent D., et al. `Fast unfolding of communities in large networks. <https://iopscience.iop.org/article/10.1088/1742-5468/2008/10/P10008/meta/>`_ Journal of statistical mechanics: theory and experiment 2008.10 (2008): P10008.
.. note:: Reference implementation: https://github.com/taynaud/python-louvain
"""

g = convert_graph_formats(g_original, nx.Graph)
Expand Down Expand Up @@ -2689,9 +2689,21 @@ def paris(g_original: object) -> NodeClustering:
.. note:: Reference implementation: https://github.com/tbonald/paris
"""

g = convert_graph_formats(g_original, nx.Graph)
D = paris_alg(g)
clustering = paris_best_clustering(D)

dmap = {n: i for i, n in enumerate(g.nodes)}
reverse_map = {i: n for n, i in dmap.items()}
nx.relabel_nodes(g_original, dmap, False)

D = paris_alg(g_original)
coms = paris_best_clustering(D)

clustering = []

for com in coms:
com = [reverse_map[c] for c in com]
clustering.append(com)

return NodeClustering(
clustering, g_original, "Paris", method_parameters={}, overlap=False
Expand Down
26 changes: 24 additions & 2 deletions cdlib/algorithms/temporal_partition.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from cdlib import TemporalClustering, NamedClustering
from cdlib.algorithms.internal_dcd.eTILES import eTILES
import networkx as nx

__all__ = ["tiles"]

Expand Down Expand Up @@ -34,7 +35,7 @@ def tiles(dg: object, obs: int = 1) -> TemporalClustering:
:References:
Rossetti, Giulio; Pappalardo, Luca; Pedreschi, Dino, and Giannotti, Fosca. `Tiles: an online algorithm for community discovery in dynamic social networks.<https://link.springer.com/article/10.1007/s10994-016-5582-8>`_ Machine Learning (2016), 106(8), 1213-1241.
Rossetti, Giulio; Pappalardo, Luca; Pedreschi, Dino, and Giannotti, Fosca. Tiles: an online algorithm for community discovery in dynamic social networks. Machine Learning (2016), 106(8), 1213-1241.
"""
alg = eTILES(dg=dg, obs=obs)
tc = TemporalClustering()
Expand All @@ -57,8 +58,10 @@ def tiles(dg: object, obs: int = 1) -> TemporalClustering:
mtc = alg.get_matches()
tc.add_matching(mtc)

### polytree

# cleaning & updating community matching
dg = tc.lifecycle_polytree(None, False)
dg = __lifecycle_polytree(tc)
community_ids = list(dg.nodes())

tids = tc.get_observation_ids()
Expand All @@ -77,3 +80,22 @@ def tiles(dg: object, obs: int = 1) -> TemporalClustering:
tc.add_matching(mtc)

return tc


def __lifecycle_polytree(tc) -> nx.DiGraph:
"""
Reconstruct the poly-tree representing communities lifecycles using a provided similarity function.
"""

lifecycle = tc.matching

pt = nx.DiGraph()
if len(lifecycle[0]) == 3:
for u, v, w in lifecycle:
pt.add_edge(u, v, weight=w)
else:
# implicit matching
for u, v in lifecycle:
pt.add_edge(u, v)

return pt
Loading

0 comments on commit 8a2b3fc

Please sign in to comment.