RAG实践:ES混合搜索BM25+kNN(cosine)

news2024/9/21 22:28:22

1 缘起

最近在研究与应用混合搜索,
存储介质为ES,ES作为大佬牌数据库,
非常友好地支持关键词检索和向量检索,
当然,支持混合检索(关键词检索+向量检索),
是提升LLM响应质量RAG(Retrieval-augmented Generation)的一种技术手段,
那么,如何通过ES实现混合搜索呢?
请看本篇文章。

本系列分为两大部分:实践理论
先讲实践,应对快速开发迭代,可快速上手实践;
再讲理论,应对优化,如归一化。

RAG理论:ES混合搜索BM25+kNN(cosine)以及归一化https://blog.csdn.net/Xin_101/article/details/140237669

在这里插入图片描述

2 实践

2.1 环境准备

2.1.1 部署ES

  • 下载ES镜像:8.12.2版本
docker pull docker.elastic.co/elasticsearch/elasticsearch:8.12.2
  • 下载ik分词器
    https://github.com/infinilabs/analysis-ik/releases
    选择与ES版本一致或者可用的版本,这里选择8.12.2版本分词器。

在这里插入图片描述

  • 添加分词器
    将分词器文件添加到目录:/home/xindaqi/data/es-8-12-2/plugins
    新建分词器文件夹:mkdir -p /home/xindaqi/data/es-8-12-2/plugins/ik_analyzer_8.12.2
    将zip文件复制到文件夹:ik_analyzer_8.12.2

  • 启动ES

docker run -dit \
--restart=always \
--name es01-8-12-2 \
-p 9200:9200 \
-p 9300:9300 \
-v /home/xindaqi/data/es-8-12-2/data:/usr/share/elasticsearch/data \
-v /home/xindaqi/data/es-8-12-2/logs:/usr/share/elasticsearch/logs \
-v /home/xindaqi/data/es-8-12-2/plugins:/usr/share/elasticsearch/plugins \
-e ES_JAVA_OPS="-Xms512m -Xmx1g" \
-e discovery.type="single-node" \
-e ELASTIC_PASSWORD="admin-es" \
-m 1GB \
docker.elastic.co/elasticsearch/elasticsearch:8.12.2

2.1.2 数据准备

实践之前,需要准备数据,包括索引和索引中存储的数据。
为了演示混合搜索,这里创建两种类型的数据:text和dense_vector。

(1)创建索引
curl -X 'PUT' \
  'http://localhost:9200/vector_5' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Basic ZWxhc3RpYzphZG1pbi1lcw==' \
  -d '{
    "settings": {
		"index": {
			"number_of_shards": 1,
			"number_of_replicas": 1,
			"refresh_interval": "3s"
		}
	},
	"mappings": {
		"properties": {
			"dense_values": {
				"type": "dense_vector",
				"dims": 5,
				"index": true,
				"similarity": "cosine"
			},
			"id": {
				"type": "keyword"
			},
			"ik_text": {
				"type": "text",
        "analyzer": "ik_max_word"
			},
      "default_text": {
				"type": "text"
			},
			"timestamp": {
				"type": "long"
			},
			"dimensions": {
				"type": "integer"
			}
		}
	}
}'
(2)新建数据

新建两条数据:

curl -X POST 'http://localhost:9200/vector_5/_doc/1' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic ZWxhc3RpYzphZG1pbi1lcw==' \
--data '{
    "dense_values": [0.1, 0.2, 0.3, 0.4, 0.5],
    "id": "1",
    "ik_text": "今天去旅游了",
    "default_text":"今天去旅游了",
    "timestamp": 1715659103373,
    "dimensions": 5
}'

curl -X POST 'http://localhost:9200/vector_5/_doc/2' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic ZWxhc3RpYzphZG1pbi1lcw==' \
--data '{
    "dense_values": [0.1, 0.2, 0.3, 0.4, 0.5],
    "id": "1",
    "ik_text": "好美的太阳",
    "default_text":"好美的太阳",
    "timestamp": 1715659103373,
    "dimensions": 5
}'

2.2 向量搜索

kNN搜索

ES中向量搜索使用k-Nearest Neighbor(k最近邻分类算法)进行搜索。
输入的请求参数如下:

参数参数描述
knn向量搜索k-Nearest Neighbor
field向量字段名称
query_vector向量值
k召回结果数量
num_candidates召回范围,每个分片选取的数量

请求样例如下:
由样例可知,存储向量数据的字段名称为:dense_values,填充向量值字段为query_vector(为固定属性),召回结果k为3个,每个分片选择100条数据(num_candidates),最大值为:10000。
实际应用过程中,又有向量数据较多(依据维度而定),为节约内存,检索时,在结果中排除,excludes。

curl -X POST 'http://localhost:9200/vector_5/_search' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic ZWxhc3RpYzphZG1pbi1lcw==' \
--data '{
  "knn": {
    "field": "dense_values",
    "query_vector": [
      0.1,
      0.1,
      0.1,
      0.1,
      0.1
    ],
    "k": 3,
    "num_candidates": 100
  },
  "_source": {
    "excludes": [
      "dense_values"
    ]
  }
}'

