使用 Python 中的 ELSER 进行Serverless 语义搜索:探索夏季奥运会历史

news2024/9/9 0:06:28

作者:来自 Elastic Essodjolo Kahanam

本博客介绍如何使用语义搜索以自然语言表达形式从 Elasticsearch 索引中获取信息。我们将创建一个无服务器 Elasticsearch 项目,将之前的奥运会数据集加载到索引中,使用推理处理器和 ELSER 模型生成推理数据(在稀疏向量场中),最后借助文本扩展(text expansion)查询以自然语言表达形式搜索历史奥运会比赛信息。

工具和数据集

对于这个项目,我们将使用 Elasticsearch serverless 项目和无服务器 Python 客户端 (elasticsearch_serverless) 与 Elasticsearch 交互。要创建 serverless 项目,只需按照 serverless 入门指南操作即可。有关 serverless 的更多信息(包括定价),可在此处找到。

设置 serverless 项目时,请务必选择 Elasticsearch 选项和用于本教程的通用选项。

使用的数据集是从 Kaggle (Athletes_summer_games.csv) 获得的 1896 年至 2020 年夏季奥运会参赛者的数据集。它包含有关比赛年份、比赛类型、参赛者姓名、他们是否赢得奖牌以及最终获得哪枚奖牌以及其他信息的信息。

对于数据集操作,我们将使用 Eland,这是一个用于 Elasticsearch 中的 DataFrames 和机器学习的 Python 客户端和工具包。

最后使用的自然语言处理 (NLP) 模型是 Elastic Learned Sparse EncodeR (ELSER),这是一个由 Elastic 训练的检索模型,允许通过语义搜索检索更相关的搜索结果。

在执行以下步骤之前,请确保你已安装 severless Python 客户端和 Eland。

pip install elasticsearch_serverless
pip install eland

请注意下面我使用的版本。如果你使用的不是同一个版本,则可能需要根据你使用的版本中的任何最终语法更改来调整代码。

➜  ~ python3 --version
Python 3.9.6
➜  ~ pip3 list | grep -E 'elasticsearch-serverless|eland'
eland                     8.14.0
elasticsearch-serverless  0.3.0.20231031

下载并部署 ELSER 模型

我们将使用 Python 客户端下载并部署 ELSER 模型。在此之前,让我们先确认我们可以连接到我们的 serverless 项目。下面的 URL 和 API 密钥是从环境变量中读取的;你需要根据自己的情况使用适当的值,或者使用你喜欢的任何方法来读取凭据。

from elasticsearch_serverless import Elasticsearch
from os import environ


serverless_endpoint = environ.get("SERVERLESS_ENDPOINT_URL")
serverless_api_key = environ.get("SERVERLESS_API_KEY")


client = Elasticsearch(
 serverless_endpoint,
 api_key=serverless_api_key
)


client.info()

如果一切配置正确,你应该得到如下输出:

ObjectApiResponse({'name': 'serverless', 'cluster_name': 'd6c6698e28c34e58b6f858df9442abac', 'cluster_uuid': 'hOuAhMUPQkumEM-PxW_r-Q', 'version': {'number': '8.11.0', 'build_flavor': 'serverless', 'build_type': 'docker', 'build_hash': '00000000', 'build_date': '2023-10-31', 'build_snapshot': False, 'lucene_version': '9.7.0', 'minimum_wire_compatibility_version': '8.11.0', 'minimum_index_compatibility_version': '8.11.0'}, 'tagline': 'You Know, for Search'})

现在我们已经确认 Python 客户端已成功连接到无服务器 Elasticsearch 项目,让我们下载并部署 ELSER 模型。我们将检查该模型是否之前已部署,并将其删除以执行全新安装。此外,由于部署阶段可能需要几分钟,我们将不断检查模型配置信息,以确保在进入下一阶段之前模型定义存在。有关更多信息,请查看Get trained models API。

from elasticsearch_serverless import Elasticsearch, exceptions
import time


# delete model if already downloaded and deployed
try:
   client.ml.delete_trained_model(model_id=".elser_model_2", force=True)
   print("Model deleted successfully, We will proceed with creating one")
except exceptions.NotFoundError:
   print("Model doesn't exist, but We will proceed with creating one")


# Creates the ELSER model configuration. Automatically downloads the model if it doesn't exist.
client.ml.put_trained_model(
   model_id=".elser_model_2",
   input={
       "field_names": [
           "concatenated_textl"
       ]
   }
)


