neo4j cypher

Neo4j的最常见用途之一是构建实时推荐引擎,一个共同的主题是它们利用大量不同的数据来提出有趣的推荐。

例如, 在此视频中, 阿曼达(Amanda)展示了约会网站如何通过社交联系开始,然后介绍热情,位置和其他一些东西,从而构建实时推荐引擎。

Graph Aware有一个简洁的框架 ,可以帮助您使用Java构建自己的推荐引擎,我很好奇Cypher版本的外观。

这是示例图:

CREATE(m:Person:Male {name:'Michal', age:30}),(d:Person:Female {name:'Daniela', age:20}),(v:Person:Male {name:'Vince', age:40}),(a:Person:Male {name:'Adam', age:30}),(l:Person:Female {name:'Luanne', age:25}),(c:Person:Male {name:'Christophe', age:60}),(lon:City {name:'London'}),(mum:City {name:'Mumbai'}),(m)-[:FRIEND_OF]->(d),(m)-[:FRIEND_OF]->(l),(m)-[:FRIEND_OF]->(a),(m)-[:FRIEND_OF]->(v),(d)-[:FRIEND_OF]->(v),(c)-[:FRIEND_OF]->(v),(d)-[:LIVES_IN]->(lon),(v)-[:LIVES_IN]->(lon),(m)-[:LIVES_IN]->(lon),(l)-[:LIVES_IN]->(mum);

我们想向“亚当”推荐一些潜在的朋友,因此我们查询的第一层是找到他的朋友,因为其中肯定有一些潜在的朋友:

MATCH (me:Person {name: "Adam"})
MATCH (me)-[:FRIEND_OF]-()-[:FRIEND_OF]-(potentialFriend)
RETURN me, potentialFriend, COUNT(*) AS friendsInCommon==> +--------------------------------------------------------------------------------------+
==> | me                             | potentialFriend                   | friendsInCommon |
==> +--------------------------------------------------------------------------------------+
==> | Node[1007]{name:"Adam",age:30} | Node[1006]{name:"Vince",age:40}   | 1               |
==> | Node[1007]{name:"Adam",age:30} | Node[1005]{name:"Daniela",age:20} | 1               |
==> | Node[1007]{name:"Adam",age:30} | Node[1008]{name:"Luanne",age:25}  | 1               |
==> +--------------------------------------------------------------------------------------+
==> 3 rows

该查询为我们提供了潜在朋友的列表以及我们有多少个共同的朋友。

现在我们有了一些潜在的朋友,让我们开始为他们每个人建立一个排名。 一个可以吸引潜在朋友的指标是,如果他们和我们生活在同一地点,那么可以将其添加到查询中:

MATCH (me:Person {name: "Adam"})
MATCH (me)-[:FRIEND_OF]-()-[:FRIEND_OF]-(potentialFriend)WITH me, potentialFriend, COUNT(*) AS friendsInCommonRETURN  me,potentialFriend,SIZE((potentialFriend)-[:LIVES_IN]->()<-[:LIVES_IN]-(me)) AS sameLocation==> +-----------------------------------------------------------------------------------+
==> | me                             | potentialFriend                   | sameLocation |
==> +-----------------------------------------------------------------------------------+
==> | Node[1007]{name:"Adam",age:30} | Node[1006]{name:"Vince",age:40}   | 0            |
==> | Node[1007]{name:"Adam",age:30} | Node[1005]{name:"Daniela",age:20} | 0            |
==> | Node[1007]{name:"Adam",age:30} | Node[1008]{name:"Luanne",age:25}  | 0            |
==> +-----------------------------------------------------------------------------------+
==> 3 rows

接下来,我们将通过比较每个节点的标签来检查Adams的潜在朋友是否与他具有相同的性别。 我们提供了“性别”和“性别”标签。

