Elasticsearch:语义搜索快速入门

news2024/11/24 18:35:05

这个交互式 jupyter notebook 将使用官方 Elasticsearch Python 客户端向你介绍 Elasticsearch 的一些基本操作。 你将使用 Sentence Transformers 进行文本嵌入的语义搜索。 了解如何将传统的基于文本的搜索与语义搜索集成,形成混合搜索系统。在本示例中,我们将使用模型自带的功能对文本进行向量化,而不借助 Elasticsearch 所提供的 ingest pipeline 来进行矢量化。这样的好处是完全免费,不需要购买版权。如果你想使用 ingest pipeline 来进行向量化,请参阅文章 ”Elasticsearch:使用 huggingface 模型的 NLP 文本搜索“。

安装

Elasticsearch 及 Kibana

如果你还没有安装好自己的 Elasticsearch 及 Kibana,请参考如下的链接来进行安装:

  • 如何在 Linux,MacOS 及 Windows 上进行安装 Elasticsearch

  • Kibana:如何在 Linux,MacOS 及 Windows 上安装 Elastic 栈中的 Kibana

在安装的时候,我们可以选择 Elastic Stack 8.x 的安装指南来进行安装。在本博文中,我将使用最新的 Elastic Stack 8.10 来进行展示。

在安装 Elasticsearch 的过程中,我们需要记下如下的信息:

Python 安装包

在本演示中,我们将使用 Python 来进行展示。我们需要安装访问 Elasticsearch 相应的安装包 elasticsearch:

python3 -m pip install -qU sentence-transformers elasticsearch transformers

我们将使用 Jupyter Notebook 来进行展示。

$ pwd
/Users/liuxg/python/elser
$ jupyter notebook

创建应用并展示

设置嵌入模型

在此示例中,我们使用 all-MiniLM-L6-v2,它是 sentence_transformers 库的一部分。 你可以在 Huggingface 上阅读有关此模型的更多信息。

from sentence_transformers import SentenceTransformer
import torch

device = 'cuda' if torch.cuda.is_available() else 'cpu'

model = SentenceTransformer('all-MiniLM-L6-v2', device=device)
model

初始化 Elasticsearch 客户端

现在我们可以实例化 Elasticsearch python 客户端。我们必须提高响应的账号及证书信息:

from elasticsearch import Elasticsearch

ELASTCSEARCH_CERT_PATH = "/Users/liuxg/elastic/elasticsearch-8.10.0/config/certs/http_ca.crt"
 
client = Elasticsearch(  ['https://localhost:9200'],
    basic_auth = ('elastic', 'vXDWYtL*my3vnKY9zCfL'),
    ca_certs = ELASTCSEARCH_CERT_PATH,
    verify_certs = True)
print(client.info())

摄入一些数据

我们的客户端已设置并连接到我们的 Elasticsearch 部署。 现在我们需要一些数据来测试 Elasticsearch 查询的基础知识。 我们将使用包含以下字段的小型书籍索引:

  • title
  • authors
  • publish_date
  • num_reviews
  • publisher

我们在当前项目的根目录下创建 books.json 文件:

books.json

[
  {
    "title": "The Pragmatic Programmer: Your Journey to Mastery",
    "authors": ["andrew hunt", "david thomas"],
    "summary": "A guide to pragmatic programming for software engineers and developers",
    "publish_date": "2019-10-29",
    "num_reviews": 30,
    "publisher": "addison-wesley"
  },
  {
    "title": "Python Crash Course",
    "authors": ["eric matthes"],
    "summary": "A fast-paced, no-nonsense guide to programming in Python",
    "publish_date": "2019-05-03",
    "num_reviews": 42,
    "publisher": "no starch press"
  },
  {
    "title": "Artificial Intelligence: A Modern Approach",
    "authors": ["stuart russell", "peter norvig"],
    "summary": "Comprehensive introduction to the theory and practice of artificial intelligence",
    "publish_date": "2020-04-06",
    "num_reviews": 39,
    "publisher": "pearson"
  },
  {
    "title": "Clean Code: A Handbook of Agile Software Craftsmanship",
    "authors": ["robert c. martin"],
    "summary": "A guide to writing code that is easy to read, understand and maintain",
    "publish_date": "2008-08-11",
    "num_reviews": 55,
    "publisher": "prentice hall"
  },
  {
    "title": "You Don't Know JS: Up & Going",
    "authors": ["kyle simpson"],
    "summary": "Introduction to JavaScript and programming as a whole",
    "publish_date": "2015-03-27",
    "num_reviews": 36,
    "publisher": "oreilly"
  },
  {
    "title": "Eloquent JavaScript",
    "authors": ["marijn haverbeke"],
    "summary": "A modern introduction to programming",
    "publish_date": "2018-12-04",
    "num_reviews": 38,
    "publisher": "no starch press"
  },
  {
    "title": "Design Patterns: Elements of Reusable Object-Oriented Software",
    "authors": [
      "erich gamma",
      "richard helm",
      "ralph johnson",
      "john vlissides"
    ],
    "summary": "Guide to design patterns that can be used in any object-oriented language",
    "publish_date": "1994-10-31",
    "num_reviews": 45,
    "publisher": "addison-wesley"
  },
  {
    "title": "The Clean Coder: A Code of Conduct for Professional Programmers",
    "authors": ["robert c. martin"],
    "summary": "A guide to professional conduct in the field of software engineering",
    "publish_date": "2011-05-13",
    "num_reviews": 20,
    "publisher": "prentice hall"
  },
  {
    "title": "JavaScript: The Good Parts",
    "authors": ["douglas crockford"],
    "summary": "A deep dive into the parts of JavaScript that are essential to writing maintainable code",
    "publish_date": "2008-05-15",
    "num_reviews": 51,
    "publisher": "oreilly"
  },
  {
    "title": "Introduction to the Theory of Computation",
    "authors": ["michael sipser"],
    "summary": "Introduction to the theory of computation and complexity theory",
    "publish_date": "2012-06-27",
    "num_reviews": 33,
    "publisher": "cengage learning"
  }
]
$ pwd
/Users/liuxg/python/elser
$ ls
Multilingual semantic search.ipynb
NLP text search using hugging face transformer model.ipynb
Semantic search - ELSER.ipynb
Semantic search quick start.ipynb
books.json
data.json