# Check the download and deploy progress
while True:
   status = client.ml.get_trained_models(
       model_id=".elser_model_2", include="definition_status"
   )


   if status["trained_model_configs"][0]["fully_defined"]:
       print("ELSER Model is downloaded and ready to be deployed.")
       break
   else:
       print("ELSER Model is downloaded but not ready to be deployed.")
   time.sleep(5)

一旦我们确认模型已下载并准备部署,我们就可以继续启动 ELSER。完全准备好部署可能需要一点时间。

# A function to check the model's routing state
# https://www.elastic.co/guide/en/elasticsearch/reference/current/get-trained-models-stats.html
def get_model_routing_state(model_id=".elser_model_2"):
   try:
       status = client.ml.get_trained_models_stats(
           model_id=".elser_model_2",
       )
       return status["trained_model_stats"][0]["deployment_stats"]["nodes"][0]["routing_state"]["routing_state"]
   except:
       return None


# If ELSER is already started, then we are fine.
if get_model_routing_state(".elser_model_2") == "started":
   print("ELSER Model has been already deployed and is currently started.")


# Otherwise, we will deploy it, and monitor the routing state to make sure it is started.
else:
   print("ELSER Model will be deployed.")


   # Start trained model deployment
   client.ml.start_trained_model_deployment(
       model_id=".elser_model_2",
       number_of_allocations=16,
       threads_per_allocation=4,
       wait_for="starting"
   )


   while True:
       if get_model_routing_state(".elser_model_2") == "started":
           print("ELSER Model has been successfully deployed.")
           break
       else:
           print("ELSER Model is currently being deployed.")
       time.sleep(5)

使用 Eland 将数据集加载到 Elasticsearch

eland.csv_to_eland 允许将逗号分隔值 (csv) 文件读入存储在 Elasticsearch 索引中的数据框中。我们将使用它将奥运会数据 (Athletes_summer_games.csv) 加载到 Elasticsearch 中。es_type_overrides 允许覆盖默认映射。

import eland as ed


index="elser-olympic-games"
csv_file="Athletes_summer_games.csv"


ed.csv_to_eland(
   csv_file,
   es_client=client,
   es_dest_index=index,
   es_if_exists='replace',
   es_dropna=True,
   es_refresh=True,
   index_col=0,
   es_type_overrides={
       "City": "text",
       "Event": "text",
       "Games": "text",
       "Medal": "text",
       "NOC": "text",
       "Name": "text",
       "Season": "text",
       "Sport": "text",
       "Team": "text"
   }
)

执行上述代码后,数据将写入索引 elser-olympic-games。你还可以将生成的数据框 (eland.DataFrame) 检索到变量中,以供进一步操作。

基于 ELSER 创建用于推理的摄取管道

我们使用语义搜索探索过去奥运会比赛数据的下一步是创建一个包含运行 ELSER 模型的 inference processor 的摄取管道。已选择一组字段并将其串联成推理处理器将在其上工作的单个字段。根据你的用例,你可能需要使用另一种策略。

串联是使用 script processor 完成的。推理处理器使用先前部署的 ELSER 模型,将串联字段作为输入,并将输出存储在稀疏向量类型字段中(参见以下要点)。

client.ingest.put_pipeline(
   id="elser-ingest-pipeline",
   description="Ingest pipeline for ELSER",
   processors=[
       {
           "script": {
           "description": "Concatenate some selected fields value into `concatenated_text` field",
           "lang": "painless",
           "source": """
               ctx['concatenated_text'] = ctx['Name'] + ' ' + ctx['Team'] + ' ' + ctx['Games'] + ' ' + ctx['City'] + ' ' + ctx['Event'];
           """
           }
       },
       {
           "inference": {
               "model_id": ".elser_model_2",
               "ignore_missing": True,
               "input_output": [
                   {
                       "input_field": "concatenated_text",
                       "output_field": "concatenated_text_embedding"
                   }
               ]
           }
       }
   ]
)

准备索引

这是使用自然语言表达查询过去奥运会比赛数据之前的最后一个阶段。我们将更新之前创建的索引的映射,添加一个 sparse vector 类型字段。

更新映射:添加稀疏向量字段

我们将通过添加一个用于保存串联数据(concatenated data)的字段和一个用于保存推理处理器使用 ELSER 模型计算出的推断信息的稀疏向量字段来更新索引映射。

index="elser-olympic-games"


