Skip to content
This repository was archived by the owner on Apr 22, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions doc/asciidoc/scripts/similarity-cosine.cypher
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,23 @@ MERGE (karin)-[:LIKES {score: 10}]->(portuguese)

// end::create-sample-graph[]

// tag::function-cypher[]
MATCH (p1:Person {name: 'Michael'})-[likes1:LIKES]->(cuisine)
MATCH (p2:Person {name: "Arya"})-[likes2:LIKES]->(cuisine)
RETURN p1.name AS from,
p2.name AS to,
algo.similarity.cosine(collect(likes1.score), collect(likes2.score)) AS similarity
// end::function-cypher[]

// tag::function-cypher-all[]
MATCH (p1:Person {name: 'Michael'})-[likes1:LIKES]->(cuisine)
MATCH (p2:Person)-[likes2:LIKES]->(cuisine) WHERE p2 <> p1
RETURN p1.name AS from,
p2.name AS to,
algo.similarity.cosine(collect(likes1.score), collect(likes2.score)) AS similarity
ORDER BY similarity DESC
// end::function-cypher-all[]

// tag::stream[]
MATCH (p:Person), (c:Cuisine)
OPTIONAL MATCH (p)-[likes:LIKES]->(c)
Expand Down
25 changes: 25 additions & 0 deletions doc/asciidoc/scripts/similarity-euclidean.cypher
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ MERGE (italian:Cuisine {name:'Italian'})
MERGE (indian:Cuisine {name:'Indian'})
MERGE (lebanese:Cuisine {name:'Lebanese'})
MERGE (portuguese:Cuisine {name:'Portuguese'})
MERGE (british:Cuisine {name:'British'})
MERGE (mauritian:Cuisine {name:'Mauritian'})

MERGE (zhen:Person {name: "Zhen"})
MERGE (praveena:Person {name: "Praveena"})
Expand All @@ -18,23 +20,46 @@ MERGE (karin:Person {name: "Karin"})

MERGE (praveena)-[:LIKES {score: 9}]->(indian)
MERGE (praveena)-[:LIKES {score: 7}]->(portuguese)
MERGE (praveena)-[:LIKES {score: 8}]->(british)
MERGE (praveena)-[:LIKES {score: 1}]->(mauritian)

MERGE (zhen)-[:LIKES {score: 10}]->(french)
MERGE (zhen)-[:LIKES {score: 6}]->(indian)
MERGE (zhen)-[:LIKES {score: 2}]->(british)

MERGE (michael)-[:LIKES {score: 8}]->(french)
MERGE (michael)-[:LIKES {score: 7}]->(italian)
MERGE (michael)-[:LIKES {score: 9}]->(indian)
MERGE (michael)-[:LIKES {score: 3}]->(portuguese)

MERGE (arya)-[:LIKES {score: 10}]->(lebanese)
MERGE (arya)-[:LIKES {score: 10}]->(italian)
MERGE (arya)-[:LIKES {score: 7}]->(portuguese)
MERGE (arya)-[:LIKES {score: 9}]->(mauritian)

MERGE (karin)-[:LIKES {score: 9}]->(lebanese)
MERGE (karin)-[:LIKES {score: 7}]->(italian)
MERGE (karin)-[:LIKES {score: 10}]->(portuguese)

// end::create-sample-graph[]

// tag::function-cypher[]
MATCH (p1:Person {name: 'Zhen'})-[likes1:LIKES]->(cuisine)
MATCH (p2:Person {name: "Praveena"})-[likes2:LIKES]->(cuisine)
RETURN p1.name AS from,
p2.name AS to,
algo.similarity.euclideanDistance(collect(likes1.score), collect(likes2.score)) AS similarity
// end::function-cypher[]

// tag::function-cypher-all[]
MATCH (p1:Person {name: 'Zhen'})-[likes1:LIKES]->(cuisine)
MATCH (p2:Person)-[likes2:LIKES]->(cuisine) WHERE p2 <> p1
RETURN p1.name AS from,
p2.name AS to,
algo.similarity.euclideanDistance(collect(likes1.score), collect(likes2.score)) AS similarity
ORDER BY similarity DESC
// end::function-cypher-all[]