检索结果如下,
由于创建过程中使用的向量数据相同,因此计算的结果也是相同的,
使用

{
    "took": 2,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 0.8427159,
        "hits": [
            {
                "_index": "vector_5",
                "_id": "1",
                "_score": 0.8427159,
                "_source": {
                    "id": "1",
                    "ik_text": "今天去旅游了",
                    "default_text": "今天去旅游了",
                    "timestamp": 1715659103373,
                    "dimensions": 5
                }
            },
            {
                "_index": "vector_5",
                "_id": "2",
                "_score": 0.8427159,
                "_source": {
                    "id": "1",
                    "ik_text": "好美的太阳",
                    "default_text": "好美的太阳",
                    "timestamp": 1715659103373,
                    "dimensions": 5
                }
            }
        ]
    }
}

2.2 混合搜索

混合搜索即将搜索拆分成多个部分,每个部分使用不同的权重,实现混合搜索的效果。
ES中使用boost参数来分配不同部分的权重,搜索案例如下。
由案例可知,混合搜索使用关键词+向量搜索,关键词b1与向量总权重b2,其中b1+b2=1,
案例中关键词权重为0.6,向量权重0.4,
关键词搜索将搜索的内容映射到query上,权重映射到boost上,
default_text为实际存储的属性名称。

curl -X POST 'http://localhost:9200/vector_5/_search' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic ZWxhc3RpYzphZG1pbi1lcw==' \
--data '{
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "default_text": {
                            "query": "好美的太阳",
                            "boost": 0.6
                        }
                    }
                }
            ]
        }
    },
    "knn": {
        "field": "dense_values",
        "query_vector": [
           0.1,
           0.1,
           0.1,
           0.1,
           0.1
        ],
        "k": 3,
        "num_candidates": 100,
        "boost": 0.4
    },
    "_source": {
        "excludes": [
            "dense_values"
        ]
    }
}'

3 小结

(1)ES混合搜索:通过boost配置比例,其中,关键词计算使用BM25计算分数,同时加入boost参数;
(2)关键词搜索boost基础比例为2.2,计算过程boost=2.2boost;
(3)向量搜索的最终分数为:final_score=boost
kNN。

计算过程参见文章:RAG理论:ES混合搜索BM25+kNN(cosine)以及归一化
https://blog.csdn.net/Xin_101/article/details/140237669

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

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

相关文章

【JS|第21期】JavaScript模块化:深入解析三种文件暴露方式

