7.2.1. The ArticleRank algorithm

This section describes the ArticleRank algorithm in the Neo4j Graph Algorithms library.

ArticleRank is a variant of the PageRank algorithm, which measures the transitive influence or connectivity of nodes.

The ArticleRank algorithm is experimental and not officially supported.

This section includes:

7.2.1.1. History and explanation

Where ArticleRank differs to PageRank is that PageRank assumes that relationships from nodes that have a low out-degree are more important than relationships from nodes with a higher out-degree. ArticleRank weakens this assumption.

ArticleRank is defined in ArticleRank: a PageRank‐based alternative to numbers of citations for analysing citation networks as follows:

AR(A) = (1-d) + d (AR(T1)/(C(T1) + C(AVG)) + ... + AR(Tn)/(C(Tn) + C(AVG))

where,

  • we assume that a page A has pages T1 to Tn which point to it (i.e., are citations).
  • d is a damping factor which can be set between 0 and 1. It is usually set to 0.85.
  • C(A) is defined as the number of links going out of page A.
  • C(AVG) is defined as the average number of links going out of all pages.

7.2.1.2. ArticleRank algorithm sample

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

articlerank

The following will create a sample graph: 

MERGE (paper0:Paper {name:'Paper 0'})
MERGE (paper1:Paper {name:'Paper 1'})
MERGE (paper2:Paper {name:'Paper 2'})
MERGE (paper3:Paper {name:'Paper 3'})
MERGE (paper4:Paper {name:'Paper 4'})
MERGE (paper5:Paper {name:'Paper 5'})
MERGE (paper6:Paper {name:'Paper 6'})

MERGE (paper1)-[:CITES]->(paper0)

MERGE (paper2)-[:CITES]->(paper0)
MERGE (paper2)-[:CITES]->(paper1)

MERGE (paper3)-[:CITES]->(paper0)
MERGE (paper3)-[:CITES]->(paper1)
MERGE (paper3)-[:CITES]->(paper2)

MERGE (paper4)-[:CITES]->(paper0)
MERGE (paper4)-[:CITES]->(paper1)
MERGE (paper4)-[:CITES]->(paper2)
MERGE (paper4)-[:CITES]->(paper3)

MERGE (paper5)-[:CITES]->(paper1)
MERGE (paper5)-[:CITES]->(paper4)

MERGE (paper6)-[:CITES]->(paper1)
MERGE (paper6)-[:CITES]->(paper4)

The following will run the algorithm and stream results: 

CALL algo.articleRank.stream('Paper', 'CITES', {iterations:20, dampingFactor:0.85})
YIELD nodeId, score
RETURN algo.asNode(nodeId).name AS page,score
ORDER BY score DESC

The following will run the algorithm and write back results: 

CALL algo.articleRank('Paper', 'CITES',
  {iterations:20, dampingFactor:0.85, write: true,writeProperty:"pagerank"})
YIELD nodes, iterations, loadMillis, computeMillis, writeMillis, dampingFactor, write, writeProperty

Table 7.1. Results
Name ArticleRank

Paper 0

0.34616300000000005

Paper 1

0.319422

Paper 4

0.213733

Paper 2

0.21089400000000003

Paper 3

0.18026850000000003

Paper 5

0.15000000000000002

Paper 6

0.15000000000000002

Paper 0 is the most important paper, but it’s only the 2nd most cited paper - Paper 1 has more citations. However, Paper 1 cites Paper 0, which lets us see that it’s not only the number of incoming links that is important, but also the importance of the papers behind those links. Papers 5 and 6 are not cited by any other papers, so their score doesn’t increase above the initial score of 1 - dampingFactor.

7.2.1.3. Huge graph projection

The default label and relationship-type projection has a limitation of 2 billion nodes and 2 billion relationships. Therefore, if our projected graph contains more than 2 billion nodes or relationships, we will need to use huge graph projection.

Set graph:'huge' in the config: 

CALL algo.articleRank('Paper','CITES', {graph:'huge'})
YIELD nodes, iterations, loadMillis, computeMillis, writeMillis, dampingFactor, writeProperty;

7.2.1.4. Cypher projection

If label and relationship-type are not selective enough to describe your subgraph to run the algorithm on, you can use Cypher statements to load or project subsets of your graph. This can also be used to run algorithms on a virtual graph. You can learn more in the Section 2.2, “Cypher projection” section of the manual.

Set graph:'cypher' in the config: 

CALL algo.articleRank(
  'MATCH (p:Paper) RETURN id(p) as id',
  'MATCH (p1:Paper)-[:CITES]->(p2:Paper) RETURN id(p1) as source, id(p2) as target',
  {graph:'cypher', iterations:5, write: true}
)

7.2.1.5. Syntax

The following will run the algorithm and write back results: 

CALL algo.articleRank(label:String, relationship:String,
    {iterations:20, dampingFactor:0.85, write: true, writeProperty:'pagerank', concurrency:4})
YIELD nodes, iterations, loadMillis, computeMillis, writeMillis, dampingFactor, write, writeProperty

Table 7.2. Parameters
Name Type Default Optional Description

label

string

null

yes

The label to load from the graph. If null, load all nodes

relationship

string

null

yes

The relationship-type to load from the graph. If null, load all relationships

iterations

int

20

yes

How many iterations of PageRank to run

concurrency

int

available CPUs

yes

The number of concurrent threads

dampingFactor

float

0.85

yes

The damping factor of the PageRank calculation

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

write

boolean

true

yes

Specify if the result should be written back as a node property

graph

string

'heavy'

yes

Use 'heavy' when describing the subset of the graph with label and relationship-type parameter. Use 'cypher' for describing the subset with cypher node-statement and relationship-statement

Table 7.3. Results
Name Type Description

nodes

int

The number of nodes considered

iterations

int

The number of iterations run

dampingFactor

float

The damping factor used

writeProperty

string

The property name written back to

write

boolean

Specifies if the result was written back as node property

loadMillis

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 algo.articleRank.stream(label:String, relationship:String,
    {iterations:20, dampingFactor:0.85, concurrency:4})
YIELD node, score

Table 7.4. Parameters
Name Type Default Optional Description

label

string

null

yes

The label to load from the graph. If null, load all nodes

relationship

string

null

yes

The relationship-type to load from the graph. If null, load all nodes

iterations

int

20

yes

Specify how many iterations of PageRank to run

concurrency

int

available CPUs

yes

The number of concurrent threads

dampingFactor

float

0.85

yes

The damping factor of the PageRank calculation

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

graph

string

'heavy'

yes

Use 'heavy' when describing the subset of the graph with label and relationship-type parameter. Use 'cypher' for describing the subset with cypher node-statement and relationship-statement

Table 7.5. Results
Name Type Description

node

long

Node ID

score

float

PageRank weight

7.2.1.6. Graph type support

The ArticleRank algorithm supports the following graph types:

  • ✓ directed, unweighted
  • ✓ undirected, unweighted