// tag::stream[]
MATCH (p:Person), (c:Cuisine)
OPTIONAL MATCH (p)-[likes:LIKES]->(c)
Expand Down
22 changes: 22 additions & 0 deletions doc/asciidoc/scripts/similarity-jaccard.cypher
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,28 @@ MERGE (karin)-[:LIKES]->(italian)

// end::create-sample-graph[]


// tag::function-cypher[]
MATCH (p1:Person {name: 'Karin'})-[:LIKES]->(cuisine1)
WITH p1, collect(id(cuisine1)) AS p1Cuisine
MATCH (p2:Person {name: "Arya"})-[:LIKES]->(cuisine2)
WITH p1, p1Cuisine, p2, collect(id(cuisine2)) AS p2Cuisine
RETURN p1.name AS from,
p2.name AS to,
algo.similarity.jaccard(p1Cuisine, p2Cuisine) AS similarity
// end::function-cypher[]

// tag::function-cypher-all[]
MATCH (p1:Person {name: 'Karin'})-[:LIKES]->(cuisine1)
WITH p1, collect(id(cuisine1)) AS p1Cuisine
MATCH (p2:Person)-[:LIKES]->(cuisine2) WHERE p1 <> p2
WITH p1, p1Cuisine, p2, collect(id(cuisine2)) AS p2Cuisine
RETURN p1.name AS from,
p2.name AS to,
algo.similarity.jaccard(p1Cuisine, p2Cuisine) AS similarity
ORDER BY similarity DESC
// end::function-cypher-all[]

// tag::stream[]
MATCH (p:Person)-[:LIKES]->(cuisine)
WITH {item:id(p), categories: collect(id(cuisine))} as userData
Expand Down
22 changes: 22 additions & 0 deletions doc/asciidoc/scripts/similarity-pearson.cypher
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,28 @@ MERGE (karin)-[:RATED {score: 9}]->(gruffalo)

// end::create-sample-graph[]

// tag::function-cypher[]
MATCH (p1:Person {name: 'Arya'})-[rated:RATED]->(movie)
WITH p1, algo.similarity.asVector(movie, rated.score) AS p1Vector
MATCH (p2:Person {name: 'Karin'})-[rated:RATED]->(movie)
WITH p1, p2, p1Vector, algo.similarity.asVector(movie, rated.score) AS p2Vector
RETURN p1.name AS from,
p2.name AS to,
algo.similarity.pearson(p1Vector, p2Vector, {vectorType: "maps"}) AS similarity
// end::function-cypher[]

// tag::function-cypher-all[]
MATCH (p1:Person {name: 'Arya'})-[rated:RATED]->(movie)
WITH p1, algo.similarity.asVector(movie, rated.score) AS p1Vector
MATCH (p2:Person)-[rated:RATED]->(movie) WHERE p2 <> p1
WITH p1, p2, p1Vector, algo.similarity.asVector(movie, rated.score) AS p2Vector
RETURN p1.name AS from,
p2.name AS to,
algo.similarity.pearson(p1Vector, p2Vector, {vectorType: "maps"}) AS similarity
ORDER BY similarity DESC
// end::function-cypher-all[]


// tag::stream[]
MATCH (p:Person), (m:Movie)
OPTIONAL MATCH (p)-[rated:RATED]->(m)
Expand Down
35 changes: 35 additions & 0 deletions doc/asciidoc/similarity-cosine.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,41 @@ image::cosine-similarity2.png[role="middle"]
include::scripts/similarity-cosine.cypher[tag=create-sample-graph]
----

.The following will return the Cosine similarity of Michael and Arya:
[source, cypher]
----
include::scripts/similarity-cosine.cypher[tag=function-cypher]
----

// tag::function-cypher[]
.Results
[opts="header"]
|===
| `from` | `to` | `similarity`
| "Michael" | "Arya" | 0.9788908326303921

|===
// end::function-cypher[]

.The following will return the Cosine similarity of Michael and the other people that have a cuisine in common:
[source, cypher]
----
include::scripts/similarity-cosine.cypher[tag=function-cypher-all]
----

// tag::function-cypher--all[]
.Results
[opts="header"]
|===
| `from` | `to` | `similarity`
| "Michael" | "Arya" | 0.9788908326303921
| "Michael" | "Zhen" | 0.9542262139256075
| "Michael" | "Praveena" | 0.9429903335828894
| "Michael" | "Karin" | 0.8498063272285821

