从谷歌最早提出知识图谱的概念后,知识图谱的火爆从美国一路烧到了国内,近几年知识图谱技术在国内已经得到了飞速的发展,我们对知识图谱的概念及应用都不再陌生。大家可以看到知识图谱技术的应用出现在越来越多的垂直领域中。从最早大家最为熟悉的在搜索引擎中的应用,逐渐地扩充到金融领域、医药领域等等。今天我们已经在各行各业中,都能够看到知识图谱的身影,更多的技术人员也加入了我们知识图谱工程的大家庭。

那么今天我们来就知识图谱的技术问题进行更深层的探讨。今天我将和大家分享一个,我在知识图谱搭建中遇到的棘手问题,相信有不少小伙伴也会遇到这样的问题。希望今天我分享的解决方案可以给大家一些帮助!

知识图谱构建的过程中不可回避的问题: 知识图谱也属于需要建立在海量数据之上的一种应用,在构建知识图谱的图关系时,基础数据来自很多不同的数据源。常见的数据源有抓取的公开信息、业务数据、三方数据、用户授权的数据等。

由于数据来源于不同的渠道,而中文又是一门博大精深的语言,同一种意义却又有很多种表达。那么这个棘手的问题就随之而来:我们收集的数据中,有大量的表达方式所表达的是相同的意义。比如:阿里巴巴网络技术有限公司和阿里巴巴集团是同一家公司么?北京市国贸中心写字楼和北京朝阳区建外大街1号国贸中心是同一个地址么?在金融风控领域中,公司的名称、地址是出现频率非常高的词汇,如果按照传统的字符串比对的方式,就会认为以上信息表示的并不是相同的意义,那这样,就会给知识图谱的构建造成很大的麻烦,因为创建了很多无用的实体,并且很多本应该创建的关系,却没有创建出来。

这个时候,需要进行的工作就是实体消歧,也就是说把地址、公司名称等信息经过处理后,变成同一个地址和公司名称,让他们表示同一种意义。只有这样,才能够将实体和关系成功的创建。

解决思路:

将这类容易造成歧义的字符串进行相似度计算,是解决这类问题的一种高效的手段。
那么在知名的图数据库Neo4j中,如何实现相似度以计算如何满足这种应用场景呢,就是我们接下来讨论的主要话题。

我将会采用余弦相似度计算来解决这个问题。大家都知道余弦相似度是n维空间中两个n维向量之间角度的余弦。它是两个向量的点积除以两个向量的长度(或幅度)的乘积。

具体的计算方式可参见下面的公式:

以上公式计算的结果介于-1和1之间,其中-1完全不同,1完全相似。

那么在图数据库Neo4j中如何进行余弦相似度计算呢?下面我会简单说明整个计算过程。不得不说我们非常幸运,Neo4j的插件提供了这样的一个功能,让我们能够简单、直接的在其上实现相似度计算。

首先我们来进行环境安装:
环境的安装其实非常的简单,这里你只需要一个jar包,就可以将其搞定。
下载链接:https://github.com/neo4j-contrib/neo4j-graph-algorithms/releases

下载后,具体的操作步骤如下:
将下载的"graph-algorithms-algo-3.5.0.1.jar"包拷贝到"$NEO4J_HOME/plugins"目录中

这里需要注意的是:要修改Neo4j的配置将
dbms.security.procedures.unrestricted=algo.*
添加到neo4j.conf文件当中,一定要做,要不然后边的试验会失败。然后重启Neo4j数据库就可以了。

插件安装成功后,打开你的Neo4j数据库,在Cypher的输入框中输入 :

RETURN algo.similarity.cosine([3,8,7,5,2,9], [10,8,6,6,4,5]) AS similarity

这个语句的意思就是调用Neo4j提供的算法计算库中的函数,并且计算[3,8,7,5,2,9]和 [10,8,6,6,4,5]两组数据的余弦相似度,那么返回的结果是(如下图):

那么其结果已经非常的接近1了。这就是这两个数字列表的余弦相似度值。这个时候你会发现使用Neo4j库中的插件来实现,非常的简单,远比自己开发一个这样的功能要容易的多。

那么下面,我们可以自己来根据公式进行推理一下,以便于进一步掌握这种算法。首先,我们创建一个图关系,将下面的Cypher在输入框中运行,就会创建好一个图关系:

