Issues with directions while running Louvain algorithm

Hello,

I am running the Louvain algorithm and both algo.louvain.stream and algo.beta.louvain.stream are returning the same error on directionality:

CALL algo.louvain.stream('MATCH (n:alias) RETURN id(n) AS id',
  "MATCH (n)--(m:alias) RETURN id(n) AS source, id(m) AS target",  
  { graph: 'cypher',
 direction: 'BOTH',
 weightProperty: 'weight',
 seedProperty: 'louvain_coauthors_label',
 includeIntermediateCommunities: true
}) YIELD nodeId, community, communities
RETURN algo.asNode(nodeId).name as name, community, communities
ORDER BY name ASC

where is the best place to specify the directionality - in the cypher projection MATCH (n)--(m:alias) or setting the configuration of the algorithm right : direction: 'BOTH'. In any case, I had no luck running either of the commands and get the following error:

Neo.ClientError.Procedure.ProcedureCallFailed
Neo.ClientError.Procedure.ProcedureCallFailed: Failed to invoke procedure `algo.beta.louvain.stream`: Caused by: java.lang.IllegalArgumentException: Incompatible directions between loaded graph and requested compute direction. Load direction: 'OUTGOING' Compute direction: 'BOTH'

Please help.

Thanks,
Lavanya

1 Like

hi , i don't think there is a need to specify the direction if you are using cypher projection. the procedure will consider all the edges you are returning in the second cypher statement.

to consider edge weights , you can return them in the second cypher statement.

MATCH (n)-[r]-(m:alias) RETURN id(n) AS source, id(m) AS target,r.weight as weight

@ganesanmithun323 I do not have an example for Louvain algorithm. But in general I notice that algorithms that differentiate between directions give different answers for directed and undirected links specified in the second argument of the cypher projection:

Undirected, weighted

MATCH (n)-[r]-(m:alias) RETURN id(n) AS source, id(m) AS target,r.weight as weight

Directed, weighted

MATCH (n)-[r]->(m:alias) RETURN id(n) AS source, id(m) AS target,r.weight as weight

In any case, I got it worked without using cypher projection:

CALL algo.beta.louvain.stream('alias', 'co_authors',   {graph: 'huge', weightProperty: 'weight', direction : 'both', seedProperty: 'louvain_coauthors_label', includeIntermediateCommunities: true
}) YIELD nodeId, community, communities
RETURN algo.asNode(nodeId).alias_name as name, community, communities
ORDER BY name ASC

With Cypher projection:

CALL algo.beta.louvain.stream('MATCH (n:alias) RETURN id(n) AS id',
  "MATCH (n)-->(m:alias) RETURN id(n) AS source, id(m) AS target",  
  { graph: 'cypher',
 weightProperty: 'weight',
 seedProperty: 'louvain_coauthors_label',
 includeIntermediateCommunities: true
}) YIELD nodeId, community, communities
RETURN algo.asNode(nodeId).name as name, community, communities
ORDER BY name ASC

AND

CALL algo.beta.louvain.stream('MATCH (n:alias) RETURN id(n) AS id',
  "MATCH (n)--(m:alias) RETURN id(n) AS source, id(m) AS target",  
  { graph: 'cypher',
 weightProperty: 'weight',
 seedProperty: 'louvain_coauthors_label',
 includeIntermediateCommunities: true
}) YIELD nodeId, community, communities
RETURN algo.asNode(nodeId).name as name, community, communities
ORDER BY name ASC

I got the error
Neo.ClientError.Procedure.ProcedureCallFailed: Failed to invoke procedure algo.beta.louvain.stream: Caused by: java.lang.IllegalArgumentException: Incompatible directions between loaded graph and requested compute direction. Load direction: 'OUTGOING' Compute direction: 'BOTH'

I guess the algorithm does not work with cypher projections somehow; but works only by directly specifying the node type, relationship type and direction.

As per my understanding , if we are using projections , we are trying to give a sub graph to the procedure to run the algorithm on . So, its like we are passing graph in the form of nodes and edges.Here, by default , we are taking care of direction and edge weight part in second cypher statement . So , i feel there is no need to pass the direction in the parameters when we are using cypher projections.
note, when we are passing an undirected graph in second cypher statement , this means , we are passing each edge twice .

In case , if we want to run the algorithm on all nodes of same label connected by a single type of relations, then we can simply call the procedure with Label name and relationship type.

hi,i'm still confused about the direction.
the louvain algorithm only supports undirected networks. so i should transfer the directed net into undirected ones ?
supose i have a network that A konws B,B knows C and so on.it's directed. and we call it basic_network.
if i make cypher projection as following:
"MATCH (n)--(m:user) RETURN id(n) AS source, id(m) AS target"'
does it mean that the projected network i got will be undirected?

