From e5f3b5e7d563862607cef29cfd60d5d2b74be644 Mon Sep 17 00:00:00 2001
From: feger <marc.feger@uni-duesseldorf.de>
Date: Wed, 20 Feb 2019 19:53:03 +0100
Subject: [PATCH] Add Mean-Centering and Z-Score-Normalization for K-NN with
 Pearson-Correlation

---
 api/adoc/browser_guide.adoc | 57 ++++++++++++++++++++++++++++++++--
 api/html/browser_guide.html | 61 +++++++++++++++++++++++++++++++++++--
 2 files changed, 114 insertions(+), 4 deletions(-)

diff --git a/api/adoc/browser_guide.adoc b/api/adoc/browser_guide.adoc
index 71847aa..533ba2e 100644
--- a/api/adoc/browser_guide.adoc
+++ b/api/adoc/browser_guide.adoc
@@ -258,9 +258,62 @@ MATCH (p2:User)-[l:LIKES]->(statement) WHERE p2 <> p1
 WITH p1, p2, p1Vector, algo.similarity.asVector(statement, l.rating) AS p2Vector
 WITH p1 AS from, p2 AS to, algo.similarity.pearson(p1Vector, p2Vector, {vectorType: "maps"}) AS similarity
 ORDER BY similarity DESC limit toInt({k_neighbors})
-WHERE similarity <> 0.0
 
 MATCH (to)-[r:LIKES]->(s:Statement) WHERE NOT EXISTS((from)-[:LIKES]->(s))
-return from , to, s, sum(similarity * r.rating)/sum(abs(similarity)) as prediction
+RETURN from , to, s, sum(similarity * r.rating)/FILTER(x in [sum(abs(similarity)), 1] WHERE NOT x=0)[0] AS prediction
+ORDER BY prediction DESC LIMIT toInt({top_n})
+----
+
+== Get Top-N Prediction for User with Pearson-Similarity + Mean-Centering + kNN
+:k_neighbors: pass:a['<span value-key="k_neighbors">5</span>']
+:top_n: pass:a['<span value-key="top_n">5</span>']
+:user: pass:a['<span value-key="user">Björn</span>']
+
+
+++++
+Find Top-<input style="display:inline;width:30%;" value-for="top_n" class="form-control" value="5" size="40"> Predictions for <input
+style="display:inline;width:30%;" value-for="user" class="form-control" value="Björn" size="40"> in the <input style="display:inline;width:30%;"
+value-for="k_neighbors" class="form-control" value="5" size="40">-NN
+++++
+
+[source, cypher,subs=attributes]
+----
+MATCH (p1:User {public_nickname: {user}})-[l:LIKES]->(statement)
+WITH p1, algo.similarity.asVector(statement, l.rating) AS p1Vector, avg(l.rating) as u1_avg
+
+MATCH (p2:User)-[l:LIKES]->(statement) WHERE p2 <> p1
+WITH p1, p2, u1_avg, p1Vector, algo.similarity.asVector(statement, l.rating) AS p2Vector, avg(l.rating) as u2_avg
+WITH p1 AS from, p2 AS to, algo.similarity.pearson(p1Vector, p2Vector, {vectorType: "maps"}) AS similarity, u1_avg, u2_avg
+ORDER BY similarity DESC limit toInt({k_neighbors})
+
+MATCH (to)-[r:LIKES]->(s:Statement) WHERE NOT EXISTS((from)-[:LIKES]->(s))
+RETURN from , to, s, u1_avg + sum(similarity * (r.rating-u2_avg))/FILTER(x in [sum(abs(similarity)), 1] WHERE NOT x=0)[0] AS prediction
+ORDER BY prediction DESC LIMIT toInt({top_n})
+----
+
+== Get Top-N Prediction for User with Pearson-Similarity + Z-Score-Normalization + kNN
+:k_neighbors: pass:a['<span value-key="k_neighbors">5</span>']
+:top_n: pass:a['<span value-key="top_n">5</span>']
+:user: pass:a['<span value-key="user">Björn</span>']
+
+
+++++
+Find Top-<input style="display:inline;width:30%;" value-for="top_n" class="form-control" value="5" size="40"> Predictions for <input
+style="display:inline;width:30%;" value-for="user" class="form-control" value="Björn" size="40"> in the <input style="display:inline;width:30%;"
+value-for="k_neighbors" class="form-control" value="5" size="40">-NN
+++++
+
+[source, cypher,subs=attributes]
+----
+MATCH (p1:User {public_nickname: {user}})-[l:LIKES]->(statement)
+WITH p1, algo.similarity.asVector(statement, l.rating) AS p1Vector, avg(l.rating) as u1_avg, stDev(l.rating) as u1_std
+
+MATCH (p2:User)-[l:LIKES]->(statement) WHERE p2 <> p1
+WITH p1, p2, u1_avg, u1_std, p1Vector, algo.similarity.asVector(statement, l.rating) AS p2Vector, avg(l.rating) as u2_avg, stDev(l.rating) as u2_std
+WITH p1 AS from, p2 AS to, algo.similarity.pearson(p1Vector, p2Vector, {vectorType: "maps"}) AS similarity, u1_avg, u1_std, u2_avg, u2_std
+ORDER BY similarity DESC limit toInt({k_neighbors})
+
+MATCH (to)-[r:LIKES]->(s:Statement) WHERE NOT EXISTS((from)-[:LIKES]->(s))
+RETURN from , to, s, u1_avg + u1_std* sum(similarity*(r.rating-u2_avg)/u2_std)/FILTER(x in [sum(abs(similarity)), 1] WHERE NOT x=0)[0] AS prediction
 ORDER BY prediction DESC LIMIT toInt({top_n})
 ----