创建索引

让我们使用测试数据的正确映射创建一个 Elasticsearch 索引。

INDEX_NAME = "book_index"

if es.indices.exists(index=INDEX_NAME):
    print("Deleting existing %s" % INDEX_NAME)
    client.options(ignore_status=[400, 404]).indices.delete(index=INDEX_NAME)

# Define the mapping
mappings = {
    "properties": {
        "title_vector": {
            "type": "dense_vector",
            "dims": 384,
            "index": "true",
            "similarity": "cosine"
        }
    }
}


# Create the index
client.indices.create(index = INDEX_NAME, mappings = mappings)

索引测试数据

运行以下命令上传一些测试数据,其中包含该数据集中的 10 本流行编程书籍的信息。 model.encode 将使用我们之前初始化的模型将文本动态编码为向量。

import json

# Load data into a JSON object
with open('books.json') as f:
   data_json = json.load(f)
 
print(data_json)

actions = []
for book in data_json:
    actions.append({"index": {"_index": INDEX_NAME}})
    # Transforming the title into an embedding using the model
    book["title_vector"] = model.encode(book["title"]).tolist()
    actions.append(book)
client.bulk(index=INDEX_NAME, operations=actions)

我们可以在 Kibana 中进行查看:

GET book_index/_search

漂亮地打印 Elasticsearch 响应

你的 API 调用将返回难以阅读的嵌套 JSON。 我们将创建一个名为 Pretty_response 的小函数,以从示例中返回漂亮的、人类可读的输出。

def pretty_response(response):
    for hit in response['hits']['hits']:
        id = hit['_id']
        publication_date = hit['_source']['publish_date']
        score = hit['_score']
        title = hit['_source']['title']
        summary = hit['_source']['summary']
        publisher = hit["_source"]["publisher"]
        num_reviews = hit["_source"]["num_reviews"]
        authors = hit["_source"]["authors"]
        pretty_output = (f"\nID: {id}\nPublication date: {publication_date}\nTitle: {title}\nSummary: {summary}\nPublisher: {publisher}\nReviews: {num_reviews}\nAuthors: {authors}\nScore: {score}")
        print(pretty_output)

查询

现在我们已经对书籍进行了索引,我们想要对与给定查询相似的书籍执行语义搜索。 我们嵌入查询并执行搜索。

response = client.search(index="book_index", body={
    "knn": {
      "field": "title_vector",
      "query_vector": model.encode("Best javascript books?"),
      "k": 10,
      "num_candidates": 100
    }
})

pretty_response(response)

过滤

过滤器上下文主要用于过滤结构化数据。 例如,使用过滤器上下文来回答以下问题:

  • 该时间戳是否在 2015 年至 2016 年范围内?
  • 状态字段是否设置为 “published”?

每当查询子句传递给过滤器参数(例如布尔查询中的 filter 或 must_not 参数)时,过滤器上下文就会生效。

在 Elasticsearch 文档中了解有关过滤器上下文的更多信息。

示例:关键字过滤

这是向查询添加关键字过滤器的示例。

它通过仅包含 “publisher” 字段等于 “addison-wesley” 的文档来缩小结果范围。

该代码检索类似于 “Best javascript books?” 的热门书籍。 基于他们的 title 向量,并以 “addison-wesley” 作为出版商。