another question is "Incompatible directions between loaded graph and requested compute direction. Load direction: 'OUTGOING' Compute direction: 'BOTH'“
which is the loaded graph? the basic_network or the projected one?

many thanks.

yes, your projected graph will be undirected one .

you dont have to mention the direction in the property map if you are using the cypher projections

thanks a lot for your help.
i'm trying the example on the neo4j-graph-algorithms-user-guide-3.5.
the same error occurs

"Neo.ClientError.Procedure.ProcedureCallFailed: Failed to invoke procedure `algo.beta.louvain.stream`: Caused by: java.lang.IllegalArgumentException: Incompatible directions between loaded graph and requested compute direction. Load direction: 'OUTGOING' Compute direction: 'BOTH' "

the code is as following. i didn't find anything wrong.but it didn't work.

MERGE (nAlice:User {id:'Alice'}) SET nAlice.community = 0
MERGE (nBridget:User {id:'Bridget'}) SET nBridget.community = 0
MERGE (nCharles:User {id:'Charles'}) SET nCharles.community = 1
MERGE (nDoug:User {id:'Doug'}) SET nDoug.community = 1
MERGE (nMark:User {id:'Mark'}) SET nMark.community = 1
MERGE (nMichael:User {id:'Michael'}) SET nMichael.community = 0
MERGE (nKarin:User {id:'Karin'}) SET nKarin.community = 1
MERGE (nAmy:User {id:'Amy'})
MERGE (nAlice)-[:FRIEND]->(nBridget)
MERGE (nAlice)-[:FRIEND]->(nCharles)
MERGE (nMark)-[:FRIEND]->(nDoug)
MERGE (nBridget)-[:FRIEND]->(nMichael)
MERGE (nCharles)-[:FRIEND]->(nMark)
MERGE (nAlice)-[:FRIEND]->(nMichael)
MERGE (nCharles)-[:FRIEND]->(nDoug)
MERGE (nMark)-[:FRIEND]->(nKarin)
MERGE (nKarin)-[:FRIEND]->(nAmy)
MERGE (nAmy)-[:FRIEND]->(nDoug)

CALL algo.louvain(
'MATCH (p:User) RETURN id(p) as id',
'MATCH (p1:User)-[f:FRIEND]-(p2:User)
RETURN id(p1) as source, id(p2) as target, f.weight as weight',
{graph:'cypher',write:true})
1 Like

I have the same problem
I am using Neo4j 3.5.14
My graph is a non-directional graph and I am unable to use cypher projection.

Failed to invoke procedure algo.beta.louvain.stream: Caused by: java.lang.IllegalArgumentException: Incompatible directions between loaded graph and requested compute direction. Load direction: 'OUTGOING' Compute direction: 'BOTH'

The same Cypher projection in 3.5.2 with algo 3.5.2.0 is working correctly.
However, 3.5.2.0 is unable to use pre-defined community which means whatever I set the initial community seed it will goes start with 0 for final community value.

MERGE (nAlice:User {id:'Alice'})
MERGE (nBridget:User {id:'Bridget'})
MERGE (nCharles:User {id:'Charles'}) SET nCharles.community = 42
MERGE (nDoug:User {id:'Doug'}) SET nDoug.community = 42
MERGE (nMark:User {id:'Mark'}) SET nMark.community = 42
MERGE (nMichael:User {id:'Michael'})
MERGE (nKarin:User {id:'Karin'}) SET nKarin.community = 42
MERGE (nAmy:User {id:'Amy'})

MERGE (nAlice)-[:FRIEND]->(nBridget)
MERGE (nAlice)-[:FRIEND]->(nCharles)
MERGE (nMark)-[:FRIEND]->(nDoug)
MERGE (nBridget)-[:FRIEND]->(nMichael)
MERGE (nCharles)-[:FRIEND]->(nMark)
MERGE (nAlice)-[:FRIEND]->(nMichael)
MERGE (nCharles)-[:FRIEND]->(nDoug)
MERGE (nMark)-[:FRIEND]->(nKarin)
MERGE (nKarin)-[:FRIEND]->(nAmy)
MERGE (nAmy)-[:FRIEND]->(nDoug);
CALL algo.louvain('User', 'FRIEND', {
  write:true,
  communityProperty: "community",
  writeProperty: "newCommunity"
})
YIELD nodes, communityCount, iterations, loadMillis, computeMillis, writeMillis;

Come out:

match (n:User)
return n.id, n.community, n.newCommunity, n.communities

Is it a bug or it what it is?

Have you got your answer finally?

Could you check this question again?

Hi,

You could set direction to 'OUTGOING' or anything except 'BOTH'..
It really confused me as the documentation mentioned: