Graphing Brexit

I’m not sure who it is, but if you spot it let me know and I’ll update the CSV files.

What else can we discover from the data?47 people didn’t vote for anythingMATCH (person:Person)–>(party:Party)WHERE not((person)-[:FOR]->()) AND not ((person)-[:AGAINST]->())RETURN party.

name, count(*) AS countORDER BY count DESCNon votes by partyMany of those were cabinet members in the Conservative PartyMATCH (person:Person)WHERE not((person)-[:FOR]->()) AND not ((person)-[:AGAINST]->())MATCH path = (person)–>(:Motion)WHERE (:Party {name: "Con"})<–(person)RETURN pathLIMIT 50Did any Conservatives vote for Labour’s plan?MATCH path = (:Motion {id: 3})<-[:FOR]-()-[:MEMBER_OF]->(:Party {name: "Con"})RETURN pathConservatives voting for Labour’s planJust the one!Visualising the data with Neo4j BloomAfter writing a few more Cypher queries, I became curious whether we could do any visual analysis, so I opened up Neo4j Bloom.

Two of the most vocal people for leaving the EU are Boris Johnson and Jacob Rees-Mogg, and by entering the search phrase Boris Johnson Motion Jacob Rees-Mogg , we get the BoRees Star below:As we can see, they voted the same way for each of the motions.

Finding similar voters using Graph AlgorithmsAfter comparing a few more MPs like this, I wanted to try and automate the process, a problem that is perfect for the similarity algorithms in the Neo4j Graph Algorithms Library.

We want to work out how similar the voting patterns were for different people.

Initially I thought we could use Jaccard Similarity to do this, but realised it wouldn’t work so well because while two people can be connected to the same motion, that doesn’t mean they are similar — they have may have voted in different ways!Instead we will think of voting as giving a score to a motion.

If you vote:FOR then it means you like it.

Score of 1DID_NOT_VOTE then it means you’re unsure.

Score of 0.

5AGAINST then it means you don’t like it.

Score of 0If we score the votes like this it means that we can use one of the weight based similarity algorithms.

The cosine similarity algorithm is commonly used when working out similarity between items in recommendation engines, so we’ll give that one a try.

Whose votes were most similar to those of Boris?MATCH (p1Party:Party)<-[:MEMBER_OF]-(p1:Person)-[r1]->(m:Motion)WHERE p1.

5 ELSE 0 END AS r1Score, CASE WHEN type(r2) = "FOR" THEN 5 WHEN type(r2) = "DID_NOT_VOTE" THEN 0.

5 ELSE 0 END AS r2Score WITH p2.

name AS to, p2Party.

name AS party, algo.

similarity.

cosine(collect(r1Score), collect(r2Score)) AS similarityWHERE similarity > 0RETURN to, party, similarityORDER BY similarity DESCPerhaps not surprisingly, many of the people in the Conservative party voted the same way.

What about if we exclude people in the same party?MATCH (p1Party:Party)<-[:MEMBER_OF]-(p1:Person)-[r1]->(m:Motion)WHERE p1.

5 ELSE 0 END AS r1Score, CASE WHEN type(r2) = "FOR" THEN 5 WHEN type(r2) = "DID_NOT_VOTE" THEN 0.

5 ELSE 0 END AS r2ScoreWHERE p1Party <> p2Party WITH p2.

name AS to, p2Party.

name AS party, algo.

similarity.

cosine(collect(r1Score), collect(r2Score)) AS similarityWHERE similarity > 0RETURN to, party, similarityORDER BY similarity DESCInterestingly Kate Hoey is the MP for a constituency that voted 78% remain, yet is voting in a similar way to people who favour leave.

What next?This does lead the way for some potential future analysis.

Can we rank each of those options in terms of how much they favour the leave/remain positions, and work out which MPs are voting in a way most in line with what their constituency votes?Another thing we could do is create a similarity graph of MPs and then run some community detection algorithms over that.

And if you have a general interest in graph analysis of data, you might enjoy the O’Reilly Graph Algorithms Book that Amy Hodler and I have been working on over the last 9 months.

We’re in the final review stage and it should be available in the next few weeks.

You can register to get your free digital copy from the Neo4j website, at: neo4j.