es-将知识库中的数据转换为向量存储到es并进行相似性检索

目录

为什么要将数据转为向量存入es?

数据准备

创建索引库

向量存储

验证


为什么要将数据转为向量存入es?

我之前把数据作为文档存入 ES,主要用于全文检索(BM25 算法),但是它不适合语义匹配,比如如果用户输入的是“求解 x² - 5x + 6 = 0”,但我的文档是“二次方程求解方法”,ES 可能不会返回这个文档,因为它不包含完全匹配的关键词。

而如果将数据作为向量存入ES(语义搜索),则可以查找语义相似的内容。

数据准备

我这里准备包含250条数学文档的csv文件:

需要检查该文件的编码格式,用文本的方式打开该文件,如果不是utf-8,则另存为,并指定编码格式为utf-8,在改了编码格式后,再用excel打开,可能会变为乱码,不用管,只要保证编码为utf-8,且用文本打开能正常显示就行。

创建索引库

我使用的es版本为7.12.1

打开devtools工具,创建一个名为math_index的索引库

PUT /math_index
{"settings": {"number_of_shards": 3,"number_of_replicas": 1},"mappings": {"properties": {"ask_vector": {  "type": "dense_vector",  "dims": 1024  },"ask": {  "type": "text","analyzer": "ik_max_word","search_analyzer": "ik_smart"},"answer": {  "type": "text","analyzer": "ik_max_word","search_analyzer": "ik_smart"}}}
}

1. 索引设定 (settings)

  • number_of_shards: 3:该索引被分成 3 个分片,提高查询和索引的吞吐量。
  • number_of_replicas: 1:每个主分片有 1 个副本,提高数据的可用性和容错性。

2. 字段映射 (mappings)

  • ask_vector
    • 类型为 dense_vector,维度为 1024,用于存储文本的向量表示(通常用于语义搜索,如基于向量相似度的检索)。
  • ask
    • 类型为 text,用于存储用户问题文本。
    • analyzer: "ik_max_word":索引时使用 ik_max_word(细粒度分词)。
    • search_analyzer: "ik_smart":搜索时使用 ik_smart(较粗粒度分词,提升搜索效率)。
  • answer
    • 类型为 text,用于存储回答文本。
    • 同样采用 ik_max_word 进行索引,ik_smart 进行搜索。

向量存储

from elasticsearch import Elasticsearch
from transformers import BertTokenizer, BertModel
import torch
import pandas as pddef embeddings_doc(doc, tokenizer, model, max_length=300):encoded_dict = tokenizer.encode_plus(doc,add_special_tokens=True,max_length=max_length,padding='max_length',truncation=True,return_attention_mask=True,return_tensors='pt')input_id = encoded_dict['input_ids']attention_mask = encoded_dict['attention_mask']# 前向传播with torch.no_grad():outputs = model(input_id, attention_mask=attention_mask)# 提取最后一层的CLS向量作为文本表示last_hidden_state = outputs.last_hidden_statecls_embeddings = last_hidden_state[:, 0, :]return cls_embeddings[0]def add_doc(index_name, id, embedding_ask, ask, answer, es):body = {"ask_vector": embedding_ask.tolist(),"ask": ask,"answer": answer}result = es.create(index=index_name, id=id, doc_type="_doc", body=body)return resultdef main():# 模型下载的地址model_name = 'D:\\model\\chinese-roberta-wwm-ext-large'# ES 信息es_host = "http://your_ip"es_port = 9200es_user = ""es_password = ""index_name = "math_index"# 数据地址path = "D:\\Downloads\\知识库1.4.csv"# 分词器和模型tokenizer = BertTokenizer.from_pretrained(model_name)model = BertModel.from_pretrained(model_name)# ES 连接es = Elasticsearch([es_host],port=es_port,http_auth=(es_user, es_password))# 读取数据写入ESdata = pd.read_csv(path, encoding='utf-8')for index, row in data.iterrows():ask = row["题目"]answer = row["答案"]# 文本转向量embedding_ask = embeddings_doc(ask, tokenizer, model)result = add_doc(index_name, index, embedding_ask, ask, answer, es)print(result)if __name__ == '__main__':main()

里面的模型文件在这里下载:

https://huggingface.co/hfl/chinese-roberta-wwm-ext-large/

把这几个文件下载下来,放到一个文件夹中:

