5.2.6. Degree Centrality

This section describes the Degree Centrality algorithm in the Neo4j Graph Data Science library.

Degree centrality measures the number of incoming and outgoing relationships from a node.

The Degree Centrality algorithm can help us find popular nodes in a graph.

This algorithm is in the alpha tier. For more information on algorithm tiers, see Chapter 5, Algorithms.

This section includes:

5.2.6.1. History and explanation

Degree Centrality was proposed by Linton C. Freeman in his 1979 paper Centrality in Social Networks Conceptual Clarification. While the Degree Centrality algorithm can be used to find the popularity of individual nodes, it is often used as part of a global analysis where we calculate the minimum degree, maximum degree, mean degree, and standard deviation across the whole graph.

5.2.6.2. Use-cases - when to use the Degree Centrality algorithm

5.2.6.3. Syntax

The following will run the algorithm and write back results: 

CALL gds.alpha.degree.write(configuration: Map)
YIELD nodes, createMillis, computeMillis, writeMillis, writeProperty

Table 5.72. Configuration
Name Type Default Optional Description

concurrency

int

4

yes

The number of concurrent threads used for running the algorithm. Also provides the default value for 'readConcurrency' and 'writeConcurrency'.

readConcurrency

int

value of 'concurrency'

yes

The number of concurrent threads used for reading the graph.

writeConcurrency

int

value of 'concurrency'

yes

The number of concurrent threads used for writing the result.

relationshipWeightProperty

string

null

yes

The property name that contains weight. If null, treats the graph as unweighted. Must be numeric.

defaultValue

float

0.0

yes

The default value of the weight in case it is missing or invalid.

Table 5.73. Results
Name Type Description

nodes

int

The number of nodes considered.

writeProperty

string

The property name written back to.

createMillis

int

Milliseconds for loading data.

computeMillis

int

Milliseconds for running the algorithm.

writeMillis

int

Milliseconds for writing result data back.

The following will run the algorithm and stream results: 

CALL gds.alpha.degree.stream(configuration: Map)
YIELD node, score

Table 5.74. Configuration
Name Type Default Optional Description

concurrency

int

4

yes

The number of concurrent threads used for running the algorithm. Also provides the default value for 'readConcurrency'.

readConcurrency

int

value of 'concurrency'

yes

The number of concurrent threads used for reading the graph.

weightProperty

string

null

yes

The property name that contains weight. If null, treats the graph as unweighted. Must be numeric.

defaultValue

float

0.0

yes

The default value of the weight in case it is missing or invalid.

Table 5.75. Results
Name Type Description

nodeId

long

Node ID

score

float

Degree Centrality score

5.2.6.4. Degree Centrality algorithm sample

This sample will explain the Degree Centrality algorithm, using a simple graph:

Create sample graph. 

CREATE (alice:User {name: 'Alice'}),
       (bridget:User {name: 'Bridget'}),
       (charles:User {name: 'Charles'}),
       (doug:User {name: 'Doug'}),
       (mark:User {name: 'Mark'}),
       (michael:User {name: 'Michael'}),
       (alice)-[:FOLLOWS]->(doug),
       (alice)-[:FOLLOWS]->(bridget),
       (alice)-[:FOLLOWS]->(charles),
       (mark)-[:FOLLOWS]->(doug),
       (mark)-[:FOLLOWS]->(michael),
       (bridget)-[:FOLLOWS]->(doug),
       (charles)-[:FOLLOWS]->(doug),
       (michael)-[:FOLLOWS]->(doug)

The following will run the algorithm and stream results, showing which users have the most followers: 

CALL gds.alpha.degree.stream({
  nodeProjection: 'User',
  relationshipProjection: {
    FOLLOWS: {
      type: 'FOLLOWS',
      orientation: 'REVERSE'
    }
  }
})
YIELD nodeId, score
RETURN gds.util.asNode(nodeId).name AS name, score AS followers
ORDER BY followers DESC

The following will run the algorithm and store results, showing which users have the most followers: 

CALL gds.alpha.degree.write({
  nodeProjection: 'User',
  relationshipProjection: {
    FOLLOWS: {
      type: 'FOLLOWS',
      orientation: 'REVERSE'
    }
  },
  writeProperty: 'followers'
})

Table 5.76. Results
Name Followers

Doug

5.0

Bridget

1.0

Charles

1.0

Michael

1.0

Mark

0.0

Alice

0.0