\ No newline at end of file
diff --git a/api/html/browser_guide.html b/api/html/browser_guide.html
index f608d78..e4cf3a5 100644
--- a/api/html/browser_guide.html
+++ b/api/html/browser_guide.html
@@ -376,10 +376,67 @@ MATCH (p2:User)-[l:LIKES]->(statement) WHERE p2 <> p1
 WITH p1, p2, p1Vector, algo.similarity.asVector(statement, l.rating) AS p2Vector
 WITH p1 AS from, p2 AS to, algo.similarity.pearson(p1Vector, p2Vector, {vectorType: "maps"}) AS similarity
 ORDER BY similarity DESC limit toInt('<span value-key="k_neighbors">5</span>')
-WHERE similarity <> 0.0
 
 MATCH (to)-[r:LIKES]->(s:Statement) WHERE NOT EXISTS((from)-[:LIKES]->(s))
-return from , to, s, sum(similarity * r.rating)/sum(abs(similarity)) as prediction
+RETURN from , to, s, sum(similarity * r.rating)/FILTER(x in [sum(abs(similarity)), 1] WHERE NOT x=0)[0] AS prediction
+ORDER BY prediction DESC LIMIT toInt('<span value-key="top_n">5</span>')<!--/code--></pre>
+</div>
+</div>
+	</div>
+  </div>
+</slide>
+
+
+
+<slide class="row-fluid">
+  <div class="col-sm-12">
+    <h3>Get Top-N Prediction for User with Pearson-Similarity + Mean-Centering + kNN</h3>
+    <br/>
+    <div>
+      Find Top-<input style="display:inline;width:30%;" value-for="top_n" class="form-control" value="5" size="40"> Predictions for <input
+style="display:inline;width:30%;" value-for="user" class="form-control" value="Björn" size="40"> in the <input style="display:inline;width:30%;"
+value-for="k_neighbors" class="form-control" value="5" size="40">-NN
+<div class="listingblock">
+<div class="content">
+<pre mode="cypher"  class="highlight pre-scrollable programlisting cm-s-neo code runnable standalone-example ng-binding" data-lang="cypher" lang="cypher"><!--code class="cypher language-cypher"-->MATCH (p1:User {public_nickname: '<span value-key="user">Björn</span>'})-[l:LIKES]->(statement)
+WITH p1, algo.similarity.asVector(statement, l.rating) AS p1Vector, avg(l.rating) as u1_avg
+
+MATCH (p2:User)-[l:LIKES]->(statement) WHERE p2 <> p1
+WITH p1, p2, u1_avg, p1Vector, algo.similarity.asVector(statement, l.rating) AS p2Vector, avg(l.rating) as u2_avg
+WITH p1 AS from, p2 AS to, algo.similarity.pearson(p1Vector, p2Vector, {vectorType: "maps"}) AS similarity, u1_avg, u2_avg
+ORDER BY similarity DESC limit toInt('<span value-key="k_neighbors">5</span>')
+
+MATCH (to)-[r:LIKES]->(s:Statement) WHERE NOT EXISTS((from)-[:LIKES]->(s))
+RETURN from , to, s, u1_avg + sum(similarity * (r.rating-u2_avg))/FILTER(x in [sum(abs(similarity)), 1] WHERE NOT x=0)[0] AS prediction
+ORDER BY prediction DESC LIMIT toInt('<span value-key="top_n">5</span>')<!--/code--></pre>
+</div>
+</div>
+	</div>
+  </div>
+</slide>
+
+
+
+<slide class="row-fluid">
+  <div class="col-sm-12">
+    <h3>Get Top-N Prediction for User with Pearson-Similarity + Z-Score-Normalization + kNN</h3>
+    <br/>
+    <div>
+      Find Top-<input style="display:inline;width:30%;" value-for="top_n" class="form-control" value="5" size="40"> Predictions for <input
+style="display:inline;width:30%;" value-for="user" class="form-control" value="Björn" size="40"> in the <input style="display:inline;width:30%;"
+value-for="k_neighbors" class="form-control" value="5" size="40">-NN
+<div class="listingblock">
+<div class="content">
+<pre mode="cypher"  class="highlight pre-scrollable programlisting cm-s-neo code runnable standalone-example ng-binding" data-lang="cypher" lang="cypher"><!--code class="cypher language-cypher"-->MATCH (p1:User {public_nickname: '<span value-key="user">Björn</span>'})-[l:LIKES]->(statement)
+WITH p1, algo.similarity.asVector(statement, l.rating) AS p1Vector, avg(l.rating) as u1_avg, stDev(l.rating) as u1_std
+
+MATCH (p2:User)-[l:LIKES]->(statement) WHERE p2 <> p1
+WITH p1, p2, u1_avg, u1_std, p1Vector, algo.similarity.asVector(statement, l.rating) AS p2Vector, avg(l.rating) as u2_avg, stDev(l.rating) as u2_std
+WITH p1 AS from, p2 AS to, algo.similarity.pearson(p1Vector, p2Vector, {vectorType: "maps"}) AS similarity, u1_avg, u1_std, u2_avg, u2_std
+ORDER BY similarity DESC limit toInt('<span value-key="k_neighbors">5</span>')
+
+MATCH (to)-[r:LIKES]->(s:Statement) WHERE NOT EXISTS((from)-[:LIKES]->(s))
+RETURN from , to, s, u1_avg + u1_std* sum(similarity*(r.rating-u2_avg)/u2_std)/FILTER(x in [sum(abs(similarity)), 1] WHERE NOT x=0)[0] AS prediction
 ORDER BY prediction DESC LIMIT toInt('<span value-key="top_n">5</span>')<!--/code--></pre>
 </div>
 </div>
-- 
GitLab