mappings_properties={
   "concatenated_text": {
       "type": "text"
   },
   "concatenated_text_embedding": {
       "type": "sparse_vector"
   }
}


client.indices.put_mapping(
   index=index,
   properties=mappings_properties
)

填充稀疏向量字段

我们将通过运行 update by query 来调用之前创建的摄取管道,以便填充每个文档中的稀疏向量字段。

client.update_by_query(
   index="elser-olympic-games",
   pipeline="elser-ingest-pipeline",
   wait_for_completion=False
)

该请求将需要一些时间,具体取决于文档数量以及用于部署 ELSER 的分配数量和每个分配的线程数。完成此步骤后,我们现在可以开始使用语义搜索探索过去的奥运会数据集。

让我们使用语义搜索探索奥运会数据集

现在我们将使用 text expansion 查询,使用自然语言表达来检索有关过去奥运会比赛的信息。在进行演示之前,让我们创建一个函数来检索和格式化搜索结果。

def semantic_search(search_text):
   response = client.search(
       index="elser-olympic-games",
       size=3,
       query={
           "bool": {
           "must": [
               {
                   "text_expansion": {
                       "concatenated_text_embedding": {
                       "model_id": ".elser_model_2",
                       "model_text": search_text
                       }
                   }
               },
               {
                   "exists": {
                       "field": "Medal"
                   }
               }
           ]
           }
       },
       source_excludes="*_embedding, concatenated_text"
   )


   for hit in response["hits"]["hits"]:
       doc_id = hit["_id"]
       score = hit["_score"]
       year = hit["_source"]["Year"]
       event = hit["_source"]["Event"]
       games = hit["_source"]["Games"]
       sport = hit["_source"]["Sport"]
       city = hit["_source"]["City"]
       team = hit["_source"]["Team"]
       name = hit["_source"]["Name"]
       medal = hit["_source"]["Medal"]


       print(f"Score: {score}\nDocument ID: {doc_id}\nYear: {year}\nEvent: {event}\nName: {name}\nCity: {city}\nTeam: {team}\nMedal: {medal}\n")

上述函数将接收有关往届奥运会比赛获胜者的问题,并使用 Elastic 的 text expansion 查询执行语义搜索。检索到的结果将被格式化并打印出来。请注意,我们强制查询中存在奖牌,因为我们只对获胜者感兴趣。我们还将结果的大小限制为 3,因为我们预计会有三名获胜者(金牌、银牌、铜牌)。同样,根据你的用例,你可能不一定会做同样的事情。

🏌️‍♂️ “Who won the Golf competition in 1900?”

请求:

semantic_search("Who won the Golf competition in 1900?")

响应:

Score: 18.184263
Document ID: 206566
Year: 1900
Event: Golf Men's Individual
Name: Walter Mathers Rutherford
City: Paris
Team: Great Britain
Medal: Silver

Score: 17.443663
Document ID: 209892
Year: 1900
Event: Golf Men's Individual
Name: Charles Edward Sands
City: Paris
Team: United States
Medal: Gold

Score: 16.939331
Document ID: 192747
Year: 1900
Event: Golf Women's Individual
Name: Myra Abigail "Abbie" Pratt (Pankhurst-, Wright-, -Karageorgevich)
City: Paris
Team: United States
Medal: Bronze

🏹 “Women archery winners of 1908”

请求:

semantic_search("Women archery winners of 1908")

响应:

Score: 21.876282
Document ID: 96010
Year: 1908
Event: Archery Women's Double National Round
Name: Beatrice Geraldine Hill-Lowe (Ruxton-, -Thompson)
City: London
Team: Great Britain
Medal: Bronze

Score: 21.0998
Document ID: 170250
Year: 1908
Event: Archery Women's Double National Round
Name: Sybil Fenton Newall
City: London
Team: Great Britain
Medal: Gold

Score: 21.079535
Document ID: 56686
Year: 1908
Event: Archery Women's Double National Round
Name: Charlotte "Lottie" Dod
City: London
Team: Great Britain
Medal: Silver

🚴‍♂️ “Who won the individual cycling competition in 1972?”

请求:

semantic_search("Who won the cycling competition in 1972?")

响应:

Score: 20.554308
Document ID: 215559
Year: 1972
Event: Cycling Men's Road Race, Individual
Name: Kevin "Clyde" Sefton
City: Munich
Team: Australia
Medal: Silver

Score: 20.267525
Document ID: 128598
Year: 1972
Event: Cycling Men's Road Race, Individual
Name: Hendrikus Andreas "Hennie" Kuiper
City: Munich
Team: Netherlands
Medal: Gold

