使用Solr 9.4的密集矢量搜索-knn搜索返回的点积和余弦值不正确

nx7onnlm  于 5个月前  发布在  Solr
关注(0)|答案(1)|浏览(97)

我正在使用Solr 9.4进行密集矢量搜索,但是knn搜索返回了奇怪的点积值。
下面是一个基本的例子:
1.将向量[0.57735027,0.57735027,0.57735027]存储在集合中
1.使用查询向量[0.26726124, 0.53452248, 0.80178373]执行knn查询
点积应为0.92582,但返回的分数为0.96291006
最奇怪的是,当我使用一个流表达式dotProduct(array(0.57735027,0.57735027,0.57735027),array(0.26726124,0.53452248,0.80178373))时,Solr返回正确的值:0.92582

任何想法为什么有这样的差异,我如何才能获得正确的点产品从knn搜索?

复制步骤

启动本地Solr

下面是我的docker-compose.yaml文件:

version: '3'
services:
  solr:
    image: solr:9.4
    ports:
     - "8983:8983"
    volumes:
      - 'solr_data:/var/solr'
    command:
      - solr-precreate
      - documents
volumes:
  solr_data:
    driver: local

字符串

向集合中添加vector

我添加一个向量[0.57735026, 0.57735026, 0.57735026](单位向量)。

# Create a 3D vector type 
curl  -X POST \
  'http://localhost:8983/api/cores/documents/schema' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "add-field-type": {
    "name": "3D-vector",
    "class": "solr.DenseVectorField",
    "vectorDimension": "3",
    "vectorEncoding": "FLOAT32",
    "similarityFunction": "dot_product"
  }
}'

# Add a field "vector" in the collection
curl  -X POST \
  'http://localhost:8983/api/cores/documents/schema' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "add-field": [
    {
      "name": "vector",
      "type": "3D-vector"
    }
  ]
}'

# Add a single vector (normalized) into the collection "documents"
curl  -X POST \
  'http://localhost:8983/api/cores/documents/update?commit=true' \
  --header 'Content-Type: application/json' \
  --data-raw '[
  {
    "vector": [
      0.57735027,
      0.57735027,
      0.57735027
    ]
  }
]'

执行knn搜索

现在,我使用向量查询[0.26726124, 0.53452248, 0.80178373]执行knn搜索
对应的点积应该是0.92582(与余弦相似性相同,因为我使用了归一化向量)。
我添加了一个计算字段,它使用函数query vectorSimilarity来仔细检查点积的返回值:
回应:

{
  "responseHeader": {
    "status": 0,
    "QTime": 1,
    "params": {
      "json": "{\n  \"fields\": [\n    \"vector\",\n    \"score\",\n    \"vectorSimilarity(FLOAT32, DOT_PRODUCT, vector, [0.26726124, 0.53452248, 0.80178373])\"\n  ],\n  \"query\": \"{!knn f=vector topK=10}[0.26726124, 0.53452248, 0.80178373]\"\n}"
    }
  },
  "response": {
    "numFound": 1,
    "start": 0,
    "maxScore": 0.96291006,
    "numFoundExact": true,
    "docs": [
      {
        "vector": [
          0.57735026,
          0.57735026,
          0.57735026
        ],
        "score": 0.96291006,
        "vectorSimilarity(FLOAT32, DOT_PRODUCT, vector, [0.26726124, 0.53452248, 0.80178373])": 0.96291006
      }
    ]
  }
}


正如我们所看到的,点积的返回值是0.96291006,这与0.92582有很大的不同。
最奇怪的是,如果我使用带有表达式dotProduct(array(0.57735027,0.57735027,0.57735027),array(0.26726124,0.53452248,0.80178373))的流式表达式端点,Solr会计算正确的点积:

curl  -X GET \
  'http://localhost:8983/solr/documents/stream?expr=dotProduct(array(0.57735027%2C0.57735027%2C0.57735027)%2Carray(0.26726124%2C0.53452248%2C0.80178373))' \
  --header 'Content-Type: application/json


回应:

{
  "result-set": {
    "docs": [
      {
        "return-value": 0.9258201002207116
      },
      {
        "EOF": true,
        "RESPONSE_TIME": 15
      }
    ]
  }
}

9vw9lbht

9vw9lbht1#

我终于明白为什么分数似乎不正确感谢this issue
看起来Solr正在计算归一化余弦相似度:(1 + cosine_sim) / 2,这解释了为什么我计算的值和knn搜索返回的值之间存在差距。
为了得到余弦相似度,可以应用公式:2 * normalized_cosine_sim - 1
对于我在问题中给出的答案:2 * 0.96291006 - 1给出0.92582

相关问题