Elasticsearch:探索 Elastic 向量数据库

news2024/10/5 23:24:14

作者:来着 Elastic Justin Castilla

向量数据库正迅速成为语义搜索的事实上的数据存储,语义搜索是一种考虑上下文和内容含义的搜索,而不是传统的关键字搜索。Elastic 一直提供执行语义搜索的现代工具,识别和理解查询向量数据库所需的大的机制非常重要。

本文将介绍在 Elasticsearch 中操作向量数据库所需的组件。我们将探索底层技术,以创建一个高效的系统,确保最佳的性能和速度平衡。涵盖的主题包括:

  • 当前的 Elastic 全文搜索(BM25 和 TF/IDF)
  • 向量、嵌入和必要的考虑因素
  • 选择嵌入模型
  • 索引向量
  • 向量查询算法

运行代码

要创建本文中所示的自己的向量数据库,你需要一个

  • 针对机器学习优化的 Elasticsearch 实例(8.13 或更高版本)
  • Docker Desktop 或类似的 Docker 容器管理器
  • Python 3.8(或更高版本)
  • Elasticsearch Python 客户端

此处提供了相关的存储库,用于说明查询向量数据库所需的各种移动部件。我们将从此来源观察整篇文章中的代码片段。示例存储库将创建一个索引,其中包含 JSON 文件中提供的大约 10,000 个对象,这些对象代表在 goodreads.com 上评论的科幻书籍。每个对象都将有一个描述该书的文本的向量嵌入。本文和存储库的目标是演示基于提供的查询字符串和嵌入的书籍描述向量之间的向量相似性来搜索书籍。

这是一个我们将在代码示例中使用的示例书籍对象。

sample_book = {
  "author_name": "Kate L. Mary",
  "description_embedding":[
      -0.24338197708129883,
      0.08498962223529816,
      ...
  ],
  "model_id": "sentence-transformers__msmarco-minilm-l-12-v3"
  },
  "book_title": "Shattered World",
  "genres": ["Horror (Zombies)", "Apocalyptic (Post Apocalyptic)", "Science Fiction",
    "Adventure (Survival)", "Fantasy"
  ],
  "rating_votes": 1667,
  "book_description": "Stranded in the middle of the Mojave Desert, surrounded by zombies, Vivian and Axl’s group are sure they’re facing the end...",
  "review_number": 146,
  "rating_score": 4.16,
  "url": "https://www.goodreads.com/book/show/22693753-shattered-world",
  "year_published": 2014
}

当前的 Elastic 全文搜索 (BM25 和 TF/IDF)

为了了解向量数据库相对于传统全文搜索数据库的范围和优势,值得花点时间回顾一下当前支持 Elasticsearch、BM25 及其前身 TF/IDF 的底层技术。

TF/IDF

TF/IDF 是查询词频率和重要性的统计度量,基于它在单个文档中出现的频率以及它在整个文档索引中的出现率。

  • 词频 (term frequency - TF):这是衡量词在文档中出现频率的指标。文档中词出现的次数越高,文档与原始查询相关的可能性就越高。这是根据词出现的次数除以文档中词的总数量得出的原始计数或归一化计数
  • 逆文档频率 (inverse document frequency - IDF):这是根据索引中所有文档的总体使用频率衡量查询词的重要性的指标。出现在更多文档中的词被认为不太重要且信息量较少,因此在评分中权重较低。这是通过对包含查询词的文档总数除以对数计算得出的。

  • nₜ = 包含该术语的文档数量
  • N = 文档总数

以科幻小说为例,让我们分解几个句子,重点关注 “space” 和 “whales” 这两个词。

  1. "The interstellar whales graceully swam through the cosmos onto their next adventure."
  2. "The space pirates encountered a human space station on their trip to Venus, ripe for plunder"
  3. "In space no one can year you scream."
  4. "Space is the place to be."
  5. "Purrgil were a semi-sentient species of massive whales that lived in deep space, traveling from star system to star system."

Space

  • 术语 “space” 出现在 4 篇文档中(句子 2、3、4 和 5)。
  • 文档总数 (N) = 5。

“Space” 的 IDF 公式:

“space” 被认为不太重要,因为它在 5 个句子中的 4 个中频繁出现。

Whales

  • 术语 “whales” 出现在 2 篇文档中(句子 1 和句子 5)。
  • 文档总数 (N) = 5。

“whales”的 IDF 公式:

“Whales” 被认为相对重要,因为它只出现在 5 个句子中的 2 个中。

“Whales” 被分配了更高的 IDF 值,因为它出现在较少的文档中,使其更具特色并且与这些文档的上下文相关。相反,“space” 在文档中更常见,导致 IDF 分数较低,从而表明它对于区分文档的作用较小。在我们的代码库的 10,000 个图书对象的上下文中,“space” 一词出现了 1,319 次,而 “whale” 一词总共出现了 6 次。可以理解的是,搜索 “space whales” 会首先将 “whales” 的出现优先于 “space”。