|===
// end::function-cypher-all[]

.The following will return a stream of node pairs along with their Cosine similarities:
[source, cypher]
----
Expand Down
33 changes: 33 additions & 0 deletions doc/asciidoc/similarity-euclidean.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,39 @@ These two lists of numbers have a euclidean distance of 8.42.
include::scripts/similarity-euclidean.cypher[tag=create-sample-graph]
----

.The following will return the Euclidean distance of Zhen and Praveena:
[source, cypher]
----
include::scripts/similarity-euclidean.cypher[tag=function-cypher]
----

// tag::function-cypher[]
.Results
[opts="header"]
|===
| `from` | `to` | `similarity`
| "Zhen" | "Praveena" | 6.708203932499369

|===
// end::function-cypher[]

.The following will return the Euclidean distance of Zhen and the other people that have a cuisine in common:
[source, cypher]
----
include::scripts/similarity-euclidean.cypher[tag=function-cypher-all]
----

// tag::function-cypher--all[]
.Results
[opts="header"]
|===
| `from` | `to` | `similarity`
| "Zhen" | "Praveena" | 6.708203932499369
| "Zhen" | "Michael" | 3.605551275463989

|===
// end::function-cypher-all[]

.The following will return a stream of node pairs, along with their intersection and euclidean similarities:
[source, cypher]
----
Expand Down
35 changes: 35 additions & 0 deletions doc/asciidoc/similarity-jaccard.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,41 @@ J(A,B) = 2 / 3 + 4 - 2
include::scripts/similarity-jaccard.cypher[tag=create-sample-graph]
----

.The following will return the Jaccard similarity of Karin and Arya:
[source, cypher]
----
include::scripts/similarity-jaccard.cypher[tag=function-cypher]
----

// tag::function-cypher[]
.Results
[opts="header"]
|===
| `from` | `to` | `similarity`
| "Karin" | "Arya" | 0.66

|===
// end::function-cypher[]

.The following will return the Jaccard similarity of Karin and the other people that have a cuisine in common:
[source, cypher]
----
include::scripts/similarity-jaccard.cypher[tag=function-cypher-all]
----

// tag::function-cypher--all[]
.Results
[opts="header"]
|===
| `from` | `to` | `similarity`
| "Karin" | "Arya" | 0.66
| "Karin" | "Michael" | 0.25
| "Karin" | "Praveena" | 0.0
| "Karin" | "Zhen" | 0.0

|===
// end::function-cypher-all[]

.The following will return a stream of node pairs along with their intersection and Jaccard similarities:
[source, cypher]
----
Expand Down
41 changes: 41 additions & 0 deletions doc/asciidoc/similarity-pearson.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,47 @@ include::scripts/similarity-pearson.cypher[tag=function]
include::scripts/similarity-pearson.cypher[tag=create-sample-graph]
----

.The following will return the Pearson similarity of Arya and Karin:
[source, cypher]
----
include::scripts/similarity-pearson.cypher[tag=function-cypher]
----

// tag::function-cypher[]
.Results
[opts="header"]
|===
| `from` | `to` | `similarity`
|"Arya" | "Karin" | 0.8194651785206903

|===
// end::function-cypher[]


In this example, we pass in `vectorType: "maps"` as an extra parameter, as well as using the `algo.similarity.asVector` function to construct a vector of maps containing each movie and the corresponding rating.
We do this because the Pearson Similarity algorithm needs to compute the average of *all* the movies that a user has reviewed, not just the ones that they have in common with the user we're comparing them to.
We can't therefore just pass in collections of the ratings of movies that have been reviewed by both people.

.The following will return the Pearson similarity of Arya and other people that have rated at least one movie:
[source, cypher]
----
include::scripts/similarity-pearson.cypher[tag=function-cypher-all]
----

// tag::function-cypher--all[]
.Results
[opts="header"]
|===
| `from` | `to` | `similarity`
| "Arya" | "Karin" | 0.8194651785206903
| "Arya" | "Zhen" | 0.4839533792540704
| "Arya" | "Praveena" | 0.09262336892949784
| "Arya" | "Michael" | -0.9551953674747637

|===
// end::function-cypher-all[]


.The following will return a stream of node pairs along with their Pearson similarities:
[source, cypher]
----
Expand Down