Endorsement
In the previous lesson iFull definition for betweenness centrality (opens in a new tab)A score for each node equal to how often it lies on the shortest paths between other nodes. scored every person by how many shortest paths run through them.
Algorithms in the Endorsement family score iFull definition for node (opens in a new tab)A vertex in a graph. In a property graph it can carry labels and properties. based on the scores of the nodes that connect to that node.
Eigenvector iFull definition for centrality (opens in a new tab)How important a node is within a graph. Each centrality algorithm defines importance differently., iFull definition for PageRank (opens in a new tab)A centrality algorithm that scores a node by the number of nodes pointing at it and by how important those nodes are., Article Rank and HITs are the four algorithms in this family.
The first three are variations on the same idea. HITs reaches the same kind of answer by holding two scores per node instead of one.
In this lesson, you'll:
- Run each algorithm on the messaging network
- Use each algorithm's results to create a comparative ranking
- Compare multiple scores from across the graph
By the end of this lesson, you will understand when and how to analyze a graph with algorithms from the Endorsement family.
What Endorsement algorithms do
Endorsement algorithms aim to score nodes higher based on the scores of nodes that point to them.
In this example graph, Declan's node would receive the highest score from Eigenvector Centrality, PageRank and Article Rank.
HITs would provide a slightly different answer. It provides two scores, and Odette would rank highest on one of them. We'll come back to HITs later in the lesson. For now, you'll focus on the three direct siblings: Eigenvector, PageRank and Article Rank.
Endorsement scores by hand
We can work out a simple Endorsement score quite easily by hand.
Let's say that all nodes start with a score of 1.0.
Odettereceives three votes, one each fromIngrid,MagnusandYusuf, soOdettescores1.0 + 1.0 + 1.0 = 3.0.Declanreceives a vote fromOdetteand one fromSana, soDeclanscores3.0 + 1.0 = 4.0.
The following table shows the actual scores produced by Eigenvector, PageRank and Article Rank in their default settings:
| Name | Eigenvector | PageRank | Article Rank |
|---|---|---|---|
| Declan | 0.997 | 0.730 | 0.386 |
| Odette | 0.075 | 0.533 | 0.359 |
| Ingrid | 0.001 | 0.150 | 0.150 |
| Magnus | 0.001 | 0.150 | 0.150 |
| Yusuf | 0.001 | 0.150 | 0.150 |
| Sana | 0.001 | 0.150 | 0.150 |
You should notice, while each algorithm produces a different score, the rank order remains consistent.
While each of these algorithms attempts to perform the same task, their biases and arithmetic differ in subtle ways.
Next, you'll take a look at their behaviors in greater detail.
Look again at the incoming messages query
In the Explore the graph lesson you ran this query for Person 1566.
Run it again, now.
MATCH path = (:Person)-[:MESSAGED]->(:Person)-[:MESSAGED]->(:Person {id: '1566'}) // (1)
RETURN path- 1
Two steps of incoming messages, both pointing towards one
(:Person)node
It returns four direct correspondents, and 119 (:Person) nodes feeding into them. To see how "important" they are the broader network, let's run some algorithms.
Eigenvector Centrality
Eigenvector Centrality is the plainest form of endorsement: a node's score is the sum of its senders' own scores, with no other adjustment.
Run it now, on the directed iFull definition for projection (opens in a new tab)An in-memory copy of part of your database that graph algorithms run against. You choose which nodes and relationships it holds..
CALL gds.eigenvector.write( // (1)
'directed', // (2)
{ writeProperty: 'eigenvector' } // (3)
)
YIELD nodePropertiesWritten // (4)
RETURN nodePropertiesWritten- 1
Runs Eigenvector Centrality and writes each score back to AuraDB instead of returning it
- 2
The projection to read the graph from
- 3
The property every
:Personis given, holding their score - 4
How many
(:Person)nodes were given the property
Your output should look something like this:
| nodePropertiesWritten |
|---|
| 1899 |
Every (:Person) node now carries an eigenvector score.
Read the eigenvector scores back
Run the following query to rank people by their eigenvector scores.
MATCH (p:Person)
RETURN p.id AS person, round(1000 * p.eigenvector) / 1000 AS eigenvector
ORDER BY eigenvector DESC
LIMIT 6Your output should look something like this:
| person | eigenvector |
|---|---|
| 1624 | 0.466 |
| 398 | 0.296 |
| 105 | 0.264 |
| 1168 | 0.247 |
| 323 | 0.204 |
| 557 | 0.158 |
Person 1624 tops this ranking by a wide margin. Back when you ran iFull definition for degree centrality (opens in a new tab)A score for each node equal to its number of outgoing relationships., Person 1624 did not appear in the top rankings at all.
Person 398 comes in second place.
Why 1624 tops Eigenvector Centrality
Now, let's take a look at Person 1624 and Person 398 in their contexts.
The following query returns both, along with Person 32 for comparison.
MATCH path = (:Person {id: '1624'})-[:MESSAGED]-(:Person)
RETURN path
UNION
MATCH path = (:Person {id: '398'})-[:MESSAGED]-(:Person)
RETURN path
UNION
MATCH path = (:Person {id: '32'})-[:MESSAGED]-(:Person)
RETURN pathWhat the visualisation shows
From the returned graph, you should notice a number of things:
1624has many more recursive link paths back to itself398also has quite a few recursive paths back to itself32mostly connects out to other nodes, receiving comparatively few votes in return