虽然 TF/IDF 本身仍被认为是一种强大的搜索算法,但它无法防止对较长文档的搜索偏差,这些文档与较小的文档相比,可能具有成比例的较大术语出现量。

BM25

BM25(Best Match 25)是一种增强的排名函数,它使用 IDF 组件来创建一个分数,概述索引中某个文档相对于其他文档的相关性。

  • 词频饱和度Term Frequency Saturation):据指出,在某个点上,文档中查询词的出现频率高并不会显著提高其与其他具有同样高计数的文档相比的相关性。BM25 引入了词频饱和度参数,随着计数的增加,词频的影响会以对数方式降低。这可以防止词频出现频率高的超大文档不成比例地影响相关性分数,确保所有分数在某个点之后趋于平稳。

  • 增强的逆文档频率 (Enhanced Inverse Document Frequency - IDF):如果查询词出现在所有文档中或出现频率非常低,IDF 分数可能会变为零。为了避免这种情况,BM25 在计算中添加了一个 0.5 的值,确保 IDF 分数不会达到零或变得太低。

  • 平均文档长度Average Document Length):这是对文档实际长度的考虑。众所周知,较长的文档自然会比较短的文档出现更多术语,但这并不一定意味着它们更相关。此调整可补偿文档长度,以避免仅由于较长文档的术语频率较高而偏向较长的文档。

BM25 是一种出色的工具,可高效搜索和检索与文本完全匹配的内容。自 2016 年以来,它一直是 Lucene(6.0 版及更高版本)的默认搜索算法,Lucene 是 Elasticsearch 使用的底层低级搜索引擎。应该注意的是,BM25 不能像向量一样提供语义搜索,语义搜索提供对查询上下文的理解,而不是纯粹的关键字搜索。还应该注意的是,词汇不匹配可能会导致无法获得正确的结果。例如,如果单词不完全匹配,例如包含术语 “space” 的文档,则用户提交的使用术语 “cosmos” 的查询可能无法检索到预期的结果。众所周知,“cosmos” 是“space”的另一种说法,但默认的 BM25f 算法并未明确告知或检查这一点。知道何时选择传统关键字搜索而不是语义搜索对于确保高效利用计算资源至关重要。

运行代码:全文搜索(BM25)

def full_text_search(query_string):
    search_result = es.search(
        index = INDEX_NAME, 
        body = {"query": 
          {"match": 
            {"book_description": query_string}
          }
        }
    )

    return search_result

进一步阅读:

  • BM25 算法及其变量
  • BM25:现代信息检索指南
  • BM25 下一代 Lucene 相关性

向量 - vectors

向量数据库本质上存储和索引文档的数学表示(向量),以进行相似性搜索。数据向量化可以将复杂且细微的文档(文本、图像、音频、视频等)标准化为计算机可以与其他向量进行比较的格式,从而获得一致的相似性结果。了解现有的多种机制对于提供可用于生产的解决方案非常重要。

什么是向量?

向量是数据信息的一种表示形式,以数字数组的形式投射到数学领域。使用数字代替单词,计算机的比较非常高效,因此可以大大提高性能。几乎所有可以想象到的用于计算的数据类型(文本、图像、音频、视频等)都可以转换为向量表示。

图像被分解为像素,视觉模式如纹理、渐变、角落和透明度等被捕捉为数值表示。单词、特定短语中的词语以及整个句子也会被分析,分配不同的情感、上下文和同义词值,并转换为浮点数组。在这些多维矩阵中,系统能够在向量的某些部分中识别出数值相似性,从而在电商网站中找到颜色相似的库存,回答 Elastic.co 上的编程问题,或识别诺贝尔奖得主的声音。

每种数据类型都受益于专用的向量嵌入模型,该模型可以最好地识别和存储该特定类型的各种特征。文本嵌入模型擅长理解常用短语和细微的头韵,但完全无法识别图像中摆姿势的人物所表现出的情绪。

上面我们可以看到嵌入模型接收三个不同的字符串作为输入并产生三个不同的向量(浮点数组)作为输出。

嵌入模型

在转换数据向量(在本例中为文本)时,将使用模型。应该注意的是,模型嵌入模型是一个预先训练的机器学习实例,它将文本(单词、短语和句子)转换为数字表示。这些表示成为浮点数的多维数组,每个维度代表原始文本的不同特征,例如情感、上下文和句法。这些不同的表示允许与其他向量进行比较,以查找相似的文档和文本片段。

已经开发了不同的嵌入模型,它们提供了各种好处;有些非常高效地利用硬件,并且可以用较少的计算能力运行。有些对它存储在索引中的上下文和内容有更大的“理解”,可以回答问题、执行文本摘要并引导线程对话。有些专注于在性能、速度和效率之间取得可接受的平衡。

