代码之家  ›  专栏  ›  技术社区  ›  user16971617

[余弦]相似性不支持弹性搜索中幅度为零的向量

  •  0
  • user16971617  · 技术社区  · 1 年前

    我试图用我的假数据集向Elastic Search执行数据摄取。我的假数据集包含很多0向量(0,0,…,),并得到了关于摄取零向量的错误。

    {'errors': True, 'took': 64, 'items': [{'create': {'_index': 'bdp-cus-feature-store-1.1-vector-p1', '_id': '5aeefc2e656b6f77c60af0d90f1280b52e298441d29a80c69321155aa9700438', 'status': 400, 'error': {'type': 'document_parsing_exception', 'reason': '[1:3931] failed to parse: The [cosine] similarity does not support vectors with zero magnitude. Preview of invalid vector: [0.0, 0.0, 0.0, 0.0, 0.0, ...]', 'caused_by': {'type': 'illegal_argument_exception', 'reason': 'The [cosine] similarity does not support vectors with zero magnitude. Preview of invalid vector: [0.0, 0.0, 0.0, 0.0, 0.0, ...]'}}}}
    

    我认为弹性搜索只是一个数据库,我很困惑什么是不允许摄入0矢量。我试图寻找解决方案并在网上搜索,但找不到任何关于它的帖子或如何解决它。有人知道吗?非常感谢。

    1 回复  |  直到 1 年前
        1
  •  1
  •   imotov    1 年前

    Elasticsearch不仅仅是一个数据库;除其他功能外,它还是一个矢量数据库。当索引密集向量时,Elasticsearch会维护一种特殊的数据结构,称为分层导航小世界(HNSW)图。这种结构能够在搜索期间实现快速近似k近邻(kNN)查找。

    该图中矢量的排列是基于矢量之间的相似性。默认情况下,Elasticsearch为此使用余弦相似性。如本文所述 https://stackoverflow.com/a/26703445/783043 ,余弦相似性对零向量没有多大意义,导致Elasticsearch提出了关于它们的错误。

    这个问题的解决方案是切换到不同的相似性度量,或者如果您不打算搜索字段,则避免对其进行索引。

    解决方案1:

    DELETE test
    
    PUT test
    {
      "mappings": {
        "properties": {
          "vector": {
            "type": "dense_vector",
            "dims": 3,
            "similarity": "l2_norm"
          }
        }
      }
    }
    
    POST test/_bulk?refresh=true
    { "index": { "_id": "1" } }
    { "vector": [1, 5, -20]}
    { "index": { "_id": "2" } }
    { "vector": [0, 0, 0]}
    

    解决方案2:

    DELETE test
    
    PUT test
    {
      "mappings": {
        "properties": {
          "vector": {
            "type": "dense_vector",
            "dims": 3,
            "index": false
          }
        }
      }
    }
    
    POST test/_bulk?refresh=true
    { "index": { "_id": "1" } }
    { "vector": [1, 5, -20]}
    { "index": { "_id": "2" } }
    { "vector": [0, 0, 0]}