scanpy icon indicating copy to clipboard operation
scanpy copied to clipboard

Get modularity score after community detection in leiden/louvain

Open AlSzmigiel opened this issue 11 months ago • 3 comments

What kind of feature would you like to request?

Additional function parameters / changed functionality / changed defaults?

Please describe your wishes

This was already discussed in https://github.com/scverse/scanpy/pull/819, is there any reason why it is not possible now?

AlSzmigiel avatar Mar 13 '24 11:03 AlSzmigiel

I'm still dubious of the value, especially when we provide different ways of ways of optimizing the score.

What would you think of instead having sc.metrics.modularity where you match a clustering and a graph returning a modularity score?

It would basically wrap:

(
    igraph.Graph.Weighted_Adjacency(adata.obsp["connectivities"])
    .modularity(adata.obs["louvain"].cat.codes)
)

But you could also generate modularity scores for other labelings.

ivirshup avatar Mar 14 '24 16:03 ivirshup

What about comparing communities between for example CPM and RBERVertexPartition at the same resolution, using modularity score? This way we are not comparing scores obtained by optimization functions, just simple "external" measure.

AlSzmigiel avatar Mar 15 '24 15:03 AlSzmigiel

Yeah, that's why I like having it be manually computed rather than relying on the output of the clustering. This way we can make sure similar scores are used.

For API, I'm thinking:

@singledispatch
def modularity(graph: sparse.spmatrix, labels: pd.Series | np.ndarray) -> float:
    ...

@modularity.register
def _modularity_adata(adata: AnnData, labels: pd.Series | str, obsp: str) -> float:
    return modularity(
        adata.obsp[obsp],
        adata.obs[labels] if isinstance(labels, str) else labels,
    )

ivirshup avatar Mar 19 '24 13:03 ivirshup