response = client.search(index=INDEX_NAME, body={
    "knn": {
      "field": "title_vector",
      "query_vector": model.encode("Best javascript books?"),
      "k": 10,
      "num_candidates": 100,
      "filter": {
          "term": {
              "publisher.keyword": "addison-wesley"
          }
      }
    }
})

pretty_response(response)

示例:高级过滤

Elasticsearch 中的高级过滤允许通过应用条件来精确细化搜索结果。 它支持多种运算符,可用于根据特定字段、范围或条件过滤结果,从而提高搜索结果的精度和相关性。 在此查询和过滤上下文示例中了解更多信息。

response = client.search(index="book_index", body={
    "knn": {
      "field": "title_vector",
      "query_vector": model.encode("Best javascript books?"),
      "k": 10,
      "num_candidates": 100,
      "filter": {
          "bool": {
              "should": [
                  {
                    "term": {
                        "publisher.keyword": "addison-wesley"
                    }
                  },
                  {
                    "term": {
                        "authors.keyword": "robert c. martin"
                    }
                  }
              ],

          }
      }
    }
})

pretty_response(response)

Hybrid search

在此示例中,我们正在研究两种搜索算法的组合:用于文本搜索的 BM25 和用于最近邻搜索的 HNSW。 通过结合多种排名方法,例如 BM25 和生成密集向量嵌入的 ML 模型,我们可以获得最佳排名结果。 这种方法使我们能够利用每种算法的优势并提高整体搜索性能。

倒数排名融合 (RRF) 是一种最先进的排名算法,用于组合来自不同信息检索策略的结果。 RRF 在未经校准的情况下优于所有其他排名算法。 简而言之,它支持开箱即用的一流混合搜索。

response = client.search(index="book_index", body={
    "query": {
        "match": {
            "summary": "python"
        }
    },
    "knn": {
        "field": "title_vector",
        # generate embedding for query so it can be compared to `title_vector`
        "query_vector" : model.encode("python programming").tolist(),
        "k": 5,
        "num_candidates": 10
    },
    "rank": {
        "rrf": {
            "window_size": 100,
            "rank_constant": 20
        }
    }
})

pretty_response(response)

最终的 jupyter 文件可以在地址下载。

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

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

相关文章

漏刻有时数据可视化大屏(15)智慧党建大数据平台

智慧党建大数据平台是依托现代信息技术和“互联网党建”的大数据管理模式,建立的综合党建平台。该平台集组织管理、党务中心、学习考评、宣传阵地、统计分析、党建助手、我的工作台等主要功能于一体,实现了基层党建工作数据化、在线化、可视化。以下是智…

使用弹性盒子flex对html进行布局和动态计算视口高度

使用弹性盒子flex对html进行布局的一个练习 height: calc(100vh - 4px); # vh表示视口高度的百分比,所以100vh表示整个视口的高度。 .mytxt { text-indent: 2em; /* 首航缩进2字符 */ line-height: 2; /* 2倍行高 */ padding: 8px; /* 内容与边框的距离 */ } …

MQ - 37 云原生:MQ的分层存储架构的实现方案

文章目录 导图概述什么是分层存储分层存储的应用和局限实现分层存储的技术思考选择远程文件系统生产性能优化消费性能优化方案一方案二隔离性和回滚隔离性回滚业界主流消息队列的架构分析RocektMQ 多级存储的实现分析Kakfa 分层存储的实现分析为什么 RocketMQ 使用准实时的方式…

Transformer预测 | Pytorch实现基于Transformer 的锂电池寿命预测(CALCE数据集)