日期:2024年7月6日 作者:Commas 签名:(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释:如果您觉得有所帮助,帮忙点个赞,也可以关注我,我们一起成长;如果有不对的地方,还望各位大佬不吝赐教,谢谢^ - ^ 1.01365 = 37.7834;0.99365 = 0.0255 1.02365 = 1377.4083…

Portainer工具

Portainer是一款免费、开源的Docker的图形化管理工具,其能够提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作(包括上传下载镜像,创建容器等操作)、事件日志显示、容器控制台操作、Swarm集群和服务等集中管理和…

ST Smart Things Sentinel:一款针对复杂IoT协议的威胁检测工具

关于ST Smart Things Sentinel ST Smart Things Sentinel,简称ST,是一款功能强大的安全工具,广大研究人员可以使用该工具检测物联网 (IoT) 设备使用的复杂协议中的安全威胁。 在不断发展的联网设备领域,ST Smart Things Sentinel…

揭秘反向沙箱:企业网络安全的终极防线

通常,我们讨论的沙箱环境分为正向沙箱和反向沙箱。那么什么正向沙盒反向沙盒到底是什么呢? 正向沙箱通常用于分析来自外部的未知文件、电子邮件附件、网页内容等,以检测其中是否包含恶意软件或有害代码。这种沙箱通常位于企业的防火墙之外&am…

鸿蒙next 下拉刷新上来加载 来了 我不允许你不会

前言 各位同学大家好, 有段时间没有给大家更新文章了 ,最近在开发 鸿蒙next中 有用到这个下拉刷新和上来加载的功能就准备写个文章分享一下 那么废话不多说 我们正式开始: 效果图 准备工作: 找到我们DevEco studio 的安装位置 找到我们ohpm 的bin目录 配置在环境变了中 …

Plotly.js带颜色比例的轮廓图

本文由ScriptEcho平台提供技术支持 项目地址:传送门 Plotly.js Contour Plot with Color Scale 应用场景 Contour plot 是一种可视化数据分布的图表,常用于气象学、地球物理学和医学成像等领域。它通过绘制等值线来展示数据的变化,帮助用…

Flink异常:org/apache/hadoop/hive/ql/parse/SemanticException

在flink项目中跑 上面这段代码出现如下这个异常&#xff0c; java.lang.NoClassDefFoundError: org/apache/thrift/TException 加上下面这个依赖后不报错 <dependency> <groupId>org.apache.thrift</groupId> <artifactId>libthrift</artifactId…

水库大坝安全监测险情应对措施

汛期暴雨洪涝灾害发生后&#xff0c;为保证大坝及下游人民生命财产安全&#xff0c;应及时进行大坝安全现场检查和快速评估。评估内容包括大坝沉降和水平变形、裂缝、坝坡是否塌滑、下游坡是否存在集中渗漏或大面积渗水、溢洪道启闭设备能否正常运行、近坝库岸是否有大的滑坡体…

[激光原理与应用-110]:南京科耐激光-激光焊接-焊中检测-智能制程监测系统IPM介绍 - 13 - 德擎激光焊接在线缺陷检测系统 WDD详解解析

目录 一、产品简介 1.1 概述 1.2 多光学信号传感器 &#xff08;1&#xff09;外观 &#xff08;2&#xff09;消费电子行业应用 1.3 IO信号处理模块/可编程控制模块 1.4 操作系统分析软件 1.5 检测原理分析 二、硬件原理 2.1 系统架构与电路接口 2.2 多光学信号传感…

链路聚合概述

技术背景&#xff1a; 随着网络规模不断扩大&#xff0c;人们对骨干链路的带宽吞吐量与可靠性提出了越来越高的要求。根据传统的方案&#xff0c;只能将当前链路更换为更高速的链路。但是更换链路需要付出较高的成本费用&#xff0c;而且灵活性差&#xff0c;因此我们需要探索…

ERROR: No matching distribution found for matplotlib

1.问题&#xff1a;安装matplotlib报错&#xff0c;如下图所示&#xff1a; 2.通过换源&#xff0c;输入以下命令&#xff1a;python -m pip install matplotlib -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com&#xff0c;但是还是无效 3.在pycharm中升级…

OpenHarmony 入门——ArkUI自定义组件的基础语法(一)

文章大纲 引言一、自定义组件的基本语法1、Component 装饰器 和 Entry 装饰器2、build函数3、Reuseable4、定义成员函数/变量 二、自定义组件的使用 引言 在OpenHarmony 系统里ArkUI子系统显示的内容均为组件&#xff0c;由框架直接提供的称为系统组件&#xff0c;由开发者定义…

本地服务器部署外网可访问地址

一、开放服务器端口 &#xff08;1&#xff09;打开【控制面板】-【系统和安全】-【防火墙】-【高级设置】 &#xff08;2&#xff09;右键【新建规则】-【端口】-【程序&#xff1a;所有程序】-【操作&#xff1a;允许连接】-【配置文件&#xff1a;默认】-【名称&#xff1a;…

Customize-A-Video:文生视频自由定制

视频领域&#xff0c;尤其是文本到视频&#xff08;T2V&#xff09;扩散模型中的动作定制&#xff0c;尚未得到充分研究。来自马里兰大学、Adobe Research 和延世大学的研究团队提出了一种名为“Customize-A-Video”的新方法&#xff0c;本方法通过单一参考视频对动作进行建模&…

20240713 每日AI必读资讯

&#x1f697; 烧钱抢老司机饭碗&#xff1f;“萝卜快跑”事件辟谣 - 武汉相关负责人辟谣&#xff1a;无人车不是1000辆&#xff0c;只有400多辆 - “萝卜快跑”自动驾驶车可以通过单车智能、多重安全系统冗余保障以及5G云代驾平行驾驶三重冗余保障&#xff0c;确保自动驾驶…

vue学习day07-scoped样式冲突、data是一个函数、props详解、组件通信、非父子通信-event bus 事件总线

19、scoped样式冲突 &#xff08;1&#xff09;默认情况&#xff1a;写在组件中的样式会全局生效&#xff0c;因此会很容易造成多个组件之间的样式冲突问题。 1&#xff09;全局样式&#xff1a;默认组件中的样式会作用到全局 比如&#xff1a; 当只有box1设置边框时&#…

外贸国际短信群发工具的开发源代码!

在外贸行业中&#xff0c;快速、准确地与客户进行沟通是业务成功的关键之一&#xff0c;随着科技的不断进步&#xff0c;国际短信群发工具成为了外贸从业者不可或缺的工具。 本文将通过科普五段源代码&#xff0c;带您深入了解外贸国际短信群发工具的开发原理和实现过程。 一…

【题目/训练】回溯算法练习

&#x1f342;八皇后 二进制来表示。 #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <unordered_map> using namespace std;int n; #define MASK(n) ((1<<(n1))-2) //如 6 得到的是1000 0000 …

阐述 C 语言中的参数传递机制

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01; &#x1f4d9;C 语言百万年薪修炼课程 通俗易懂&#xff0c;深入浅出&#xff0c;匠心打磨&#xff0c;死磕细节&#xff0c;6年迭代&#xff0c;看过的人都说好。 文章目…

谷粒商城踩坑记录-网关服务启动报错

文章目录 一&#xff0c;错误表现二&#xff0c;错误原因三&#xff0c;解决方案1&#xff0c;排除无关依赖2&#xff0c;调整依赖关系 一&#xff0c;错误表现 在启动Spring Cloud Gateway服务时&#xff0c;控制台输出了一系列错误信息&#xff0c;指出应用程序未能成功启动…