相似度算法在知识图谱中的实现

栏目: 数据库 · 发布时间: 7年前

内容简介:随着知识图谱的火爆从美国一路烧到了国内,近几年知识图谱技术在国内已经得到了飞速的发展,我们对知识图谱的概念及应用都不再陌生。你可以看到知识图谱技术的应用出现在越来越多的垂直领域中。从最早大家最为熟悉的在搜索引擎中的应用,逐渐地扩充到金融领域、医药领域等等。今天我们已经在各行各业中,都能够看到知识图谱的身影,更多的技术人员也加入了我们知识图谱工程的大家庭。那么今天我们来就知识图谱的技术问题进行更深层的探讨。今天我将和大家分享一个,我在知识图谱搭建中遇到的棘手问题,相信有不少小伙伴也会遇到这样的问题。希望今天

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

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

我遇到的问题:

在构建知识图谱的图关系时,基础数据来自很多不同的数据源。比如金融风控领域中,我们要构建的知识图谱中,包含地址、公司等出现频率比较高,并且名称一模一样的可能性很低的词汇。

比如:北京市国贸中心写字楼和北京朝阳区建外大街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数据库,输入 :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)

neo4j插入结果:

相似度算法在知识图谱中的实现

那么我们用这个数据再进行一次计算

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

相似度计算结果:

相似度算法在知识图谱中的实现

以上,我们可以看到Arya和Karin的食物口味最相似,得分为0.889。最高分为1,因此它们非常接近最大相似度

下边还有很多相似度为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参数来做到这一点。

以下将返回用户流以及最相似的用户(即k=1):

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, {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如下

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

执行结果如下:

相似度算法在知识图谱中的实现

然后,我们可以写一个查询,以找出与我们相似的其他人可能喜欢的美食类型。

以下将找到与Praveena最相似的用户

Cypher:

MATCH (p:Person {name: "Praveena"})-[:SIMILAR]->(other),

(other)-[:LIKES]->(cuisine)

WHERE not((p)-[:LIKES]->(cuisine))

RETURN cuisine.name AS cuisine

执行结果:

相似度算法在知识图谱中的实现

以上就是整个的计算过程。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Mastering Regular Expressions, Second Edition

Mastering Regular Expressions, Second Edition

Jeffrey E F Friedl / O'Reilly Media / 2002-07-15 / USD 39.95

Regular expressions are an extremely powerful tool for manipulating text and data. They have spread like wildfire in recent years, now offered as standard features in Perl, Java, VB.NET and C# (and an......一起来看看 《Mastering Regular Expressions, Second Edition》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具