MATCH (me:Person {name: "Adam"})
MATCH (me)-[:FRIEND_OF]-()-[:FRIEND_OF]-(potentialFriend)WITH me, potentialFriend, COUNT(*) AS friendsInCommonRETURN  me,potentialFriend,SIZE((potentialFriend)-[:LIVES_IN]->()<-[:LIVES_IN]-(me)) AS sameLocation,LABELS(me) = LABELS(potentialFriend) AS gender==> +--------------------------------------------------------------------------------------------+
==> | me                             | potentialFriend                   | sameLocation | gender |
==> +--------------------------------------------------------------------------------------------+
==> | Node[1007]{name:"Adam",age:30} | Node[1006]{name:"Vince",age:40}   | 0            | true   |
==> | Node[1007]{name:"Adam",age:30} | Node[1005]{name:"Daniela",age:20} | 0            | false  |
==> | Node[1007]{name:"Adam",age:30} | Node[1008]{name:"Luanne",age:25}  | 0            | false  |
==> +--------------------------------------------------------------------------------------------+
==> 3 rows

接下来,让我们计算亚当和他的潜在朋友之间的年龄差异:

MATCH (me:Person {name: "Adam"})
MATCH (me)-[:FRIEND_OF]-()-[:FRIEND_OF]-(potentialFriend)WITH me, potentialFriend, COUNT(*) AS friendsInCommonRETURN me,potentialFriend,SIZE((potentialFriend)-[:LIVES_IN]->()<-[:LIVES_IN]-(me)) AS sameLocation,abs( me.age - potentialFriend.age) AS ageDifference,LABELS(me) = LABELS(potentialFriend) AS gender,friendsInCommon==> +--------------------------------------------------------------------------------------+
==> | me                             | potentialFriend                   | sameLocation | ageDifference | gender | friendsInCommon |
==> +--------------------------------------------------------------------------------------+
==> | Node[1007]{name:"Adam",age:30} | Node[1006]{name:"Vince",age:40}   | 0            | 10.0          | true   | 1               |
==> | Node[1007]{name:"Adam",age:30} | Node[1005]{name:"Daniela",age:20} | 0            | 10.0          | false  | 1               |
==> | Node[1007]{name:"Adam",age:30} | Node[1008]{name:"Luanne",age:25}  | 0            | 5.0           | false  | 1               |
==> +--------------------------------------------------------------------------------------+
==> 3 rows

现在,让我们进行一些过滤,以摆脱与亚当已经成为朋友的人–推荐这些人没有多大意义!

MATCH (me:Person {name: "Adam"})
MATCH (me)-[:FRIEND_OF]-()-[:FRIEND_OF]-(potentialFriend)WITH me, potentialFriend, COUNT(*) AS friendsInCommonWITH me,potentialFriend,SIZE((potentialFriend)-[:LIVES_IN]->()<-[:LIVES_IN]-(me)) AS sameLocation,abs( me.age - potentialFriend.age) AS ageDifference,LABELS(me) = LABELS(potentialFriend) AS gender,friendsInCommonWHERE NOT (me)-[:FRIEND_OF]-(potentialFriend)RETURN me,potentialFriend,SIZE((potentialFriend)-[:LIVES_IN]->()<-[:LIVES_IN]-(me)) AS sameLocation,abs( me.age - potentialFriend.age) AS ageDifference,LABELS(me) = LABELS(potentialFriend) AS gender,friendsInCommon==> +---------------------------------------------------------------------------------------+
==> | me                             | potentialFriend                   | sameLocation | ageDifference | gender | friendsInCommon |
==> +---------------------------------------------------------------------------------------+
==> | Node[1007]{name:"Adam",age:30} | Node[1006]{name:"Vince",age:40}   | 0            | 10.0          | true   | 1               |
==> | Node[1007]{name:"Adam",age:30} | Node[1005]{name:"Daniela",age:20} | 0            | 10.0          | false  | 1               |
==> | Node[1007]{name:"Adam",age:30} | Node[1008]{name:"Luanne",age:25}  | 0            | 5.0           | false  | 1               |
==> +---------------------------------------------------------------------------------------+
==> 3 rows

在这种情况下,我们实际上并未将任何人过滤掉,但是对于其他一些人,我们会看到潜在朋友数量的减少。

我们的最后一步是为每个我们认为对提出朋友建议很重要的功能评分。

如果人们居住在与亚当相同的地方或性别相同,我们将给满分10分,否则给0分。 对于ageDifference和friendsInCommon,我们将应用对数曲线,以使这些值不会对我们的最终分数产生不成比例的影响。 我们将使用ParetoScoreTransfomer中定义的公式来执行此操作:

public <OUT> float transform(OUT item, float score) {if (score < minimumThreshold) {return 0;}double alpha = Math.log((double) 5) / eightyPercentLevel;double exp = Math.exp(-alpha * score);return new Double(maxScore * (1 - exp)).floatValue();}

现在,对于我们完整的推荐查询:

MATCH (me:Person {name: "Adam"})
MATCH (me)-[:FRIEND_OF]-()-[:FRIEND_OF]-(potentialFriend)WITH me, potentialFriend, COUNT(*) AS friendsInCommonWITH me,potentialFriend,SIZE((potentialFriend)-[:LIVES_IN]->()<-[:LIVES_IN]-(me)) AS sameLocation,abs( me.age - potentialFriend.age) AS ageDifference,LABELS(me) = LABELS(potentialFriend) AS gender,friendsInCommonWHERE NOT (me)-[:FRIEND_OF]-(potentialFriend)WITH potentialFriend,// 100 -> maxScore, 10 -> eightyPercentLevel, friendsInCommon -> score (from the formula above)100 * (1 - exp((-1.0 * (log(5.0) / 10)) * friendsInCommon)) AS friendsInCommon,sameLocation * 10 AS sameLocation,-1 * (10 * (1 - exp((-1.0 * (log(5.0) / 20)) * ageDifference))) AS ageDifference,CASE WHEN gender THEN 10 ELSE 0 END as sameGenderRETURN potentialFriend,{friendsInCommon: friendsInCommon,sameLocation: sameLocation,ageDifference:ageDifference,sameGender: sameGender} AS parts,friendsInCommon + sameLocation + ageDifference + sameGender AS score
ORDER BY score DESC==> +---------------------------------------------------------------------------------------+
==> | potentialFriend                   | parts                                                                                                           | score             |
==> +---------------------------------------------------------------------------------------+
==> | Node[1006]{name:"Vince",age:40}   | {friendsInCommon -> 14.86600774792154, sameLocation -> 0, ageDifference -> -5.52786404500042, sameGender -> 10} | 19.33814370292112 |
==> | Node[1008]{name:"Luanne",age:25}  | {friendsInCommon -> 14.86600774792154, sameLocation -> 0, ageDifference -> -3.312596950235779, sameGender -> 0} | 11.55341079768576 |
==> | Node[1005]{name:"Daniela",age:20} | {friendsInCommon -> 14.86600774792154, sameLocation -> 0, ageDifference -> -5.52786404500042, sameGender -> 0}  | 9.33814370292112  |
==> +----------------------------------------------------------------------------------------+

最终查询还不错-唯一真正复杂的部分是对数曲线计算。 用户定义的功能将在将来发挥作用。

这种方法的好处是我们不必走出密码的道路,因此,如果您对Java不满意,仍然可以进行实时建议! 另一方面,推荐引擎的不同部分混合在一起,因此要查看整个管道并不像使用图形感知框架那样容易。

下一步是将其应用于Twitter图形,并在此提供关注者建议。

翻译自: https://www.javacodegeeks.com/2015/03/neo4j-generating-real-time-recommendations-with-cypher.html

neo4j cypher