选择嵌入模型

我们将简要介绍三种文本嵌入模型及其各种属性。

Word2Vec:该模型高效且易于训练,可根据单词的上下文和语义含义为其提供高质量的嵌入。Word2VEc 最适合用于具有语义相似性需求、情感分析或计算资源有限的应用程序。

GloVe:GloVe 在许多方面与 Word2Vec 相似,它在整个索引中建立了全局意识。通过分析整个文本中的单词共现,GloVe 可以捕获单词的频率和上下文,从而生成反映单词在存储的向量总体中的整体关系和含义的嵌入。

BERT:与 Word2Vec 和 GloVe 不同,BERT(来自 Transformers 的双向编码器表示)查看每个单词前后的文本,以建立局部上下文和语义含义。通过对大量文本进行预训练,该模型能够出色地完成问答任务以及情感分析。

运行代码:创建用于嵌入向量的摄取管道

对于编码示例,选择了较小、较简单的 BERT 版本,称为 sentence-transformers__msmarco-minilm-l-12-v3。它被认为是 MiniLM,比正常大小的模型更高效,但仍保留了向量相似性所需的性能。对于非生产教程来说,这是一个很好的模型选择,可以快速运行代码而无需进行微调。有关该模型的更多信息可在此处获得

下面我们正在为索引 books 创建一个摄取管道。这意味着在 Elasticsearch 索引中创建和存储的所有书籍对象都将自动将其 book_description 字段转换为名为 description_embedding 的向量嵌入。这减少了在客户端创建新书籍对象所需的代码库。

如果发生故障,文档将存储在 failure-books 索引中,并且错误消息将包含在文档中。这使你可以查看可能导致嵌入失败的任何错误,并能够使用更新的代码重新索引失败的索引,确保没有丢失或遗留任何文档。

注意:由于嵌入向量的工作负载通过此推理采集管道传递给 Elastic,因此应注意,此 Elasticsearch 云实例中可能需要更大级别的可用 CPU 和 RAM,以便快速嵌入和索引新文档和更新的文档。如果嵌入的工作负载留给本地应用程序代码库,还应考虑在高吞吐量期间所需的计算硬件。本文提供的代码库包括一个选项,可在本地嵌入 book_description,以便进行比较和计算压力。

es.ingest.put_pipeline(
    id="text-embedding",
    description="converts book description text to a vector",
    processors=[
        {
            "inference": {
                "model_id": 
                  "sentence-transformers__msmarco-minilm-l-12-v3",
                "input_output": [
                    {
                        "input_field": "book_description",
                        "output_field": "description_embedding",
                    }
                ],
            }
        }
    ],
    on_failure=[
        {
            "set": {
                "description": "Index document to 'failed-<index>'",
                "field": "_index",
                "value": "failed-{{{_index}}}",
            }
        },
        {
            "set": {
                "description": "Set error message",
                "field": "ingest.failure",
                "value": "{{_ingest.on_failure_message}}",
            }
        },
    ],
)

此代码片段创建了一个名为 text-embedding 的采集管道,该管道创建了一个推理处理器。该处理器使用 sentence-transformers__msmarco-minilm-l-12-v3 模型将 book_description 文本复制并转换为向量嵌入,并将其存储在 description_embedding 属性下。

索引向量

索引向量的方法对搜索结果的性能和准确性有重大影响。索引向量需要将它们存储在专门的数据结构中,以确保高效的相似性搜索、快速的向量距离计算以及最终的向量检索结果。你决定如何存储向量应该基于你独特的数据需求。还应注意,Elasticsearch 使用术语索引作为作用于文档的动词,表示将文档添加到索引中。应小心谨慎,以免混淆两者。

索引文档有两种通用方法:KNN 和 ANN。在选择其中一种时,区分两者并权衡利弊非常重要。

KNN

给定 k=4,选择并返回四个与查询向量(黄色)最接近的向量。

KNN(K 最近邻)将根据提供的距离度量提供 K 个最近邻向量的精确结果。与大多数返回精确结果的方法一样,代价是速度,必须牺牲速度才能获得准确性。KNN 方法整理从目标点到向量维度中所有其他现有点的每个距离。然后对距离进行排序并返回最近的 K。在上图中,请求 k 为 4,并返回四个最近的向量。

ANN

ANN(近似最近邻)将基于已建立的向量索引提供最近邻的近似值,这些向量的维度已降低,以便于更轻松、更快速地处理。权衡是加速搜索阶段,其中遍历由索引辅助,索引可以被认为是所有向量的预定义映射。当速度、可扩展性和资源效率被认为比精确度更重要时,ANN 在语义搜索中比 KNN 更受欢迎。这使得 ANN 成为大规模和实时应用的实用选择,在这些应用中可以接受快速、近似匹配。与概率数据结构非常相似,为了速度和大小,可以接受对准确性的轻微影响。