Score: 19.108923
Document ID: 19225
Year: 1972
Event: Cycling Men's Team Pursuit, 4,000 metres
Name: Michael John "Mick" Bennett
City: Munich
Team: Great Britain
Medal: Bronze

结论

本博客展示了如何使用 serverlss 的 Python 编程语言,通过 Elastic Learned Sparse EncodeR (ELSER) NLP 模型执行语义搜索。运行本教程后,你需要确保关闭 serverless,以避免任何额外费用。要进一步了解,请随时查看我们的 Elasticsearch 相关性引擎 (ESRE​​) 工程师课程,你可以在其中学习如何利用 Elasticsearch 相关性引擎 (ESRE​​) 和大型语言模型 (LLMs) 构建高级 RAG(检索增强生成)应用程序,将 Elasticsearch 的存储、处理和搜索功能与 LLM 的生成能力相结合。

本文中描述的任何特性或功能的发布和时间均由 Elastic 自行决定。任何当前不可用的特性或功能可能无法按时交付或根本无法交付。

准备好自己尝试一下了吗?开始免费试用。

想要获得 Elastic 认证?了解下一期 Elasticsearch 工程师培训何时开始!

更多关于奥运的数据分析,请阅读文章 :

  • 使用 Elastic Stack 来分析奥运数据(一)(二)(三)

原文:Serverless semantic search with ELSER in Python — Search Labs

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

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

相关文章

洛谷 P1883 【模板】三分 | 函数

原题 题目描述 给定 n 个二次函数 f1​(x),f2​(x),…,fn​(x)(均形如 ax2bxc),设 𝐹(𝑥)F(x)max{f1​(x),f2​(x),...,fn​(x)},求 𝐹(𝑥)F(x) 在区间[0,1000] 上的最小值。 输入…

PHP师生荣誉管理系统—计算机毕业设计源码10079

目 录 摘要 1 绪论 1.1 研究背景 1.2论文结构与章节安排 2 师生荣誉管理系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据增加流程 2.2.2 数据修改流程 2.2.3 数据删除流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析 2.…

Hive命令创建数据库和表(内置数据库)

【实验目的】 1) 了解hive操作命令 2) 熟悉hive数据库的操作 【实验原理】 配置完毕hive环境之后,通过hive指令进行创建数据库和表,这些信息被存放在metadata和hdfs上面,当执行操作之后,会在hdfs上有目录结构变化&#xff0c…

windows C/C++系列 64位汇编

Visual Studio 包括 32 位和 64 位托管版本的 MASM(Microsoft 宏汇编程序),面向 x64 代码。 它的名称为 ml64.exe,是接受 x64 汇编程序语言的汇编程序。 当你在 Visual Studio 安装期间选择 C 工作负荷时,会安装 MASM …

【运维】远程控制与访问的协议(域,工作组,RDP,ARD,VNC,SSH,SCP)和工具(DDNS,跳板机,堡垒机)

【运维】远程控制与访问的协议(域,工作组,RDP,ARD,VNC,SSH,SCP)和工具(DDNS,跳板机,堡垒机) 文章目录 1、远程访问协议1.1 组织&#…

基于 SASL/SCRAM 让 Kafka 实现动态授权认证

