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

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

The ArticleRank algorithm was developed by the Neo4j Labs team and is not officially supported. |

This section includes:

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.

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

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
```

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`

.

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;
```

If node 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}
)
```

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
```

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 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. |

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 |
'huge' |
yes |
Use 'huge' 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. |

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
```

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 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. |

writeConcurrency |
int |
value of 'concurrency' |
yes |
The number of concurrent threads used for writing the result. |

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 |
'huge' |
yes |
Use 'huge' 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. |

Name | Type | Description |
---|---|---|

node |
long |
Node ID |

score |
float |
PageRank weight |

The ArticleRank algorithm supports the following graph types:

- ✓ directed, unweighted
- ✓ undirected, unweighted