sparql - 在SPARQL中计算余弦相似度

标签 sparql embedding cosine-similarity

我正在寻找一种计算 cosine similarity 的方法使用 SPARQL。

向量在 RDF 数据中的描述如下:

@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<http://example.org/london> rdfs:label "London" ;
    rdf:_1 0.011788688 ;
    rdf:_2 0.006153286 ;
    rdf:_3 -0.0034582422 ;
    ...
    rdf:_1536 -0.020006698 .

<http://example.org/united-kingdom> rdfs:label "United Kingdom" ;
    rdf:_1 0.007484864 ;
    rdf:_2 -0.022806747 ;
    rdf:_3 -0.010839927 ;
    ...
    rdf:_1536 0.001866414 .

<http://example.org/united-states> rdfs:label "United States of America" ;
    rdf:_1 0.0070878486 ;
    rdf:_2 -0.02133514 ;
    rdf:_3 -0.000050822895 ;
    ...
    rdf:_1536 -0.012027864 .

最佳答案

我的查询如下所示:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX afn: <http://jena.apache.org/ARQ/function#>

SELECT ?embed1 ?embed2 ((SUM(?dot) / (afn:sqrt(SUM(?v1_squared)) * afn:sqrt(SUM(?v2_squared)))) AS ?similarity)
WHERE {
  ?embed1 ?p ?v1 .
  ?embed2 ?p ?v2 .
  FILTER (STRSTARTS(STR(?p), str(rdf:_)))

  BIND((?v1 * ?v1) AS ?v1_squared)
  BIND((?v2 * ?v2) AS ?v2_squared)
  BIND (?v1 * ?v2 AS ?dot) 

}
GROUP BY ?embed1 ?embed2
ORDER BY DESC(?similarity)

它需要 Jena's ARQ library 中的 afn:sqrt 函数因为标准 SPARQL 1.1 不提供 sqrt 函数。

它似乎有效,但在大数据上可能表现不佳:

----------------------------------------------------------------------------------------------------
| embed1                              | embed2                              | similarity           |
====================================================================================================
| <http://example.org/united-kingdom> | <http://example.org/united-kingdom> | 1.0000000000000002e0 |
| <http://example.org/london>         | <http://example.org/london>         | 1.0e0                |
| <http://example.org/united-states>  | <http://example.org/united-states>  | 1.0e0                |
| <http://example.org/united-states>  | <http://example.org/united-kingdom> | 0.8804311835944831e0 |
| <http://example.org/united-kingdom> | <http://example.org/united-states>  | 0.8804311835944831e0 |
| <http://example.org/london>         | <http://example.org/united-kingdom> | 0.8510995877458968e0 |
| <http://example.org/united-kingdom> | <http://example.org/london>         | 0.8510995877458968e0 |
| <http://example.org/london>         | <http://example.org/united-states>  | 0.7855264600385297e0 |
| <http://example.org/united-states>  | <http://example.org/london>         | 0.7855264600385297e0 |
----------------------------------------------------------------------------------------------------

关于sparql - 在SPARQL中计算余弦相似度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76610470/

相关文章:

graph - 尝试提交事务时,Jena 的 TDB 数据集出现 TDBTransactionException

rdf - 查询 dbpedia 以查找可能的上下文来消除单词的歧义

python - 随机生成相似的向量?

nlp - 如何根据预定义的语言类别衡量文档的不同程度?

r - 如何使用R通过余弦相似度有效地检索前K个相似向量?

rdf - 有没有办法将RDF词汇表的数据格式转换为SKOS

java - Virtuoso Jena Provider 构造查询错误

python - 在网页中嵌入 Python shell

python - 如何将 SWF 内容加载到 Linux 上的 Python 应用程序中?

javascript - JW播放器 : Black screen before seek in Firefox