MERGE (french:Cuisine {name:'French'})
MERGE (italian:Cuisine {name:'Italian'})
MERGE (indian:Cuisine {name:'Indian'})
MERGE (lebanese:Cuisine {name:'Lebanese'})
MERGE (portuguese:Cuisine {name:'Portuguese'})
MERGE (zhen:Person {name: "Zhen"})
MERGE (praveena:Person {name: "Praveena"})
MERGE (michael:Person {name: "Michael"})
MERGE (arya:Person {name: "Arya"})
MERGE (karin:Person {name: "Karin"})
MERGE (praveena)-[:LIKES {score: 9}]->(indian)
MERGE (praveena)-[:LIKES {score: 7}]->(portuguese)
MERGE (zhen)-[:LIKES {score: 10}]->(french)
MERGE (zhen)-[:LIKES {score: 6}]->(indian)
MERGE (michael)-[:LIKES {score: 8}]->(french)
MERGE (michael)-[:LIKES {score: 7}]->(italian)
MERGE (michael)-[:LIKES {score: 9}]->(indian)
MERGE (arya)-[:LIKES {score: 10}]->(lebanese)
MERGE (arya)-[:LIKES {score: 10}]->(italian)
MERGE (arya)-[:LIKES {score: 7}]->(portuguese)
MERGE (karin)-[:LIKES {score: 9}]->(lebanese)
MERGE (karin)-[:LIKES {score: 7}]->(italian)

下面我们再用这个数据进行一次计算,输入以下Cypher:

MATCH (p:Person), (c:Cuisine) OPTIONAL MATCH (p)-[likes:LIKES]->(c) WITH {item:id(p), weights: collect(coalesce(likes.score, 0))} as userData WITH collect(userData) as data CALL algo.similarity.cosine.stream(data) YIELD item1, item2, count1, count2, similarity RETURN algo.getNodeById(item1).name AS from, algo.getNodeById(item2).name AS to, similarity ORDER BY similarity DESC

运行后的结果是:

我们从结果中可以看到得分为0.889的是最高分,那么我们可以认为Arya和Karin的食物口味最相似。但结果当中还有很多数据是我们不关心的,因为他们的相似度为0,原因是我数据库中原本有一些数据导致,那么现在我们要把这些数据过滤掉,输入以下Cypher:

MATCH (p:Person), (c:Cuisine)
OPTIONAL MATCH (p)-[likes:LIKES]->(c)
WITH {item:id(p), weights: collect(coalesce(likes.score, 0))} as userData
WITH collect(userData) as data
CALL algo.similarity.cosine.stream(data, {similarityCutoff: 0.0})
YIELD item1, item2, count1, count2, similarity
RETURN algo.getNodeById(item1).name AS from, algo.getNodeById(item2).name AS to, similarity
ORDER BY similarity DESC

运行结果如下:

我们可以看到那些没有相似性的数据已被过滤掉了。如果我们正在实现k-Nearest Neighbors类型查询,我们可能希望k为给定数据找到最相似的数据。我们可以通过传入topK参数来进行条件控制。

使用以下Cypher将返回最相似的数据(即k=1):

MATCH (p:Person), (c:Cuisine)
OPTIONAL MATCH (p)-[likes:LIKES]->(c)
WITH {item:id(p), weights: collect(coalesce(likes.score, 0))} as userData
WITH collect(userData) as data
CALL algo.similarity.cosine.stream(data, {topK:1, similarityCutoff: 0.0})
YIELD item1, item2, count1, count2, similarity
RETURN algo.getNodeById(item1).name AS from, algo.getNodeById(item2).name AS to, similarity
ORDER BY from

执行结果:

细心的同学会发现,以上的结果有一点问题,第一行的结果和第二行的结果其实是相同的。那么我们现在要做的是为每个用户找到最相似的用户,并存储这些用户之间的关系:

下面在你的Cypher输入框中输入以下Cypher:

MATCH (p:Person), (c:Cuisine)
OPTIONAL MATCH (p)-[likes:LIKES]->(c)
WITH {item:id(p), weights: collect(coalesce(likes.score, 0))} as userData
WITH collect(userData) as data
CALL algo.similarity.cosine(data, {topK: 1, similarityCutoff: 0.1, write:true})
YIELD nodes, similarityPairs, write, writeRelationshipType, writeProperty, min, max, mean, stdDev, p25, p50, p75, p90, p95, p99, p999, p100
RETURN nodes, similarityPairs, write, writeRelationshipType, writeProperty, min, max, mean, p95

执行结果如下:

然后,我们可以写一个查询,以找出与我们相似的其他人可能喜欢的美食类型。
以下Cypher将找到与Praveena最相似的用户

MATCH (p:Person {name: "Praveena"})-[:SIMILAR]->(other),
(other)-[:LIKES]->(cuisine)
WHERE not((p)-[:LIKES]->(cuisine))
RETURN cuisine.name AS cuisine

很幸运,我们已经找到了,下面就是执行结果:

以上就是整个的计算过程。解决相似度计算的思路我们已经有了。 在知识图谱的构建中,还有更多的挑战等着我们。


本文转载自"贪心科技AI"公众号
原文链接https://mp.weixin.qq.com/s/wlsVlyRsig3Fisv78pGJug

