如何使用SPARQL计算余弦相似度(cosine similarity)
使用SPARQL计算RDF向量的余弦相似度
要计算RDF中两个向量的余弦相似度,核心是实现余弦相似度公式:
余弦相似度 = (向量A·向量B) / (||向量A|| × ||向量B||)
其中:
- 向量点积(A·B):对应维度数值相乘后求和
- 向量模长(||A||):各维度数值平方和的平方根
针对你提供的RDF数据结构(用rdf:_1到rdf:_1536表示向量维度),可以用以下SPARQL查询实现:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> SELECT ?labelA ?labelB ( ?dotProduct / (?magnitudeA * ?magnitudeB) AS ?cosineSimilarity ) WHERE { # 定义两个目标资源 BIND(<http://example.org/london> AS ?vecA) BIND(<http://example.org/united-kingdom> AS ?vecB) # 获取资源标签 ?vecA rdfs:label ?labelA . ?vecB rdfs:label ?labelB . # 计算点积:对应维度数值相乘后求和 { SELECT ?vecA ?vecB (SUM(?valA * ?valB) AS ?dotProduct) WHERE { ?vecA ?dim ?valA . ?vecB ?dim ?valB . # 过滤出rdf:_开头的维度属性 FILTER(STRSTARTS(STR(?dim), STR(rdf:_))) } GROUP BY ?vecA ?vecB } # 计算向量A的模长:平方和的平方根 { SELECT ?vecA (SQRT(SUM(?valA * ?valA)) AS ?magnitudeA) WHERE { ?vecA ?dim ?valA . FILTER(STRSTARTS(STR(?dim), STR(rdf:_))) } GROUP BY ?vecA } # 计算向量B的模长:平方和的平方根 { SELECT ?vecB (SQRT(SUM(?valB * ?valB)) AS ?magnitudeB) WHERE { ?vecB ?dim ?valB . FILTER(STRSTARTS(STR(?dim), STR(rdf:_))) } GROUP BY ?vecB } }
说明:
- 修改
BIND语句中的资源URI,可以计算任意两个向量的相似度 FILTER(STRSTARTS(STR(?dim), STR(rdf:_)))确保只匹配向量维度属性,避免混入其他属性(如rdfs:label)- 若你的SPARQL引擎支持更高效的数学函数优化,可以根据引擎特性调整查询逻辑
内容的提问来源于stack exchange,提问作者Martynas Jusevičius
相关产品推荐
相关产品推荐