例如,想象一下杂货店货架上存储的各种向量点,当你进入设施时,你会得到一张地图。预制地图可以让你找到想要去的地方,而不是从入口到出口穿过每个过道,直到最终到达你的目标点(KNN)。

HNSW

HNSW(Hierarchical Navigable Small World - 分层可导航小世界)是 Elastic 想量数据库的默认 ANN 方法。它利用基于图形的关系(节点和顶点)高效地遍历索引以查找最近的邻居。在这种情况下,节点是数据点,边是与附近邻居的连接。HNSW 由多层图形组成,这些图形之间的距离越来越近。

使用 HNSW,每次后续遍历到更高层都会暴露更近的节点或向量,直到找到所需的向量。

这类似于传统的 skip list 列表数据结构,其中较高层的元素彼此相距较远,或 “粗” 粒度,而较低层的元素彼此更近,或 “细” 粒度。从节点和顶点的较高平面到较低平面的遍历意味着并非所有向量都需要搜索和比较,只需搜索和比较最近的邻居。这确保可以快速有效地索引和搜索高维向量。

HNSW 非常适合用于实时语义搜索和推荐系统,这些系统具有高维向量,但可以接受近似结果而不是精确的最近邻居。对于较小的数据集、较低维向量,或者当内存大小限制是一个因素时,HNSW 可以被视为无关紧要的。由于图结构的复杂性,HNSW 可能不适合插入、更新和删除频率很高的高度动态数据存储。这是由于在所需的许多不同层中维护图连接的开销。与实现向量数据库的所有方面一样,必须在可用资源、延迟容忍度和所需性能之间取得平衡。

运行代码:创建索引

Elasticsearch 提供了一个 indices.create() 方法(记录在此处),该方法根据给定的索引名称和索引文档中预期数据类型的映射创建索引。这允许基于数值范围、全文和关键字搜索以及语义搜索更快、更高效地索引和检索文档。请注意,description_embedding 属性不包括在内 - 它将由上面定义的摄取管道在插入书籍对象时自动创建。

es.indices.create(index = 'books', body = {
    "properties": {
        "book_title": {"type": "text"},
        "author_name": {"type": "text"},
        "rating_score": {"type": "float"},
        "rating_votes": {"type": "integer"},
        "review_number": {"type": "integer"},
        "book_description": {"type": "text"},
        "genres": {"type": "keyword"},
        "year_published": {"type": "integer"},
        "url": {"type": "text"},
    }
})

Elasticsearch 提供了一种 indices.create() 方法,该方法根据给定的索引名称和索引文档中预期数据类型的映射来创建索引。这样可以基于数值范围、全文和关键字搜索以及语义搜索更快、更高效地索引和检索文档。请注意,description_embedding 属性不包括在内 - 该属性将由上面定义的摄取管道自动创建。

现在已经创建了索引 books,我们可以用书籍对象填充 Elasticsearch 以用于语义搜索。

让我们从在 Elasticsearch 中存储单个书籍对象开始。


sample_book = {
  "author_name": "Kate L. Mary",
  "book_title": "Shattered World",
  "genres": ["Horror (Zombies)", "Apocalyptic (Post Apocalyptic)", 
    "Science Fiction", "Adventure (Survival)", "Fantasy"
  ],
  "rating_votes": 1667,
  "book_description": "Stranded in the middle of the Mojave Desert, 
    surrounded by zombies, Vivian and Axl’s group are sure they’re 
    facing the end...",
  "review_number": 146,
  "rating_score": 4.16,
  "url": "https://www.goodreads.com/book/show/22693753-shattered-world",
  "year_published": 2014
}

es.index(
  index="books", 
  body=sample_book, 
  pipeline="text-embedding")

这里我们运行批量插入方法,这大大减少了索引我们起始图书馆 10,000 多本书所需的时间。索引大量对象时建议使用批量方法。更多信息可在此处找到。

from elasticsearch import helpers

file_path = "../data/books.json"

with open(file_path, "r") as file:
  books = json.load(file)

actions = [
  {"_index": "books", "_id": book.get("id", None), "_source": book}
  for book in books
]

helpers.bulk(es, actions, pipeline="text-embedding", chunk_size=1000)

请注意,在单次索引和批量索引方法中,我们都包含了 pipeline=’text-embedding’ 参数,以便每次添加新的书籍对象时,Elasticsearch 都会触发上面定义的推理处理器。