文章目录 效果一览文章概述模型描述程序设计参考资料效果一览 文章概述 Pytorch实现基于Transformer 的锂电池寿命预测,环境为pytorch 1.8.0,pandas 0.24.2 随着充放电次数的增加,锂电池的性能逐渐下降。电池的性能可以用容量来表示,故寿命预测 (RUL) 可以定义如下: SOH(t…

【银河麒麟V10】【服务器】Oracle11g部署

一、环境准备 操作系统版本:银河麒麟V10 SP1 0518 Server x86_64 二、基础环境准备 1、安装麒麟操作系统 注意:预留至少7G以上swap缓存 2、关闭selinux和firewalld 3、如果是内网环境需要挂载本地源 【银河麒麟V10】【服务器】搭建本地镜像源_桂安俊…

【Linux】Vim使用总结

【Linux】Vim使用总结 Vim 的三种模式命令行模式1. 移动2.复制,粘贴,剪切3.撤销4.大小写切换,替换,删除 插入模式底行模式 Vim 的三种模式 一进入VIM就是处于一般模式(命令模式),该模式下只能输…

java BigInteger的基本使用

BigInteger 注意对象一旦创建,内部记录的值不能发生改变 import java.math.BigInteger; import java.util.Random;public class myBigInteger {public static void main(String[] args) {//获取一个随机的大整数BigInteger bigIntegernew BigInteger(4,new Random());System.ou…

3dmax怎样渲染全景图?3dmax渲染全景图的2种方法

3dmax怎样渲染全景图?今天介绍3dmax渲染全景图的3种方法 3dmax渲染全景图方法1 在 360 度渲染时,您必须采取的第一步是放置摄像机。 定位相机:选择您要使用的相机类型。 无论您希望使用哪种类型的相机(目标相机、物理相机或免费…

漏刻有时数据可视化Echarts组件开发(42)炫酷的pictorialBar象形柱图代码分析

核心代码 var data []; for (let i 0; i < 5; i) {data.push(Math.round(Math.random() * 10)); } var xData2 ["A", "B", "C", "D", "E"]; var data1 [100, 100, 100, 100, 100]; // var data2 [50, 32, 55, 65, …

WPF向Avalonia迁移(三、项目结构)

前提&#xff1a; Avalonia版本11.0.0 1.配置文件 1.1 添加配置文件 1.2 读取配置文件 添加System.Configuration.ConfigurationManager using Avalonia.Controls; using System.Configuration;namespace AvaloniaApplication7.Views {public partial class MainWindow : W…

java实验(头歌)--面向对象封装继承和多态

文章目录 第一题第二题第三题第四题第五题第六题第七题第八题 快速完成实验的方法&#xff1a; 把对应题目的主函数替换&#xff0c;其他复制粘贴。 第一题 public class TestPersonDemo {public static void main(String[] args) {/********* begin *********/// 声明并实例化…

基于双二阶广义积分器的三相锁相环(DSOGI-PLL)Simulink仿真

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

漏刻有时数据可视化Echarts组件开发(41)svg格式地图应用

1.定义SVG文件 var svg ;2.注册地图函数 Echarts.registerMap是Echarts图表库中用于注册地图的函数。它可以将第三方地图或自定义地图数据与Echarts进行集成&#xff0c;使用Echarts的API进行绘制。使用方法如下&#xff1a; echarts.registerMap(mapName, geoJson) 参数map…

vscode Vue代码script全白

原因&#xff1a;template闭合标签有换行 更改为一行之后&#xff0c;成功解决

置换环建笛卡尔树:AT_wtf22Day1B

https://atcoder.jp/contests/wtf22-day1/tasks/wtf22_day1_b?langen 置换环是用值连位 首先肯定要分成每个置换环&#xff0c;每个置换环操作次数只能是 s i z e − 1 size-1 size−1&#xff08;置换环性质&#xff09; 我们考虑置换环任意一次操作&#xff0c;会划分成…

【C++】笔试训练(四)

目录 一、选择题二、编程题1、计算糖果2、进制转换 一、选择题 1、有以下程序&#xff0c;程序运行后的输出结果是&#xff08;&#xff09; #include<iostream> #include<cstdio> using namespace std; int main() {int m 0123, n 123;printf("%o %o\n&…

VR酒店虚拟仿真情景实训教学演示

在传统的酒店管理教学过程中&#xff0c;学生往往缺乏实践操作经验&#xff0c;难以将理论知识与实际工作相结合。而VR酒店虚拟仿真情景实训教学应用可以为学生提供一个逼真的、沉浸式的酒店管理环境&#xff0c;使学生能够在模拟实践中掌握酒店管理的各项技能。 VR酒店虚拟仿真…

【漏洞复现】时空智友企业流程化管控系统 session泄露

漏洞描述 时空智友企业流程化管控系统 session 泄露 免责声明 技术文章仅供参考&#xff0c;任何个人和组织使用网络应当遵守宪法法律&#xff0c;遵守公共秩序&#xff0c;尊重社会公德&#xff0c;不得利用网络从事危害国家安全、荣誉和利益&#xff0c;未经授权请勿利用…

【通义千问】Qwen从本地加载分词器报错‘‘tokenizer class not exist‘‘

问题描述&#xff1a; 将模型文件下载到本地&#xff0c; 模型文件>https://huggingface.co/Qwen/Qwen-7B-Chat/tree/main 通过【from_pretrained】去加载本地磁盘上的分词器 YOURPATH models/Qwen-7B-Chatname Qwen/Qwen-7B-Chat tokenizer AutoTokenizer.from_pretr…

windows RPC调用过程实例详解

概述&#xff1a;windows 创建 RPC调用过程实例详解 参考文章&#xff1a;Remote procedure call (RPC)&#xff08;远程过程调用 (RPC)&#xff09; - Win32 apps | Microsoft Learn 文章目录 0x01、生成 UUID 和模版(IDL)文件0x02、添加 acf 文件0x03、编译 idl 文件0x04、客…