然后运行脚本就可以了。(这里的es依赖用到7.12.1版本:pip install elasticsearch==7.12.1 -i https://pypi.tuna.tsinghua.edu.cn/simple)

运行结束后,es就存储了知识库数据以及生成的向量:

验证

这里使用余弦相似度进行相似性检索

from elasticsearch import Elasticsearch
from transformers import BertTokenizer, BertModel
import torchdef embeddings_doc(doc, tokenizer, model, max_length=300):encoded_dict = tokenizer.encode_plus(doc,add_special_tokens=True,max_length=max_length,padding='max_length',truncation=True,return_attention_mask=True,return_tensors='pt')input_id = encoded_dict['input_ids']attention_mask = encoded_dict['attention_mask']# 前向传播with torch.no_grad():outputs = model(input_id, attention_mask=attention_mask)# 提取最后一层的CLS向量作为文本表示last_hidden_state = outputs.last_hidden_statecls_embeddings = last_hidden_state[:, 0, :]return cls_embeddings[0]def search_similar(index_name, query_text, tokenizer, model, es, top_k=3):query_embedding = embeddings_doc(query_text, tokenizer, model)print(query_embedding.tolist())query = {"query": {"script_score": {"query": {"match_all": {}},"script": {"source": "cosineSimilarity(params.queryVector, 'ask_vector') + 1.0","lang": "painless","params": {"queryVector": query_embedding.tolist()}}}},"size": top_k}res = es.search(index=index_name, body=query)hits = res['hits']['hits']similar_documents = []for hit in hits:similar_documents.append(hit['_source'])return similar_documentsdef main():# 模型下载的地址model_name = 'D:\\model\\chinese-roberta-wwm-ext-large'# ES 信息es_host = "http://your_ip"es_port = 9200es_user = ""es_password = ""index_name = "math _index"# 分词器和模型tokenizer = BertTokenizer.from_pretrained(model_name)model = BertModel.from_pretrained(model_name)# ES 连接es = Elasticsearch([es_host],port=es_port,http_auth=(es_user, es_password))query_text = "在复平面内,(1+3i)(3-i) 对应的点位于哪个象限"similar_documents = search_similar(index_name, query_text, tokenizer, model, es)for item in similar_documents:print("================================")print('ask:', item['ask'])print('answer:', item['answer'])if __name__ == '__main__':main()

得到的结果(找到的相似度前十的数据):

可以看到,第一个数据确实最为相似。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【资料分享】全志科技T113-i全国产(1.2GHz双核A7 RISC-V)工业核心板规格书

核心板简介 创龙科技SOM-TLT113 是一款基于全志科技T113-i 双核ARM Cortex-A7 玄铁C906 RISC-V HiFi4 DSP 异构多核处理器设计的全国产工业核心板,ARM Cortex-A7 处理单元主频高达1.2GHz。核心板 CPU、ROM、RAM、电源、晶振等所有元器件均采用国产工业级方案&…

wepy微信小程序自定义底部弹出框功能,显示与隐藏效果(淡入淡出,滑入滑出)

视图html部分 <view class"salePz"><view class"btnSelPz" tap"pzModelClick">去选择</view><!-- modal --><view class"modal modal-bottom-dialog" hidden"{{hideFlag}}"><view class&q…

基于Springboot+Typst的PDF生成方案,适用于报告打印/标签打印/二维码打印等

基于SpringbootTypst的PDF生成方案&#xff0c;适用于报告打印/标签打印/二维码打印等。 仅提供后端实现 Typst2pdf-for-report/label/QR code github 环境 JDK11linux/windows/mac 应用场景 适用于定制化的报告模板/标签/条码/二维码等信息的pdf生成方案。通过浏览器的p…

leetcode每日一题:使字符串平衡的最小交换次数

引言 今天开始&#xff0c;打算做一个新的系列&#xff1a;leetcode每日一题的题解。预期每天用90分钟的时间&#xff0c;去写一篇当天的每日一题的题解&#xff0c;这个目标跟早起结合在一起&#xff0c;才有足够的时间完成。其实早在前几年&#xff0c;就开始断断续续做leetc…

Learn Redis 5 (Java)

分布式锁 在面对高并发业务时&#xff0c;单个项目解决不过来&#xff0c;此时一个项目部署到多个机器&#xff0c;这就是集群模式&#xff0c;不同的项目实例就会对应不同的端口和JVM。 1.模拟集群模式 Nginx实现负载均衡&#xff08;轮询&#xff09; 2.使用集群模…

lua学习(三)

错误处理 assert断言 作用&#xff1a;确保某些数据是符合预期的&#xff0c;避免影响最终结果。 格式&#xff1a;assert(条件语句&#xff0c;报错信息) 当条件语句为true时&#xff0c;assert语句不会有任何行为&#xff0c;但是当为false时&#xff0c;assert会将报错信息…

基于eNSP的IPV4和IPV6企业网络规划

基于eNSP的IPV4和IPV6企业网络规划 前言网络拓扑设计功能设计技术详解一、网络设备基础配置二、虚拟局域网&#xff08;VLAN&#xff09;与广播域划分三、冗余协议与链路故障检测四、IP地址自动分配与DHCP相关配置五、动态路由与安全认证六、广域网互联及VPN实现七、网络地址转…

优选算法合集————双指针(专题四)

1&#xff0c;一维前缀和模版 题目描述&#xff1a; 描述 给定一个长度为n的数组a1,a2,....ana1​,a2​,....an​. 接下来有q次查询, 每次查询有两个参数l, r. 对于每个询问, 请输出alal1....aral​al1​....ar​ 输入描述&#xff1a; 第一行包含两个整数n和q. 第二行…

Web3游戏行业报告

一&#xff0c;gamefi经济 什么是gamefi GameFi是一个缩写&#xff0c;它结合了游戏和去中心化金融(“DeFi”)这两个术语&#xff0c;关注的是游戏玩法如何在去中心化系统中实现货币化。对于游戏而言&#xff0c;只要开放了交易市场&#xff0c;允许玩家自由买卖&#xff0c;…

【程序人生】成功人生架构图(分层模型)

文章目录 ⭐前言⭐一、根基层——价值观与使命⭐二、支柱层——健康与能量⭐三、驱动层——学习与进化⭐四、网络层——关系系统⭐五、目标层——成就与财富⭐六、顶层——意义与传承⭐外层&#xff1a;调节环——平衡与抗风险⭐思维导图 标题详情作者JosieBook头衔CSDN博客专家…

拖拽实现+摇杆实现

拖拽实现 拖拽事件实现: 半透明渐变贴图在ios设备下&#xff0c;使用压缩会造成图片质量损失&#xff0c;所以可以将半透明渐变UI切片单独制作真彩色图集 拖拽事件组 IBeginDragHandler:检测到射线后&#xff0c;当拖拽动作开始时执行一次回调函数 IDragHandler:拖拽开始后&a…

vs2017版本与arcgis10.1的ArcObject SDK for .NET兼容配置终结解决方案

因电脑用的arcgis10.1,之前安装的vs2010正常能使用AO和AE&#xff0c;安装vs2017后无法使用了&#xff0c;在重新按照新版本arcgis engine或者arcObject费时费力&#xff0c;还需要重新查找资源。 用vs2017与arc10.1的集成主要两个问题&#xff0c;1&#xff1a;安装后vs中没有…

C语言和C++到底有什么关系?

C 读作“C 加加”&#xff0c;是“C Plus Plus”的简称。 顾名思义&#xff0c;C 就是在 C 语言的基础上增加了新特性&#xff0c;玩出了新花样&#xff0c;所以才说“Plus”&#xff0c;就像 Win11 和 Win10、iPhone 15 和 iPhone 15 Pro 的关系。 C 语言是 1972 年由美国贝…

企业微信群聊机器人开发

拿到机器人hook 机器人开发文档 https://developer.work.weixin.qq.com/document/path/91770

AT指令集-NBIOT

是什么&#xff1f; 窄带物联网&#xff08;Narrow Band Internet of Things, NB-IoT&#xff09;成为万物互联网络的一个重要分支支持低功耗设备在广域网的蜂窝数据连接&#xff0c;也被叫作低功耗广域网(LPWAN)NB-IoT支持待机时间长、对网络连接要求较高设备的高效连接NB-Io…

网络爬虫【爬虫库urllib】

我叫不三不四&#xff0c;很高兴见到大家&#xff0c;欢迎一起学习交流和进步 今天来讲一讲爬虫 urllib介绍 Urllib是Python自带的标准库&#xff0c;无须安装&#xff0c;直接引用即可。 Urllib是一个收集几个模块来使用URL的软件包&#xff0c;大致具备以下功能。 ● urlli…

vue中js简单创建一个事件中心/中间件/eventBus

vue中js简单创建一个事件中心/中间件/eventBus 目录结构如下&#xff1a; eventBus.js class eventBus {constructor() {this.events {};}// 监听事件on(event, callback) {if (!this.events[event]) {this.events[event] [];}this.events[event].push(callback);}// 发射…

弹球小游戏-简单开发版

一、需求 弹球小游戏是一个简单的互动游戏&#xff0c;玩家需要控制一个挡板在窗口底部左右移动&#xff0c;以接住从上方落下的球。游戏的主要需求包括&#xff1a; (1) 游戏界面 &#xff1a;创建一个指定尺寸的游戏窗口&#xff0c;显示球和挡板。 (2) 球的运动 &#xf…

Cursor与Blender-MCP生成3D模型

随着DeepSeek的热度&#xff0c;各行各业接入AI智能&#xff0c;当然作为一个深受3D爱好者喜爱的软件——Blender&#xff0c;也接入了AI智能&#xff0c;通过Blender-MCP&#xff0c;开启一场Blender的智能化模型创建的世界之旅。 目录 1.准备工作2.环境配置2.1 Mac安装2.2 W…

简单以太网配置

display arp //查看路由器mac地址 交换机配置命令&#xff1a; system-view // 从用户视图进入系统视图 dis mac-address //查看mac地址表 路由器配置命令: system-view // 从用户视图进入系统视图 int GigabitEthernet 0/0/0 //进入G口 0/0/0 进入之后配置网关: ip addre…