下面是已编入书籍向量数据库的示例书籍的后索引文档。现在有两个新字段:

  • model_id:用于创建向量的嵌入模型。
  • description_embedding:从我们的 book_description 字段创建的向量嵌入。由于空间有限,本文已将其截断,因为数组中总共有384个浮点值(我们选择的特定模型的维度)。
{
  "author_name": "Kate L. Mary",
  "book_title": "Shattered World",
  "genres": ["Horror (Zombies)", "Apocalyptic (Post Apocalyptic)", 
    "Science Fiction", "Adventure (Survival)", "Fantasy"
  ],
  "rating_votes": 1667,
  "book_description": "Stranded in the middle of the Mojave Desert, 
  surrounded by zombies, Vivian and Axl’s group are sure they’re 
  facing the end..",
  "review_number": 146,
  "rating_score": 4.16,
  "year_published": 2014,
  "url": "https://www.goodreads.com/book/show/22693753-shattered-world",
  "model_id": "sentence-transformers__msmarco-minilm-l-12-v3",
  "description_embedding": [
    -0.012079359032213688,
    0.18128874897956848,
    -0.10277046263217926,
    0.04724976792931557,
    -0.024640405550599098
  ]
}

向量搜索算法

有了充满嵌入向量的向量数据库,现在可以进行语义搜索和向量查询。每种索引方法和嵌入模型都擅长利用不同的算法来返回优化结果。

我们将介绍最常用的方法并讨论它们的具体应用。

余弦相似度:余弦相似度是 Elasticsearch 向量搜索的默认算法,它测量空间中两个向量之间角度的余弦。这种距离度量非常适合语义搜索和推荐系统。ANN 索引(例如 HNSW)经过优化,专门用于余弦相似度。角度越小,向量越相似,因此邻居越近。角度越大,它们的相关性越小,90°或垂直度完全不相关。任何超过 90°的值都被视为与给定向量所含内容 “相反”。

上面是三对显示不同方向的向量。这些方向说明了这些对可以相似、不相似或完全相反

余弦相似度的一个缺点是维数灾难。当向量对之间的距离开始达到其他向量对之间的平均值时,就会发生这种情况,因为向量所占的空间变得越来越大。特征或数据点越多,向量之间的距离就越远。这种情况发生在非常高维的向量中 —— 应该小心评估不同的距离指标以满足你的需求。

点积(Dot Product:):点积接收两个向量作为输入,并计算每个单独分量的乘积之和:

例如,如果向量 A 包含分量 [1,3,5] 且向量 B 包含分量 [4,9,1],则结果计算如下:

总和值越高,表示给定向量之间的相似性越强。如果该值为零或接近零,则向量彼此垂直,这使它们被视为不相关。负值表示向量彼此相反。

欧几里得 (Euclidean - L2):欧几里得距离可以想象为勾股定理 (a² + b² = c²) 的 n 维扩展,该定理用于查找直角三角形的斜边。对于向量 A 中的每个分量,我们确定其与向量 B 中对应分量的距离。这可以通过将一个分量的绝对值减去另一个分量的值来实现。然后,我们将差值平方并将其添加到下一个平方分量差中,直到确定两个向量中每个分量之间的每个距离,求平方并求和以创建一个最终值。然后,我们找到该值的平方根以达到两个向量 A 和 B 之间的欧几里得距离。

例如,我们有 2 个向量 A [3, 4, 5] 和 B [6, 7, 8]

我们的计算如下:

在两个向量 A 和 B 之间,距离约为 5.196。

欧几里得与余弦非常相似,受到维数灾难的影响,大多数向量距离在较高维度时变得均匀相似。因此,建议对低维向量使用欧几里得。

曼哈顿 (Manhattan - L1):曼哈顿距离与欧几里得距离类似,将两个对应向量分量的距离相加。曼哈顿不是以直线的形式找到两点之间的精确直线距离,而是可以认为是使用网格系统,就像纽约曼哈顿市的街区布局一样。

例如,如果一个人向北走 3 个街区,然后向东走 4 个街区到达目的地,那么你将总共行驶 7 个街区。这可以概括为:

在我们的编号示例中,我们可以将原点设为 [0,0],将目的地设为 [3,4]。因此,此计算适用:

与欧几里得和余弦不同,曼哈顿在高维向量中具有良好的扩展性,是特征丰富向量的绝佳候选者。

更改相似度算法

要在 Elasticsearch 中设置想量字段类型的特定相似度算法,请使用索引映射对象中的相似度字段。Elasticsearch 允许你将相似度定义为 dot_prodcut 或 l2_norm(欧几里得)。如果没有 similarity 字段定义,Elasticsearch 默认为 cosine。在这里,我们选择 l2_norm 作为 description_embedding 字段的相似度度量:

"mappings": {
    "properties": {
        "description_embedding": {
            "type": "dense_vector",
            "dims": 384,
            "index": True,
            "similarity": "dot_product"
        }
    }
}

综合起来

