Jaccard Similarity 如何使用 writeRelationshipType 创建 "SIMILAR" 关系
Jaccard Similarity how to create "SIMILAR" relationship using writeRelationshipType
我正在尝试根据 Jaccard 相似度截止点建议关键字。最终目标是使用 py2neo 并在用户需要推荐关键字时调用此查询。
我的理由是:
(Title1)-[:HAS_KEYWORDS]->(Keyword1)<-[:HAS_KEYWORDS]-(Title2)-[:HAS_KEYWORDS]->(Keyword2)
我正在按照手册中的示例进行操作:
https://neo4j.com/docs/graph-algorithms/current/algorithms/similarity-jaccard/
我的数据表示如下: 我的测试数据 csv 文件的表示如下: CSV 用于创建所有标题节点:
title_id,title
T1,Article Title 1
T2,Article Title 2
我想用来创建关系的 CSV:
title_id,keyword_id,keyword
T1,K1,aaa
T1,K2,bbb
T1,K3,ccc
T1,K4,ddd
T2,K1,aaa
T2,K5,eee
T2,K6,fff
T2,K4,ddd
我目前正在计算相似度:
我试过以下方法:
MATCH (search_query:Title)-[:HAS_KEYWORDS]->(k_id:Keyword)
<-[:HAS_KEYWORDS]-(return_query:Title)-[r2:HAS_KEYWORDS]->(rec_k:Keyword)
WITH {item:id(return_query), categories: collect(id(rec_k))} as userData
WITH collect(userData) as data
CALL algo.similarity.jaccard.stream(data, {similarityCutoff: 0.0})
YIELD item1, item2, count1, count2, intersection, similarity
RETURN algo.getNodeById(item1) AS from, algo.getNodeById(item2) AS to, intersection, similarity ORDER BY similarity DESC
但是,当我继续执行该示例时,该示例使用了另一个查询,我也尝试复制该查询:
MATCH (search_query:Title)
-[:HAS_KEYWORDS]->(k_id:Keyword)
<-[:HAS_KEYWORDS]-(return_query:Title)
-[r2:HAS_KEYWORDS]->(rec_k:Keyword)
WITH {item:id(return_query), categories: collect(id(rec_k))} as userData
WITH collect(userData) as data
CALL algo.similarity.jaccard(data, {topK: 1, similarityCutoff: 0.0, 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
我正在尝试进入下一步并查询相似关系,
但是当我检查我的结果时,我发现我的测试图中没有创建相似关系。
因此,我的第一个问题是: 问:为什么 SIMILAR 关系没有出现在我的图表中?
(一个相关的子问题:我相信我的 MATCH 逻辑会搜索所有标题,这些标题至少有一个与另一个标题共同的关键字,另一个标题也必须至少有一个其他 non-related 关键字。如果我使用第二个例子, 我只能创建一个 SIMILAR 关系吗?)
我的第二个问题与我的最终目标有关。 Q:如果我正确理解查询,只有最相似的结果才会在数据库中存储SIMILAR关系;我可以在函数内使用相同的查询吗?目前我的函数看起来像这样:
def get_similar_keywords(self):
'''
MATCH (search_query:Title)
-[:HAS_KEYWORDS]->(k_id:Keyword)
<-[:HAS_KEYWORDS]-(return_query:Title)
-[r2:HAS_KEYWORDS]->(rec_k:Keyword)
WITH {item:id(return_query), categories: collect(id(rec_k))} as userData
WITH collect(userData) as data
CALL algo.similarity.jaccard(data, {topK: 1, similarityCutoff: 0.0, 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
'''
return graph.run(query, username=self.username)
现在,我的目标是找出: 1. MATCH 条件背后的想法是否错误; 2. 如何使用写入关系类型创建 SIMILAR 关系以及 3. 找出是否可以重用这些查询。
目前,在使用变量之后。我认为我的 Jaccard 相似度值看起来正确:
╒═══════╤═════════════════╤═══════╤═══════════════════════╤═══════════════╤═>══════════════════╤══════════════════╤══════════════════╤══════════════════╕
│"nodes"│"similarityPairs"│"write"│"writeRelationshipType"│"writeProperty"│">min" │"max" │"mean" │"p95" │
╞═══════╪═════════════════╪═══════╪═══════════════════════╪═══════════════╪═>══════════════════╪══════════════════╪══════════════════╪══════════════════╡
│7 │5 │false │"SIMILAR" │"score" >│0.01162785291671753│0.5844191908836365│0.2831512808799744│0.584419190883636>5│
└───────┴─────────────────┴───────┴───────────────────────┴───────────────┴─>──────────────────┴──────────────────┴──────────────────┴──────────────────┘
I just don't quite get why it shows it has "SIMILAR" but nothing shows up on the graph...
如果我在正确的轨道上,我想复制这段代码:
MATCH (p:Person {name: "Praveena"})-[:SIMILAR]->(other),
(other)-[:LIKES]->(cuisine)
WHERE not((p)-[:LIKES]->(cuisine))
RETURN cuisine.name AS cuisine
...和return通过py2neo推荐的关键字。
非常感谢,
埃里克
如果要写回 SIMILAR 关系,则必须使用 similarityCutoff: 0.1
或更高。查看 source code 以了解更多信息。
此外,您的 MATCH
查询有点偏差,因此回写查询应如下所示:
MATCH (search_query:Title)-[:HAS_KEYWORDS]->(k_id:Keyword)
WITH {item:id(search_query), categories: collect(id(k_id))} as userData
WITH collect(userData) as data
CALL algo.similarity.jaccard(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
您输入标题的 ID 作为 item
,将描述标题的所有关键字的 ID 作为类别输入,让算法处理其余部分。
现在您已经存储了关系,您可以执行推荐查询。
MATCH (p:Title {name: "T1"})-[:SIMILAR]->(other),
(other)-[:HAS_KEYWORDS]->(keyword)
WHERE not((p)-[:HAS_KEYWORDS]->(keyword))
RETURN keyword.name AS keywords
我正在尝试根据 Jaccard 相似度截止点建议关键字。最终目标是使用 py2neo 并在用户需要推荐关键字时调用此查询。 我的理由是:
(Title1)-[:HAS_KEYWORDS]->(Keyword1)<-[:HAS_KEYWORDS]-(Title2)-[:HAS_KEYWORDS]->(Keyword2)
我正在按照手册中的示例进行操作:
https://neo4j.com/docs/graph-algorithms/current/algorithms/similarity-jaccard/
我的数据表示如下: 我的测试数据 csv 文件的表示如下: CSV 用于创建所有标题节点:
title_id,title
T1,Article Title 1
T2,Article Title 2
我想用来创建关系的 CSV:
title_id,keyword_id,keyword
T1,K1,aaa
T1,K2,bbb
T1,K3,ccc
T1,K4,ddd
T2,K1,aaa
T2,K5,eee
T2,K6,fff
T2,K4,ddd
我目前正在计算相似度:
我试过以下方法:
MATCH (search_query:Title)-[:HAS_KEYWORDS]->(k_id:Keyword)
<-[:HAS_KEYWORDS]-(return_query:Title)-[r2:HAS_KEYWORDS]->(rec_k:Keyword)
WITH {item:id(return_query), categories: collect(id(rec_k))} as userData
WITH collect(userData) as data
CALL algo.similarity.jaccard.stream(data, {similarityCutoff: 0.0})
YIELD item1, item2, count1, count2, intersection, similarity
RETURN algo.getNodeById(item1) AS from, algo.getNodeById(item2) AS to, intersection, similarity ORDER BY similarity DESC
但是,当我继续执行该示例时,该示例使用了另一个查询,我也尝试复制该查询:
MATCH (search_query:Title)
-[:HAS_KEYWORDS]->(k_id:Keyword)
<-[:HAS_KEYWORDS]-(return_query:Title)
-[r2:HAS_KEYWORDS]->(rec_k:Keyword)
WITH {item:id(return_query), categories: collect(id(rec_k))} as userData
WITH collect(userData) as data
CALL algo.similarity.jaccard(data, {topK: 1, similarityCutoff: 0.0, 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
我正在尝试进入下一步并查询相似关系,
但是当我检查我的结果时,我发现我的测试图中没有创建相似关系。
因此,我的第一个问题是: 问:为什么 SIMILAR 关系没有出现在我的图表中?
(一个相关的子问题:我相信我的 MATCH 逻辑会搜索所有标题,这些标题至少有一个与另一个标题共同的关键字,另一个标题也必须至少有一个其他 non-related 关键字。如果我使用第二个例子, 我只能创建一个 SIMILAR 关系吗?)
我的第二个问题与我的最终目标有关。 Q:如果我正确理解查询,只有最相似的结果才会在数据库中存储SIMILAR关系;我可以在函数内使用相同的查询吗?目前我的函数看起来像这样:
def get_similar_keywords(self):
'''
MATCH (search_query:Title)
-[:HAS_KEYWORDS]->(k_id:Keyword)
<-[:HAS_KEYWORDS]-(return_query:Title)
-[r2:HAS_KEYWORDS]->(rec_k:Keyword)
WITH {item:id(return_query), categories: collect(id(rec_k))} as userData
WITH collect(userData) as data
CALL algo.similarity.jaccard(data, {topK: 1, similarityCutoff: 0.0, 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
'''
return graph.run(query, username=self.username)
现在,我的目标是找出: 1. MATCH 条件背后的想法是否错误; 2. 如何使用写入关系类型创建 SIMILAR 关系以及 3. 找出是否可以重用这些查询。
目前,在使用变量之后。我认为我的 Jaccard 相似度值看起来正确:
╒═══════╤═════════════════╤═══════╤═══════════════════════╤═══════════════╤═>══════════════════╤══════════════════╤══════════════════╤══════════════════╕ │"nodes"│"similarityPairs"│"write"│"writeRelationshipType"│"writeProperty"│">min" │"max" │"mean" │"p95" │ ╞═══════╪═════════════════╪═══════╪═══════════════════════╪═══════════════╪═>══════════════════╪══════════════════╪══════════════════╪══════════════════╡ │7 │5 │false │"SIMILAR" │"score" >│0.01162785291671753│0.5844191908836365│0.2831512808799744│0.584419190883636>5│ └───────┴─────────────────┴───────┴───────────────────────┴───────────────┴─>──────────────────┴──────────────────┴──────────────────┴──────────────────┘
I just don't quite get why it shows it has "SIMILAR" but nothing shows up on the graph...
如果我在正确的轨道上,我想复制这段代码:
MATCH (p:Person {name: "Praveena"})-[:SIMILAR]->(other),
(other)-[:LIKES]->(cuisine)
WHERE not((p)-[:LIKES]->(cuisine))
RETURN cuisine.name AS cuisine
...和return通过py2neo推荐的关键字。
非常感谢,
埃里克
如果要写回 SIMILAR 关系,则必须使用 similarityCutoff: 0.1
或更高。查看 source code 以了解更多信息。
此外,您的 MATCH
查询有点偏差,因此回写查询应如下所示:
MATCH (search_query:Title)-[:HAS_KEYWORDS]->(k_id:Keyword)
WITH {item:id(search_query), categories: collect(id(k_id))} as userData
WITH collect(userData) as data
CALL algo.similarity.jaccard(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
您输入标题的 ID 作为 item
,将描述标题的所有关键字的 ID 作为类别输入,让算法处理其余部分。
现在您已经存储了关系,您可以执行推荐查询。
MATCH (p:Title {name: "T1"})-[:SIMILAR]->(other),
(other)-[:HAS_KEYWORDS]->(keyword)
WHERE not((p)-[:HAS_KEYWORDS]->(keyword))
RETURN keyword.name AS keywords