OpenSearch中余弦相似度分数异常,请求原因分析
OpenSearch向量相似度分数不符合预期的原因解析
问题核心原因
你看到的0.33333334分数,是OpenSearch搭配nmslib引擎的cosinesimil空间时,分数计算逻辑和你预期的规则不一致导致的,具体拆解如下:
基础余弦值验证
你的两个向量[0,1]和[0,-1]的余弦相似度确实是-1,这点你之前的验证是对的。nmslib的cosine距离定义
nmslib引擎将cosinesimil空间的距离定义为:distance = 1 - cosine_similarity代入你的向量,距离为
1 - (-1) = 2。OpenSearch的分数转换逻辑
OpenSearch为了将距离值转换为0~1之间的相似度分数(值越大越相似),对nmslib返回的距离采用了以下公式:score = 1 / (1 + distance)代入距离
2,得到1/(1+2) = 1/3 ≈ 0.33333334,和你查询到的结果完全匹配。而你预期的
0分,是基于“将余弦值-1直接映射为0”的逻辑,但这并不是nmslib引擎下的转换规则。
解决方案
如果想要得到你预期的分数(即余弦值映射到0~1区间,-1对应0,1对应1),可以选择两种方式:
更换为faiss引擎
修改索引映射的引擎为faiss,faiss的cosinesimil空间分数计算规则是(1 + cosine_similarity)/2,完全符合你的预期。修改后的映射定义如下:PUT /my-index2 { "settings": { "index": { "knn": true } }, "mappings": { "properties": { "content": { "type": "text" }, "content_vector": { "type": "knn_vector", "dimension": 2, "method": { "name": "hnsw", "space_type": "cosinesimil", "engine": "faiss", "parameters": { "ef_construction": 500, "m": 16 } } } } } }应用层手动转换分数
保持现有索引不变,在查询结果后自行转换分数。根据现有分数反推预期值的公式:expected_score = (3 - 1/score) / 2代入你得到的
0.33333334,计算得(3 - 3)/2 = 0;代入相同向量的0.9999999,计算得约1,完全符合预期。
内容的提问来源于stack exchange,提问作者Giedrius
相关产品推荐
相关产品推荐