一、说明 在大数据处理和分析中 Apache Kafka 已经成为了一个核心组件。然而在生产环境中部署 Kafka 时,安全性是一个必须要考虑的重要因素。SASL(简单认证与安全层)和 SCRAM(基于密码的认证机制的盐化挑战响应认证机制&#xff…

傻瓜式PHP-Webshell免杀学习手册,零基础小白也能看懂

项目描述 一、PHP相关资料 PHP官方手册: https://www.php.net/manual/zh/ PHP函数参考: https://www.php.net/manual/zh/funcref.php 菜鸟教程: https://www.runoob.com/php/php-tutorial.html w3school: https://www.w3school…

网络流量分析>>pcapng文件快速分析有用价值解析

引言 在网络安全和流量管理中,解析网络协议数据包是了解网络行为和检测潜在威胁的关键步骤。本文介绍了如何使用Python解析和分析TCP、UDP和ICMP协议的数据包,并统计端口的访问次数。本文的示例代码展示了如何处理不同协议的数据包,提取关键…

网安零基础入门神书,全面介绍Web渗透核心攻击与防御方式!

Web安全是指Web服务程序的漏洞,通常涵盖Web漏洞、操作系统洞、数据库漏洞、中间件漏洞等。 “渗透测试”作为主动防御的一种关键手段,对评估网络系统安全防护及措施至关重要,因为只有发现问题才能及时终止并预防潜在的安全风险。 根据网络安…

前端面试宝典【vue篇】【3】

欢迎来到《前端面试宝典》,这里是你通往互联网大厂的专属通道,专为渴望在前端领域大放异彩的你量身定制。通过本专栏的学习,无论是一线大厂还是初创企业的面试,都能自信满满地展现你的实力。 核心特色: 独家实战案例:每一期专栏都将深入剖析真实的前端面试案例,从基础知…

phpenv安装redis扩展

1、下载dll文件 https://pecl.php.net/package/redis 我的是php8.1, 安装最新版的 DLL文件 2、将dll文件放到php安装目录的ext目录下 3、在php.ini中增加配置后重启服务 [Redis] extension php_redis.dll

自研Vue3开源Tree组件:节点拖拽bug修复

当dropType为after,且dropNode为父节点时,bug出现了: bug原因:插入扁平化列表的位置insertIndex计算的不对: 正确的逻辑,同inner要算上子孙节点所占的位置: bug修复!

vue里给img的src绑定数据失效

起因 在v-for遍历数据时想要通过给img的src单向绑定 图片路径时出现问题 解决过程 上网查说是webpack构建时识别不到,直接不单绑数据,写死试试看 解决方案 直接require导入图像文件模块

【C语言】VS的实用调试技巧

0. 前言 VS(Visual Studio)是集成开发环境,其内置了多种调试工具和技巧帮助开发人员在开发过程中解决问题。包含断点、监视窗口、自动窗口、调用堆栈等,通过这些技巧,开发人员可以有效地调试和解决程序中的问题。我们在VS编译器上写代码&…

yolov10在地平线旭日X3派上的部署和测试(Python版本和C++版本)

0、搭建开发环境 当前的测试根据一下的步骤并修改源码是可以实现yolov8的板端运行,如果不想再搭建环境和测试代码bug上浪费更多的时间可以直接获取本人的测试虚拟机,所有的测试代码、虚拟环境和板端测试工程以全部打包到了虚拟机,需要的可以…

微前端概念

微前端作用 大型应用程序的拆分独立的前端子应用降低程序复杂性&#xff0c;提高开发效率 微前端能力 js隔离css隔离元素隔离生命周期预加载数据通信应用跳转多层嵌套… 微前端实现方案 IframeSingle-spaQiankunMicro-app Iframe <iframe src"https://www.examp…

【优秀python web设计】基于Python flask的猫眼电影可视化系统,可视化用echart,前端Layui,数据库用MySQL,包括爬虫

1 绪论 1.1 设计背景及目的 猫眼电影作为国内知名的电影信息网站&#xff0c;拥有海量的电影信息、票房数据和用户评价数据。这些数据对于电影市场的研究和分析具有重要意义。然而&#xff0c;由于数据的复杂性和数据来源的多样性&#xff0c;如何有效地采集、存储和展示这些数…

巴黎OSGB倾斜摄影数据详细介绍

北京时间7月27日&#xff0c;第33届夏季奥林匹克运动会开幕式在法国巴黎举行&#xff0c;巴黎成为继伦敦后&#xff0c;第二个三度举办夏季奥运会的城市&#xff0c;此次为法国相隔100年后再次举办夏季奥运会&#xff0c;前两次分别在1900年及1924年。开幕式上&#xff0c;巴黎…

Shader入门精要总结(二)矩阵

1. 矩阵乘法 一个rn的矩阵A和一个nc的矩阵B相乘&#xff0c;它们的结果AB将会是一个rc大小的矩阵&#xff0c;不满足此规则不能相乘 矩阵乘法满足一些性质 矩阵乘法不满足交换律 即AB≠BA矩阵乘法满足结合律 (AB)CA(BC) 2. 特殊矩阵 方块矩阵 指行和列数目相等的矩阵&#…

【WEB安全】 PHP基础文件知识完整教学中(超详细)

文章目录​​​​​​​ 1.PHP 文件处理 PHP 操作文件 PHP 文件打开/读取/关闭 ​​​​​​​文件的 复制 删除 重名 ​​​​​​​文件的判断 2.PHP获取文件属性 3.PHP目录操作 4.命名空间 PHP 命名空间可以解决以下两类问题&#xff1a; 5.正则表达式 正则表达…