现在我们已经对如何创建向量以及比较向量相似度的方法有了基本的了解,我们需要了解事件序列以成功利用我们的向量数据库。

  1. 现在我们假设我们有一个充满表示数据的向量嵌入的数据库。所有向量都是使用同一模型创建的。
  2. 我们收到原始查询数据。
  3. 此查询数据文本使用我们之前使用的相同模型嵌入。这为我们提供了一个结果查询向量,它将具有与数据库中现有的向量相同的维度和特征。
  4. 我们在查询向量和向量索引之间运行相似度算法,以根据我们选择的距离度量和索引方法找到相似度最高的向量。
  5. 我们根据它们的相似度得分收到结果。返回的每个向量还应具有原始未嵌入的数据以及与数据集主题相关的任何信息。

在下面的代码示例中,我们使用 knn 参数执行搜索命令,该参数包含要比较的字段 (description_embedding) 和原始查询字符串以及用于嵌入查询的模型。搜索方法将查询转换为向量并运行相似度算法。

query_string = "The unliving dead are back to attack the living"
model_id = "sentence-transformers__msmarco-minilm-l-12-v3"

search_results = es.search(
  index=INDEX_NAME,
  knn={
    "field": "description_embedding",
    "query_vector_builder": {
      "text_embedding": {
        "model_id": model_id, 
        "model_text": query_string
      }
    },
  },
)

print(search_results)

作为响应,我们会收到来自 Elastic 云的有效负载,其中包含按相似度得分排序的书籍对象数组,其中 0 表示相关性最低,1 表示完全匹配。以下是响应的截断版本:

Book: Siege
Author: Rhiannon Frater
Description: As the survivors continue to seek stability in their lives,
forces both inside and outside the fort walls move them toward a final, 
climactic conflict betweenthe living and the dead.  Jenni, Katie and the
others discover that they are not alone, that there is anotherenclave of
survivors whose leaders plan to take over the fort.Faced with a series of 
difficult decisions, each choice they make could lead to the deaths of 
those they love or, if notcareful, their own demise.Meanwhile, an army of 
the dead is descending on the fort.Soon, the living will face their ultimate
fear......a siege by the dead.But they will fight to the end to survive...
As the world dies.
Score: 0.7783239

Book: The Walking Dead, Vol. 8: Made to Suffer
Author: Robert Kirkman
Description: The world we knew is gone. The world of commerce and frivolous
necessity has been replaced by a world of survival and responsibility.
An epidemic of apocalyptic proportions has swept the globe, causing the dead
to rise and feed on the living. In a matter of months society has crumbled: no
government, no grocery stores, no mail delivery, no cable TV. In a world ruled
by the dead, the survivors are forced to finally start living. The series that
created the zombie movement reaches its most pivotal, series-altering arc yet!
They thought they were safe in the prison. They were wrong. A force far more
deadly than the walking dead is at their door and when the dust settles, their
rank will be reduced by more than half. No one is safe! Reprint Edition
Score: 0.7740557

Book: Fire
Author: William Esmont
Description: No one knows what caused the dead to rise. No one knows what
caused them to attack the living. Fighting for their lives, scattered survivors
find the attempted cure to be almost worse than the disease.In the twilight of
a shattered civilization, the fate of humankind rests upon the actions of a
handful of war-weary survivors. Driven to a scorched corner of the former
United States, they alone hold the key to a global reawakening.Or the final
epitaph for a dead planet.
Score: 0.7725022

Book: New Dead: A Zombie Anthology
Author: Christopher Golden
Description: Resurrection! The hungry dead have risen. They shamble down the
street. They hide in back yards, car lots, shopping malls. They devour
neighbors, dogs and police officers. And they are here to stay. The real
question is, what are you going to do about it? How will you survive?How will
the world change when the dead begin to rise? Stoker-award-winning author
Christopher Golden has assembled an original anthology of
never-before-published zombie stories from an eclectic array of today's hottest
writers. Inside there are stories about military might in the wake of an
outbreak, survival in a wasted wasteland, the ardor of falling in love with a
zombie, and a family outing at the circus. Here is a collection of new views on
death and resurrection.With stories from Joe Hill, John Connolly, Max Brooks,
Kelley Armstrong, Tad Williams, David Wellington, David Liss, Aimee Bender,
Jonathan Maberry, and many others, this is a wildly diverse and entertaining
collection... the last word on The New Dead. 
Score: 0.76979184

结论

在 Elasticsearch 中操作向量数据库为高效管理和查询复杂数据集开辟了新的可能性,远远超出了 BM25 或 TF/IDF 等传统全文搜索方法所能提供的范围。通过针对你的特定用例选择和测试向量嵌入模型和相似性算法,你可以启用复杂的语义搜索功能,以了解数据的细微差别,无论是文本、图像还是其他多媒体。这对于需要精确和上下文感知搜索结果的应用程序(例如推荐系统、自然语言处理和图像识别)至关重要。