知识图谱中的余弦相似度计算相关推荐

  1. Python简单实现基于VSM的余弦相似度计算

    在知识图谱构建阶段的实体对齐和属性值决策.判断一篇文章是否是你喜欢的文章.比较两篇文章的相似性等实例中,都涉及到了向量空间模型(Vector Space Model,简称VSM)和余弦相似度计算相关知 ...

  2. 实体对齐 算法_知识图谱中的实体对齐方法及装置与流程

    本发明涉及计算机领域,具体而言,涉及一种知识图谱中的实体对齐方法及装置. 背景技术: 在构建大规模知识库的任务中,需要处理大量来自多源知识库的实体数据.在构建知识库之初,首先需建立一个知识描述体系,然 ...

  3. 论文小综 | 知识图谱中的复杂查询问答

    作者 | 张文,浙江大学博士,研究兴趣为知识图谱表示与推理 陈名杨,浙江大学在读博士生,研究兴趣为知识图谱表示与推理 本文将介绍近两年4篇关于知识图谱中的复杂查询问答(Complex Query An ...

  4. 知识图谱中的关系方向与强度研究

    知识图谱中的关系方向与强度研究 臧根林1,2, 王亚强1,2, 吴庆蓉1,2, 占春丽1,2, 谢新扬1,2 1 拓尔思知识图谱研究院,广东 广州 510665 2 广州拓尔思大数据有限公司,广东 广 ...

  5. 余弦相似度计算的实现方式

    目录 一.余弦相似度计算方式 1.python 2.sklearn 3.scipy 4.numpy 5.pytorch 6.faiss 二.规模暴增计算加速 1.numpy矩阵计算GPU加速--cup ...

  6. 知识图谱学习笔记之知识图谱中的知识分类

    知识图谱中的知识分类 事实知识 事实知识是关于某个特定实体的基本事实,如(山东富士苹果,产地,山东).事实知识是知识图谱中非常常见的知识类型.大部分的事实知识都是在描述实体的特定属性或关系,如&quo ...

  7. 知识图谱中的关系推理,究竟是个什么玩意儿?

    关系推理是我全新接触的东西,虽然大一暑假的时候,留校做比赛有了解过神经网络的相关算法, 看过十多篇国内的论文,但这一次跟着刘老师的团队进行的这份工作,才让我真正的感受到了科研的魅力. 说起来,机器学习 ...

  8. 文本分析—余弦相似度计算

    文本分析-余弦相似度计算 一.余弦相似度简介 欧几里得点积公式:a · b = || a || || b || cosθ 我们从图中可以看出,利用两个向量之间夹角的余弦值来代表两个向量之间的差异. 那 ...

  9. 使用余弦相似度计算文本相似度

    1. 使用simhash计算文本相似度 2. 使用余弦相似度计算文本相似度 3. 使用编辑距离计算文本相似度 4. jaccard系数计算文本相似度 2.向量余弦计算文本相似度 2.1 原理 余弦相似 ...

最新文章

  1. TMS320C6678中Hyperlink接口的理解
  2. WebAssembly 浏览器中运行c/c++模块
  3. php 数组Array 删除指定键名值
  4. linux文件一列加1,Linux命令(1)-创建文件
  5. python 3.9 发布计划_Python 3.9.0 beta4 发布
  6. jquery指定节点设css,jquery 获取和设置节点属性 css样式
  7. 2021年上犹中学高考成绩查询入口,上犹县2019年高考成绩单出来了……
  8. java指定存入arraylist值_Java高效打印出0000-9999之间所有的值存到arraylist集合中
  9. 更适合智能家庭使用的新 Wi-Fi 技术问世了
  10. Python报错: RuntimeError: The current Numpy installation (‘D:\\Develop\\anaconda\\lib\\site-packages\\
  11. PHP连接MongoDB
  12. 震惊!Faker.js作者删库,理由竟然是 拒绝被“白嫖”~
  13. HDU 2258 Continuous Same Game
  14. 定时器_STM32通用定时器
  15. 不同转录组测序方法总结
  16. 日本东京成田国际机场的第三候机楼
  17. ❌ Exiting due to GUEST_PROVISION: Failed to cache ISO: unable to cache ISO:
  18. 强化学习(RL)算法
  19. Advance Steel Addon for Autodesk AutoCAD 2022.0.1 x64
  20. LeetCode 871. Minimum Number of Refueling Stops 最少加油次数

热门文章

  1. 常用数据分析指标和术语
  2. linux中进程pid,线程tid以及线程pid
  3. c++ 11 原子操作库 (std::atomic)(一)
  4. c语言特殊字符字符串宽度对齐,[转]C语言字节对齐问题详解
  5. pg 递归算法_PostgreSQL递归查询示例
  6. 拍卖售价最高的10幅超现实主义作品公布 | 周末
  7. 机器学习scikit-learn入门
  8. 大班音乐机器人反思_幼儿园大班音乐游戏教案《机器人》含反思
  9. SteamVR插件使用
  10. 《嵌入式Linux驱动开发教程》--高级I/O操作