Consider this result in line with the results from Betweenness Centrality—where Person 32 outranked all others.
32 was more influential as a gatekeeper. These nodes are more influential as endorsers — or "influencers" in a social media context.
How Eigenvector calculates scores
Eigenvector Centrality repeats one simple step, over and over. Eventually, the scores stop moving between rounds. That is convergence.
- Every node starts with a score of
1.0. - On each round, a node's new score becomes the sum of its senders' current scores.
- After each round, iGo to glossary for graph data science (opens in a new tab)Analysing data through the structure of its connections. Also the name of the Neo4j library that implements it. divides every score by the L2 norm of the whole set. That is not the same as the scores summing to
1.0— it fixes the vector's Euclidean length at1.0, not its total.
1624 and 398 both have paths that loop back to themselves, so on each iteration, they bump each others' scores.

Nothing in the three steps above stops that pair from boosting each other every round. That compounding is what carries 1624 and 398 to the top of the ranking.
It is also at least partially why PageRank exists.
PageRank
PageRank keeps Eigenvector's step and adds two adjustments to it:
- It divides each sender's score by that sender's outgoing count, so somebody who sent 200 messages passes on a two-hundredth of their score along each one.
- It splits every score into an inherited part and a granted part. 85% is inherited from the senders pointing at the node, and the remaining 15% is granted to every node unconditionally.
The second adjustment is called the damping factor, and it can be reconfigured arbitrarily — which can result in wildly varying scores. You'll learn more about the nuances of PageRank in later labs.
Run PageRank now, on the directed projection, writing scores to a pageRank iFull definition for property (opens in a new tab)A named value stored on a node or a relationship.. Try it yourself first, without checking the solution below.
▶Solution
CALL gds.pageRank.write( // (1)
'directed', // (2)
{ writeProperty: 'pageRank' } // (3)
)
YIELD nodePropertiesWritten // (4)
RETURN nodePropertiesWritten- 1
Runs PageRank and writes each score back to AuraDB instead of returning it
- 2
The projection to read the graph from
- 3
The property every
:Personis given, holding their score - 4
How many
(:Person)nodes were given the property
Your output should look like this:
| nodePropertiesWritten |
|---|
| 1899 |
Read the PageRank scores back
Every (:Person) node now carries a pageRank score alongside its eigenvector score.
Run the following query to rank nodes by PageRank.
MATCH (p:Person)
RETURN p.id AS person,
round(1000 * p.pageRank) / 1000 AS pageRank,
round(1000 * p.eigenvector) / 1000 AS eigenvector
ORDER BY pageRank DESC
LIMIT 6Your output should look something like this:
| person | pageRank | eigenvector |
|---|---|---|
| 32 | 8.706 | 0.11 |
| 323 | 8.629 | 0.204 |
| 372 | 7.708 | 0.081 |
| 103 | 7.282 | 0.092 |
| 1624 | 7.041 | 0.466 |
| 42 | 6.296 | 0.061 |
Person 1624 is still here, in fifth place. Dividing each sender's score by the number of messages that sender wrote has cost the pair their compounding advantage.
Article Rank
Article Rank takes PageRank's division one step further.
PageRank divides a sender's score by that sender's own outgoing count. Article Rank divides it by that count plus the average outgoing count across the whole graph.
In your CollegeMsg graph, a sender who wrote thirty messages sits near that average, so the extra term changes little. A sender who wrote only one message receives a heavy penalty to their score.
Run it now on the directed projection, writing to an articleRank property.
CALL gds.articleRank.write( // (1)
'directed', // (2)
{ writeProperty: 'articleRank' } // (3)
)
YIELD nodePropertiesWritten // (4)
RETURN nodePropertiesWritten- 1
Runs Article Rank and writes each score back to AuraDB instead of returning it
- 2
The projection to read the graph from
- 3
The property every
:Personis given, holding their score - 4
How many
(:Person)nodes were given the property
Now rank your nodes by their Article Rank scores.
MATCH (p:Person)
RETURN p.id AS person,
round(1000 * p.articleRank) / 1000 AS articleRank,
round(1000 * p.pageRank) / 1000 AS pageRank,
round(1000 * p.eigenvector) / 1000 AS eigenvector
ORDER BY articleRank DESC
LIMIT 6Your output should look something like this:
| person | articleRank | pageRank | eigenvector |
|---|---|---|---|
| 323 | 1.546 | 8.629 | 0.204 |
| 32 | 1.340 | 8.706 | 0.11 |
| 1624 | 1.321 | 7.041 | 0.466 |
| 372 | 1.276 | 7.708 | 0.081 |
| 103 | 1.243 | 7.282 | 0.092 |
| 454 | 1.074 | 6.103 | 0.047 |
The scores are much smaller than PageRank's, because every sender's contribution is divided by a larger number.
Person 323 sits fifth on Eigenvector, second on PageRank, and first here.
The same six people, on one scale
The three scores use different scales, so a number from one means nothing beside a number from another.
The table below presents the same six nodes, with each column scaled so the highest score in the graph reads 1 and the lowest reads 0.
| person | eigenvector | pageRank | articleRank |
|---|---|---|---|
| 323 | 0.437 | 0.992 | 1.0 |
| 32 | 0.236 | 1.0 | 0.853 |
| 1624 | 1.0 | 0.806 | 0.839 |
| 372 | 0.173 | 0.883 | 0.807 |
| 103 | 0.198 | 0.834 | 0.783 |
| 454 | 0.101 | 0.666 | 0.662 |
Person 1624 holds the top eigenvector score and 0.806 of the top PageRank score. Person 32 reverses that, on 0.236 and 1.0.
Which of the three to run
Each algorithm decides how much a single endorsement is allowed to carry.
Eigenvector passes a sender's score on whole. Somebody endorsed by two or three heavily endorsed senders scores highly. Run Eigenvector when every node's vote remains the same regardless of how many votes they give.
For example, a person with an infectious disease does not lose their infectiousness the more they infect others, so, in a contact-tracing graph, Eigenvector could make more sense than PageRank.
Bridget infected four people and Dmitri infected one. All five carry the same exposure, because what Bridget passes on is not divided by the number of people Bridget met.
PageRank divides a sender's score by the number of messages that sender wrote. An endorsement from somebody who wrote to four hundred people is worth a four-hundredth of one from somebody who wrote to one. Run PageRank when a node holds a fixed amount of influence and splits it between everybody it votes for.
For example, a social media user who likes everything may be considered to have less endorsement value per like than someone else who likes only a curated selection.
Bridget and Dmitri hold the same score to give. Bridget likes four posts and passes a quarter of it to each — Dmitri likes one post and passes all of it.
Article Rank adds the graph's average outgoing count to PageRank's divisor. In our messaging graph, under PageRank, a person who sent one message hands their whole score to one recipient, and a thirty-second of it under Article Rank. Run Article Rank when a node with very few votes should not decide the ranking on its own.
For example, a reviewer who has rated a single film should not carry more weight per rating than a critic who has rated hundreds. Article Rank inverts PageRank's low-relationship, single-authority bias.
By PageRank
By Article Rank
Under PageRank the Newcomer's single rating carries three times the weight of any one of the Critic's. Article Rank adds the average outgoing count to both divisors, so in a graph where people rate many films the Newcomer's voting power will be dampened relative to the average.
HITs
HITs asks the same question as the other three, and answers it with two scores per node rather than one:
- Authority: How much link juice a node receives from other nodes that are recognized as Hubs
- Hub: How much authority this node can pass to other nodes
Notice here that Eigenvector, PageRank and Article Rank all use one score to influence neighbors' scores.
HITs does not. Any single node's current score can only be influenced by its neighbors' opposing scores.
On each iteration, a node receives another update to both its Authority score and Hub score, in that order:
- Authority: A node's authority score is updated by the sum of the hub scores of nodes that point into it.
- Hub: A node's Hub score is updated by the sum of the Authority scores of the nodes it points into.
Take a look at the same graph, updated in two steps:
Authority update
Hub update
The Authority update identifies Odette as the highest authority node. The Hub update identifies Ingrid, Magnus and Yusuf as tied for the most important Hub nodes.
HITs by hand
We can similarly work this out, for one iteration, by hand. Let's say every node starts with a hub score and an authority score of 1.0.
Authority update:
Odettereceives three votes, one each fromIngrid,MagnusandYusuf.Odettethen, has an authority score of1.0 + 1.0 + 1.0 = 3.0.Declanreceives two votes, fromOdetteandSana.Declanthen, has an authority score of1.0 + 1.0 = 2.0.
Hub update:
Ingrid,Magnus, andYusufeach point atOdettealone, so they each receive her authority score of3.0.OdetteandSanaboth point atDeclanalone, so they both getDeclan's new authority score of2.0.
If we run this same calculation 20 times in a row, the values of each will stop moving, and we will have converged.
Run HITs
HITs holds two scores per node, so it streams a map of values rather than writing a single property.
HITs is not currently available in iGo to glossary for Aura Graph Analytics (opens in a new tab)The Aura service that runs graph algorithms in a separate session, with no plugin to install., except via the graphdatascience driver or the GDS plugin. The code below demonstrates how to run it in either.
hits = gds.hits.stream(G_directed, hitsIterations=20) # (1)
print(hits.head()) # (2)- 1
Twenty rounds of the authority update followed by the hub update
- 2
One row per person, holding a
valuesmap with both scores
On the current graph, your output would look like this:
| person | authority | hub |
|---|---|---|
| 569 | 0.430 | 0.019 |
| 1118 | 0.258 | 0.015 |
| 1312 | 0.248 | 0.038 |
| 1624 | 0.227 | 0.119 |
| 8 | 0.182 | 0.009 |
| 282 | 0.169 | 0.004 |
Person 1624 is the only name here that also appeared in the first three rankings.
A high authority score and a low hub score describe somebody the network writes to far more than they write out.
Other considerations
As with all algorithms, the meaning of an Endorsement result will change based on the analyzed graph.
For instance, had you run these algorithms on the undirected projection, every endorsement would also count backwards along the message that carried it. PageRank on an iFull definition for undirected relationship (opens in a new tab)A relationship with no direction. Neo4j GDS represents them as parallel relationships in opposite directions. graph often degrades to the same ranking as Degree Centrality.
Similarly, PageRank's damping factor is a setting you choose, so the same graph can produce more than one ranking.
Later, you will learn more about the nuances and differences between each of these algorithms in their dedicated labs.
Check your understanding
Sign in to test your knowledge with interactive questions, track your progress, and earn a certificate when you complete the course.
Sign in or register