在围绕我们存储库中的大量书籍对象构建向量数据库的过程中,希望你能看到使用自然人类语言搜索单个书籍描述的实用性。这为我们与图书管理员或书店店员交谈数据提供了机会。通过为你的查询输入提供上下文理解并将其与已经处理和向量化的现有文档进行匹配,语义搜索的强大功能提供了理想的用例。 RAG(Retrieval Augmented Generation - 检索增强生成)是使用转换器模型(例如 ChatGPT)的过程,该模型已被授予访问你精选文档的权限,以生成对自然语言查询的自然语言答案。这提供了增强的用户体验并可以处理复杂的查询。

相反,在实施想量数据库之前和之后,还应考虑语义搜索是否对你的特定用例是必要的。传统全文查询生态系统中精心设计的查询可能会以较低的计算开销返回相同或更好的结果。在选择想量数据库之前,必须谨慎评估数据的复杂性和预期规模,因为较小或较简单的数据集可能不会从添加矢量嵌入中受益显著。通常,在传统搜索框架内微调索引策略和实施排名模型可以提供更高效的性能,而无需机器学习增强。

随着向量数据库和支持技术的不断发展,随时了解最新发展,例如生成式 AI 集成和进一步的调整技术(如标记化和量化),将至关重要。这些进步不仅会提高想量数据库的性能和可扩展性,还能确保它能够适应现代应用程序日益增长的需求。有了正确的工具和知识,你可以充分利用 Elasticsearch 的矢量功能,为你的日常任务提供尖端解决方案。

准备好自己尝试了吗?开始免费试用。
Elasticsearch 集成了 LangChain、Cohere 等工具。加入我们的高级语义搜索网络研讨会,构建你的下一个 GenAI 应用程序!

更多阅读:Elasticsearch:向量相似度技术和评分

原文:Elastic vector database: Build and manage with practical code samples — Search Labs

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2190723.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(java)简单设计一个本地搜索,你会怎么实现

目录 1. 需求分析 2. 系统设计 主要类 3. Java代码实现 4. 进一步扩展 在Java中实现一个简单的本地搜索功能的设计流程通常包括以下几个步骤&#xff1a; 1. 需求分析 输入&#xff1a;用户输入要索引的目录路径和搜索的关键词。处理&#xff1a; 扫描指定目录及其子目录…

HTML+CSS之表格(15个案例+代码+效果图+素材)

目录 1.table标签的border属性 案例:制作一个带边框的表格 1.代码 2.效果 2.table标签的cellspacing属性 案例:制作一个带边距的表格 1.代码 2.效果 3.table标签的cellpadding属性 1.代码 2.效果 4.table标签的width和height属性 案例:指定宽高的表格 1.代码 2.效果 5.table标签…

BUSHOUND的抓包使用详解

BUSHOUND是个过滤软件&#xff0c;确切来说是在windows操作系统它的驱动层USB传输的数据。所以这个数据上可能是与USB的总线上的数据是有一点差异的。 先要选择设备的抓包。所以就是在device这个界面底下&#xff0c;我们首先要选择我们要抓的设备。 尝试下键盘设备 电脑键盘…

COPS论文总结——Lec17

文章目录 一、简介二、ALPS1.可用性。2.低延迟。3.分区容忍。4.高可扩展性。5.对比CAP 三、COPS的一致性1.一致性的分类2.Causal 一致性&#xff08;1&#xff09;模型抽象&#xff08;2&#xff09;Causal 定义 一、简介 1.论文的标题是‘Don’t Settle for Eventual: Scalab…

CNN中的平移不变性和平移等变性

1. 平移等变性 数学上函数的等变性定义如下&#xff1a; 也就是给定一张图像&#xff0c;平移后卷积的结果与卷积后再平移的结果是相同的 2. 平移不变性 如果某个属性在任何平移下都不会改变&#xff0c;那么它就是平移不变的。考虑上面的图像。 即使像素值发生了位移&#x…

c++内存申请和释放

// // Created by 徐昌真 on 2024/10/5. // #include <iostream> using namespace std; int main() {//在堆区申请一块内存int* ptr new int(1314); //申请了一个int类型的内存 用ptr指针指向它 它的值是1314cout << *ptr << endl;//可以通过指针修改它的值…

【C++差分数组】1589. 所有排列中的最大和|1871

本文涉及知识点 C差分数组 LeetCode1589. 所有排列中的最大和 有一个整数数组 nums &#xff0c;和一个查询数组 requests &#xff0c;其中 requests[i] [starti, endi] 。第 i 个查询求 nums[starti] nums[starti 1] … nums[endi - 1] nums[endi] 的结果 &#xff…