The following will run the algorithm and stream results, showing which users follow the most other users: 

CALL gds.alpha.degree.stream({
  nodeProjection: 'User',
  relationshipProjection: 'FOLLOWS'
})
YIELD nodeId, score
RETURN gds.util.asNode(nodeId).name AS name, score AS followers
ORDER BY followers DESC

The following will run the algorithm and store results, showing which users follow the most other users: 

CALL gds.alpha.degree.write({
  nodeProjection: 'User',
  relationshipProjection: 'FOLLOWS',
  writeProperty: 'followers'
})

Table 5.77. Results
Name Following

Alice

3.0

Mark

2.0

Bridget

1.0

Charles

1.0

Michael

1.0

Doug

0.0

We can see that Doug is the most popular user in our imaginary Twitter graph, with 5 followers - all other users follow him, but he doesn’t follow anybody back. In the real Twitter network celebrities have very high follower counts but tend to follow very few back people. We could therefore consider Doug a celebrity!

5.2.6.5. Weighted Degree Centrality algorithm sample

This sample will explain the weighted Degree Centrality algorithm, using a simple graph:

The following will create a sample graph: 

CREATE (alice:User {name:'Alice'}),
       (bridget:User {name:'Bridget'}),
       (charles:User {name:'Charles'}),
       (doug:User {name:'Doug'}),
       (mark:User {name:'Mark'}),
       (michael:User {name:'Michael'}),
       (alice)-[:FOLLOWS {score: 1}]->(doug),
       (alice)-[:FOLLOWS {score: 2}]->(bridget),
       (alice)-[:FOLLOWS {score: 5}]->(charles),
       (mark)-[:FOLLOWS {score: 1.5}]->(doug),
       (mark)-[:FOLLOWS {score: 4.5}]->(michael),
       (bridget)-[:FOLLOWS {score: 1.5}]->(doug),
       (charles)-[:FOLLOWS {score: 2}]->(doug),
       (michael)-[:FOLLOWS {score: 1.5}]->(doug)

This algorithm is a variant of the Degree Centrality algorithm, that measures the sum of the weights of incoming and outgoing relationships.

The following will run the algorithm and stream results, showing which users have the most weighted followers: 

CALL gds.alpha.degree.stream({
   nodeProjection: 'User',
   relationshipProjection: {
       FOLLOWS: {
           type: 'FOLLOWS',
           orientation: 'REVERSE',
           properties: 'score'
       }
   },
   relationshipWeightProperty: 'score'
})
YIELD nodeId, score
RETURN gds.util.asNode(nodeId).name AS name, score AS weightedFollowers
ORDER BY weightedFollowers DESC

The following will run the algorithm and store results, showing which users have the most weighted followers: 

CALL gds.alpha.degree.write({
   nodeProjection: 'User',
   relationshipProjection: {
       FOLLOWS: {
           type: 'FOLLOWS',
           orientation: 'REVERSE',
           properties: 'score'
       }
   },
   relationshipWeightProperty: 'score',
   writeProperty: 'weightedFollowers'
})
YIELD nodes, writeProperty

Table 5.78. Results
Name weightedFollowers

Doug

7.5

Charles

5.0

Michael

4.5

Bridget

2.0

Alice

0.0

Mark

0.0

Doug still remains our most popular user, but there isn’t such a big gap to the next person. Charles and Michael both only have one follower, but those relationships have a high relationship weight.

5.2.6.6. Cypher projection

If node label and relationship type are not selective enough to create the graph projection to run the algorithm on, you can use Cypher queries to project your graph. This can also be used to run algorithms on a virtual graph. You can learn more in the Section 4.3, “Cypher projection” section of the manual.

CALL gds.alpha.degree.write({
  nodeQuery: 'MATCH (u:User) RETURN id(u) AS id',
  relationshipQuery: 'MATCH (u1:User)<-[:FOLLOWS]-(u2:User) RETURN id(u1) AS source, id(u2) AS target',
  writeProperty: 'followers'
})

Note, that if we want to find the number of users that a user is following rather than their number of followers, we need to handle that in our Cypher query.

The following will run the algorithm and store the results, calculating the number of users that a user follows: 

CALL gds.alpha.degree.write({
  nodeQuery: 'MATCH (u:User) RETURN id(u) AS id',
  relationshipQuery: 'MATCH (u1:User)-[:FOLLOWS]->(u2:User) RETURN id(u1) AS source, id(u2) AS target',
  writeProperty: 'followers'
})