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