华为OD机试 - 基站维护工程师数 - 动态规划(Python/JS/C/C++ 2024 E卷 200分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…

GEE问题:筛选指定区域的Sentinel-1影像缺乏VH等波段

目录 问题简介 原始代码 原始代码 问题解析 修改后的代码 问题简介 亲爱的同事们&#xff0c;我正在尝试使用 SAR 图像 - Sentinel-1 来改进使用机器学习的地上生物量建模。我想处理 Sentinel 图像并将它们作为波段插入以增强模型。通过阅读文档&#xff0c;可用的极化&a…

前端编程艺术(3)---JavaScript

目录 1.JavaScript 1.输出 2.变量和数据类型 3.运算符 4.数组 5.函数 6.面向对象 7.ES6面向对象 2.BOM 1.document对象 3.DOM 4.JSON 1.JavaScript JavaScript是一种脚本编程语言&#xff0c;通常用于为网页增加交互性和动态效果。它是一种高级语言&#xff…

用js和css实现一行一行文字交替显示

用js和css实现&#xff0c;效果是&#xff1a;有多行文字&#xff0c;一行一行的交替显示&#xff0c;每隔几秒显示一行&#xff0c;循环显示。 代码如下&#xff0c;保存为html即可看到效果&#xff1a; <!DOCTYPE html> <html lang"en"> <hea…

心觉:梦想成真的三个核心步骤

Hi&#xff0c;我是心觉&#xff0c;与你一起玩转潜意识、脑波音乐和吸引力法则&#xff0c;轻松掌控自己的人生&#xff01; 挑战每日一省写作190/1000天 梦想成真是每个人的愿望 但是希望你不要把“梦想成真”这四个字当成愿望或许愿&#xff0c;因为它实际上是一个成事的…

为什么芯片有多个不同的供电电压?

一、为什么芯片有多个不同的供电电压&#xff1f; 优化性能与功耗&#xff1a;芯片的核心部分&#xff08;Core&#xff09;和输入输出部分&#xff08;IO&#xff09;可能采用不同的电压。核心电压通常较低&#xff0c;以减少功耗和发热&#xff0c;提高能效&#xff1b;而IO电…

如何解决msvcp140.dll丢失,这6个方法可以解决msvcp140.dll丢失

在日常电脑使用中&#xff0c;可能会遇到一些常见问题&#xff0c;比如msvcp140.dll丢失或损坏。这个问题会导致程序无法正常运行&#xff0c;对我们的生活、工作造成困扰。本文将介绍6种解决msvcp140.dll丢失的方法&#xff0c;让大家能快速解决这个问题。 一&#xff0c;msvc…

25游卡(服务器)面试经验 游卡最常见面试问题总结

目录 【面试经历】 问题+详细答案 面试流程 面试攻略 【面试经历】 秋招目前面了十多家,第一家不开摄像头且表示麦不好要求找个耳机的。贴面经(纯八股) 1.HTTP与HTTPS 2.MTU如何设置,过大过小的后果 3.DNS过程 4.如何创建进程/线程,孤儿进程 5.java从文件到运行的过程…

大厂笔试现已经禁用本地IDE怎么看

如果我说本来面试做题这种事情就是反人类你相信吗&#xff1f; 这个罪恶的源头就是 Google&#xff0c;说是为了选择高素质的计算机编程水平的人才&#xff0c;然后把面试就变成了考试&#xff0c;最大的受益者当然是印度人了。 当把一个考察过程变成标准化的考试过程&#x…

每日一道算法题——二分查找

文章目录 开口闭口区分:1、问题2、示例3、解决方法&#xff08;1&#xff09;注意点&#xff08;2&#xff09;代码 开口闭口区分: 开口闭口区分: [1,2,3] 左闭右闭[1,2,3) 左闭右开(1,2,3] 左开右闭 开口如数组(1,2,3)不包含当前数据&#xff0c;也就是指只有2&#xff0c;闭口…

各省-科技创新、研发强度数据(2007-2022年)

研发强度通常指研究与试验发展&#xff08;R&D&#xff09;经费与国内生产总值&#xff08;GDP&#xff09;之比&#xff0c;是衡量一个国家或地区科技活动强度的重要指标。高研发强度往往意味着更强的科技创新能力和更快的技术进步速度。 从地区分布来看&#xff0c;研发…

什么是 HTTP 请求中的 preflight 类型请求

在浏览器的 HTTP 请求中&#xff0c;当我们使用 fetch API 或者 XMLHttpRequest 来进行跨域请求时&#xff0c;浏览器有时会发送一种称为 Preflight 的请求。这种请求是浏览器在实际发送跨域请求前&#xff0c;先与目标服务器进行的一次 “探测” 请求&#xff0c;以确认服务器…

java基础_异常总结详解

1 列举一些列举常见的运行时异常 运行时异常都是 RuntimeException 子类异常 NullPointerException - 空指针异常 ClassCastException - 类转换异常 IndexOutOfBoundsException - 下标越界异常 ArithmeticException - 计算异常 IllegalArgumentException - 非法参数异常 Numb…