美文网首页
ES 向量检索 dense_vector 类型

ES 向量检索 dense_vector 类型

作者: caster | 来源:发表于2021-09-06 17:26 被阅读0次

ES 7.X 版本引入了向量类型dense_vector,用于存储浮点类型的密集向量,其最大维度为2048。其用作是可以将待查询向量和文档内存储向量之间的距离作为查询评分使用,即越相似的向量评分越高。使用方式为在 query 的script_score中指定向量的计算方式,具体有四种:

cosineSimilarity – 余弦函数
dotProduct – 向量点积
l1norm – 曼哈顿距离
l2norm - 欧几里得距离

  1. 创建含有dense_vector的索引用于测试,建表如下:
PUT caster_vector
{
  "settings": {
    "number_of_replicas": 0
  },
  "mappings": {
    "properties": {
      "my_vector": {
        "type": "dense_vector",
        "dims": 2
      },
      "my_text": {
        "type": "keyword"
      }
    }
  }
}
  1. 插入测试数据:
POST caster_vector/_doc
{
  "my_text" : "text1",
  "my_vector" : [1, 1]//[1, -1],[1, 0],[0, 1],[0, -1],[-1, 1],[-1, 0],[-1, -1]
}

注:不要插入 [0,0] 向量,查询时会由于无法计算而报错。

  1. 采用cos方式计算,运行查询语句,查询的向量为 [1,1]:
GET caster_vector/_search
{
  "query": {
    "script_score": {
      "query": {
        "match_all": {}
      },
      "script": {
        "source": "cosineSimilarity(params.query_vector, 'my_vector') + 1.0",//加1规避分数为负数
        "params": {
          "query_vector": [
            1,
            1
          ]
        }
      }
    }
  }
}

(注:因为向量函数cosineSimilarity会线性扫描全部匹配文档,线上尽量使用query过滤出较少的文档进行计算以节约时间。)
结果分数如下:

{
  "took" : 6,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 8,
      "relation" : "eq"
    },
    "max_score" : 2.0,
    "hits" : [
      {
        "_index" : "caster_vector",
        "_type" : "_doc",
        "_id" : "57DwuXsBSCW7lcY4Ic7I",
        "_score" : 2.0,
        "_source" : {
          "my_text" : "text1",
          "my_vector" : [
            1,
            1
          ]
        }
      },
......
      {
        "_index" : "caster_vector",
        "_type" : "_doc",
        "_id" : "L7DwuXsBSCW7lcY4adYc",
        "_score" : 0.29289323,
        "_source" : {
          "my_text" : "text1",
          "my_vector" : [
            -1,
            0
          ]
        }

查询向量 [1,1] 和文档内向量 [1,1] 夹角为0°,cos值为1,结果为1+1=2。
查询向量 [1,1] 和文档内向量 [-1,0] 夹角为135°,cos值为-0.707x,结果为-0.707x+1=0.292x。
......

  1. 采用向量点积方式计算,运行查询语句,查询的向量为 [1,1]:
GET caster_vector/_search
{
  "query": {
    "script_score": {
      "query": {
        "match_all": {}
      },
      "script": {
        "source": """
          double value = dotProduct(params.query_vector, 'my_vector');
//          return value+2.0;
          return sigmoid(1, Math.E, -value); 
        """,
        "params": {
          "query_vector": [
            1,
            1
          ]
        }
      }
    }
  }
}

这里使用了sigmoid函数对点积结果进行了0~1之间的平滑映射,规避负值。与直接点积效果(针对当前情况采取加2转正方式)对比如下:

向量 点积 sigmoid
[1,1] 2+2=4 0.8807971
[1,0] 1+2=3 0.7310586
[1,-1] 0+2=2 0.5
[0,-1] -1+2=1 0.26894143
[-1,-1] -2+2=0 0.11920292

可以看出经过sigmoid函数评分映射为0~1之间且效果与直接点积近似。

  1. 采用曼哈顿距离方式计算,运行查询语句,查询的向量为 [1,1]:
GET caster_vector/_search
{
  "query": {
    "script_score": {
      "query": {
        "match_all": {}
      },
      "script": {
        "source": "1 / (1 + l1norm(params.queryVector, 'my_vector'))",
        "params": {
          "queryVector": [
            1,
            1
          ]
        }
      }
    }
  }
}

曼哈顿距离计算二维向量方式为:|x1-x2|+ |y1-y2|,计算结果越小越相关。ES 采取加一取倒数方式表示得分情况。计算结果对比如下:

向量 曼哈顿距离 加一取倒数
[1,1] 0 1
[1,0] 1 0.5
[1,-1] 2 0.33333334
[0,-1] 3 0.25
[-1,-1] 4 0.2
  1. 采用欧几里得距离方式计算,运行查询语句,查询的向量为 [1,1]:
GET caster_vector/_search
{
  "query": {
    "script_score": {
      "query": {
        "match_all": {}
      },
      "script": {
        "source": "1 / (1 + l2norm(params.queryVector, 'my_vector'))",
        "params": {
          "queryVector": [
            1,
            1
          ]
        }
      }
    }
  }
}

欧几里得距离计算二维向量方式为:\sqrt{(x1-y1)^2+(x2-y2)^2} ,计算结果越小越相关。ES 采取加一取倒数方式表示得分情况。计算结果对比如下:

向量 欧几里得距离 加一取倒数
[1,1] 0 1
[1,0] 1 0.5
[1,-1] 2 0.33333334
[0,-1] \sqrt{5} 0.309017
[-1,-1] 2*\sqrt{2} 0.26120389
  1. 你也可以通过doc[<field>].vectorValuedoc[<field>].magnitude获取向量数组和向量大小进行自己的计算方法。

相关文章

  • ES 向量检索 dense_vector 类型

    ES 7.X 版本引入了向量类型dense_vector,用于存储浮点类型的密集向量,其最大维度为2048。其用作...

  • 向量检索

    最近的工作开始偏向于底层向量检索算法的开发上面,但是对我而言有壁垒需要突破。 从新造轮子效率太低,一个是C++基本...

  • ES8.0新增KNN向量近邻检索

    向量检索将加速深度学习的落地与应用,向量检索的应用场景如下图所示,它几乎覆盖了大部分的可以应用AI的业务场景 这里...

  • Elasticsearch 字段类型

    在学习 ES 文档相关操作之前,我们先学习 ES 中常用的字段类型。 1、text 当一个字段的内容需要被全文检索...

  • 向量检索排序

    2020-07-20 如何计算特征距离 欧式距离: 两点间的真实距离,值越小,说明距离越近; 余弦距离:就是两个向...

  • 实现TopK问题的三种算法

    在检索类的应用中往往实现TopK的应用,比如特征检索场景下,要对一个向量进行距离查询,输出距离最近的前10个向量。...

  • 1106 chapter15 向量

    向量基础 向量类型 原子向量:逻辑型、整型、双精度型、字符型、复数型、原始型 列表 向量属性 类型 typeof(...

  • Elastic检索技巧总结

    常用的检索类型 在mysql中,我们常用的查询 可能就是 精准查询 模糊查询 范围查询 等等,那么在es中,有哪...

  • R语言初级教程(09): 向量(上篇)

    向量(vector)是R语言最基本的数据类型。向量中的元素必须为同一属性,常见的向量类型有数值型向量、字符型向量和...

  • 2018-04-10

    /** *该篇文章主要介绍如何学习ES,如何入门,ES简单的检索方式等(ES版本2.4.1) **/ public...

网友评论

      本文标题:ES 向量检索 dense_vector 类型

      本文链接:https://www.haomeiwen.com/subject/cigewltx.html