neo4j cypher_Neo4j:使用Cypher生成实时建议相关推荐

  1. Neo4j:使用Cypher生成实时建议

    Neo4j的最常见用途之一是构建实时推荐引擎,一个共同的主题是它们利用大量不同的数据来提出有趣的推荐. 例如, 在此视频中, 阿曼达(Amanda)展示了约会网站如何通过社交联系开始,然后介绍热情,位 ...

  2. neo4j cypher_Neo4j:Cypher –避免热切

    neo4j cypher 当心渴望的管道 尽管我喜欢Cypher的LOAD CSV命令使它容易地将数据获取到Neo4j中的方法,但它目前打破了最不惊奇的规则,因为它急切地在所有行中加载某些查询,即使是 ...

  3. neo4j cypher_Neo4j:Cypher – Neo.ClientError.Statement.TypeError:不知道如何添加Double和String...

    neo4j cypher 最近,我将支持Neo4j的应用程序从Neo4j 3.2升级到Neo4j 3.3,发现围绕类型强制的行为发生了有趣的变化,导致我的应用程序抛出了很多错误. 在Neo4j 3.2 ...

  4. nginx+lua+GraphicsMagick生成实时缩略图-CentOS7

    背景说明 大多数的系统都会涉及缩略图的处理,比如新闻系统和电商系统,特别是电商系统,每个商品大图都会对应一系列尺寸的缩略图用于不同业务场景的使用.部分系统也会生成不同尺寸的缩略图以供PC.手机端.ip ...

  5. neo4j cypher_neo4j / cypher:悬挂查询参数

    neo4j cypher 一直以来,我一直在使用neo4j的密码查询语言, 迈克尔一直在告诉我在查询中使用参数,但是查询的性能始终可以接受,因此我没有必要. 但是,最近我正在研究一个数据集,并使用类似 ...

  6. 【国内首家】第一个基于语音生成实时知识图谱的系统来啦!!!

    点击上方,选择星标或置顶,不定期资源大放送! 阅读大概需要8分钟 Follow小博主,每天更新前沿干货 基于文本生成知识图谱的研究很常见,但是基于语音生成知识图谱,这算是第一家. 在这个信息飞速发展的 ...

  7. Spring boot 整合Neo4j 实现动态Cypher

    提到spring boot整合Neo4j,一般都会提到spring-data-neo4j,使用类似于jpa的方式,使用entity去maintain,但是如果想要添加动态关系或者动态的node,就算是 ...

  8. 关于在neo4j中使用cypher语句实现NOT IN 的功能

    我们知道cypher语句中可以使用 IN [1,2,3] 来达到过滤集合数据的功能,那怎么实现NOT IN 呢? 经过研究cypher函数,我找到了方法.就是使用none()函数函数,这个函数的意思是 ...

  9. matlab根据数据生成实时动画,Matlab 坐标图动画,动态显示数据

    数据采集或者数据回放时,用matlab的plot画图的话一般都是静态的,一下画完了就不动了.但是有些时候,比如实时的数据采集然后通过串口或pci在matlab中画出数据的变化图并同步动态显示,以及在一 ...

最新文章

  1. 获取本年、本月、本周时间范围_为什么“增值税期末留抵税额本年累计数”很快就被废止了...
  2. Microsoft Desktop Player是IT Pro的宝贵工具
  3. msp430 c语言开发环境,如何使用C语言来编写MSP430的高质量代码
  4. 无法打开Win11系统小组件怎么办
  5. 【第九课】MriaDB密码重置和慢查询日志
  6. 打造物联网+WiFi融合新模式 华三通信发布卫星AP
  7. js监听scrolltop_js中scrollTop()方法和scroll()方法用法示例
  8. linux 不换行显示数据库,linux下怎么在不按回车情况下就能读取字符读取到字符不回显...
  9. 用canvas画太极图(一步步详解附带源代码)
  10. Sdut PTA练习 2021级-JAVA01 Java入门
  11. openwrt修改默认网关地址_命令下配置ip地址
  12. JS的IE和Firefox兼容性汇编(原作:hotman_x)
  13. 【coq】函数语言设计 笔记 01 - basics
  14. 使用网络图展示Venn图集合及Cytoscape操作视频
  15. 软件测试学习资料大全
  16. jquery mobile_使用jQuery Mobile改善Web应用程序的安全性
  17. fork()创建子进程步骤、函数用法及常见考点(内附fork()过程图)
  18. 七牛云 阿里云图片存储 新增套餐 分页 定时任务Quartz(作业:编辑和删除功能)
  19. 【我的Android进阶之旅】你了解adb device unauthorized的原因 和 adb授权机制的中adbkey与adbkey.pub的作用吗?
  20. SpringMVC的参数传递

热门文章

  1. CF311B-Cats Transport【斜率优化dp】
  2. 欢乐纪中B组周五模拟赛【2019.3.8】
  3. codeforces1497 E. Square-free division(数学+dp)
  4. [XSY] 传统游戏(DP、容斥)
  5. Codeforces Gym 101173 CERC 16 D BZOJ 4790 Dancing Disks
  6. Java阻塞队列ArrayBlockingQueue和LinkedBlockingQueue实现原理分析
  7. springmvc常用注解
  8. 数据结构(四)之单链表查找中间结点
  9. “老师,我不要苹果味的,我要葡萄味的”!
  10. java中,剩下的这两个内部类不太好理解!