RAG词嵌入召回质量评估

一、目录

1 采用官方评估器进行评估
2 Open Ai的key分享
3 采用gpt 生成词嵌入的训练集
4 微调sentence_transformer模型
5 评估sentence_transformer模型

二、实现

官方网址:https://github.com/run-llama/finetune-embedding/blob/main/evaluate.ipynb
1.采用官方评估器进行评估
数据集格式:

datasets={"corpus":[{uuid1:doc1},{uuid2:doc2},{uuid3:doc3}       #对应的文本id、文本            ],"queries":[{uuid1:问题},{uuid2:问题},...     ],"relevant_docs":[{uuid1:[uuid答案]},{uuid2:[uuid答案]},{uuid3:[uuid答案]}            ]
}
from sentence_transformers.evaluation import InformationRetrievalEvaluator
from sentence_transformers import SentenceTransformer
def evaluate_st(dataset,model_id,name,
):corpus = dataset['corpus']queries = dataset['queries']relevant_docs = dataset['relevant_docs']evaluator = InformationRetrievalEvaluator(queries, corpus, relevant_docs, name=name)     #评估器model = SentenceTransformer(model_id)       #加载模型return evaluator(model, output_path='results/')bge="C:/Users/86188/Downloads/bge-small-en"
evaluate_st(val_dataset, bge, name='bge')
bge="bge"
dfs=pd.read_csv(f"./results/Information-Retrieval_evaluation_{bge}_results.csv")
print(dfs)

注:具体见下文5
2. Open Ai的key分享
参考:https://blog.csdn.net/qq_32265503/article/details/130471485

1 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
2 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
3 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
4 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
5 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
6 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
7 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
8 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
9 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
10 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
11 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
12 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
13 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
14 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
15 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
16 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
17 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
18 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
19 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
  1. 采用gpt 生成词嵌入的训练集(本人并未购买openAI对应的key)
import json
from llama_index import SimpleDirectoryReader
from llama_index.node_parser import SimpleNodeParser
from llama_index.schema import MetadataMode#加载pdf 文件
def load_corpus(files, verbose=False):if verbose:print(f"Loading files {files}")reader = SimpleDirectoryReader(input_files=files)docs = reader.load_data()if verbose:print(f'Loaded {len(docs)} docs')parser = SimpleNodeParser.from_defaults()nodes = parser.get_nodes_from_documents(docs, show_progress=verbose)if verbose:print(f'Parsed {len(nodes)} nodes')corpus = {node.node_id: node.get_content(metadata_mode=MetadataMode.NONE) for node in nodes}return corpusTRAIN_FILES = ['C:/Users/86188/Downloads/智能变电站远程可视化运维与无人值守技术研究与实现_栾士岩.pdf']
VAL_FILES = ['C:/Users/86188/Downloads/基于人工智能的核电文档知识管理探索与实践_詹超铭.pdf']
train_corpus = load_corpus(TRAIN_FILES, verbose=True)      #加载文章
val_corpus = load_corpus(VAL_FILES, verbose=True)# #保存文本文件
TRAIN_CORPUS_FPATH = './data/train_corpus.json'
VAL_CORPUS_FPATH = './data/val_corpus.json'
with open(TRAIN_CORPUS_FPATH, 'w+') as f:json.dump(train_corpus, f)with open(VAL_CORPUS_FPATH, 'w+') as f:json.dump(val_corpus, f)import re
import uuid
from llama_index.llms import OpenAI
from llama_index.schema import MetadataMode
from tqdm.notebook import tqdm#加载数据集
with open(TRAIN_CORPUS_FPATH, 'r+') as f:train_corpus = json.load(f)with open(VAL_CORPUS_FPATH, 'r+') as f:val_corpus = json.load(f)import os
os.environ["OPENAI_API_KEY"] ="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"
# 采用gpt 3.5 生成训练集def generate_queries(corpus,num_questions_per_chunk=2,prompt_template=None,verbose=False,
):"""Automatically generate hypothetical questions that could be answered withdoc in the corpus."""llm = OpenAI(model='gpt-3.5-turbo')prompt_template = prompt_template or """\Context information is below.---------------------{context_str}---------------------Given the context information and not prior knowledge.generate only questions based on the below query.You are a Teacher/ Professor. Your task is to setup \{num_questions_per_chunk} questions for an upcoming \quiz/examination. The questions should be diverse in nature \across the document. Restrict the questions to the \context information provided.""""queries = {}relevant_docs = {}for node_id, text in tqdm(corpus.items()):query = prompt_template.format(context_str=text, num_questions_per_chunk=num_questions_per_chunk)print(query)response = llm.complete(query)       #生成答案result = str(response).strip().split("\n")questions = [re.sub(r"^\d+[\).\s]", "", question).strip() for question in result]questions = [question for question in questions if len(question) > 0]for question in questions:question_id = str(uuid.uuid4())queries[question_id] = questionrelevant_docs[question_id] = [node_id]return queries, relevant_docs'''自动生成训练数据集'''train_queries, train_relevant_docs = generate_queries(train_corpus)
val_queries, val_relevant_docs = generate_queries(val_corpus)TRAIN_QUERIES_FPATH = './data/train_queries.json'
TRAIN_RELEVANT_DOCS_FPATH = './data/train_relevant_docs.json'
VAL_QUERIES_FPATH = './data/val_queries.json'
VAL_RELEVANT_DOCS_FPATH = './data/val_relevant_docs.json'with open(TRAIN_QUERIES_FPATH, 'w+') as f:json.dump(train_queries, f)with open(TRAIN_RELEVANT_DOCS_FPATH, 'w+') as f:json.dump(train_relevant_docs, f)with open(VAL_QUERIES_FPATH, 'w+') as f:json.dump(val_queries, f)with open(VAL_RELEVANT_DOCS_FPATH, 'w+') as f:json.dump(val_relevant_docs, f)'''生成的数据转为标准格式'''
TRAIN_DATASET_FPATH = './data/train_dataset.json'
VAL_DATASET_FPATH = './data/val_dataset.json'train_dataset = {'queries': train_queries,'corpus': train_corpus,'relevant_docs': train_relevant_docs,
}val_dataset = {'queries': val_queries,'corpus': val_corpus,'relevant_docs': val_relevant_docs,
}with open(TRAIN_DATASET_FPATH, 'w+') as f:json.dump(train_dataset, f)with open(VAL_DATASET_FPATH, 'w+') as f:json.dump(val_dataset, f)
  1. 微调sentence_transformer模型
#加载模型
from sentence_transformers import SentenceTransformer
model_id = "BAAI/bge-small-en"
model = SentenceTransformer(model_id)import json
from torch.utils.data import DataLoader
from sentence_transformers import InputExampleTRAIN_DATASET_FPATH = './data/train_dataset.json'
VAL_DATASET_FPATH = './data/val_dataset.json'
BATCH_SIZE = 10with open(TRAIN_DATASET_FPATH, 'r+') as f:train_dataset = json.load(f)with open(VAL_DATASET_FPATH, 'r+') as f:val_dataset = json.load(f)dataset = train_datasetcorpus = dataset['corpus']
queries = dataset['queries']
relevant_docs = dataset['relevant_docs']examples = []
for query_id, query in queries.items():node_id = relevant_docs[query_id][0]text = corpus[node_id]example = InputExample(texts=[query, text])examples.append(example)loader = DataLoader(examples, batch_size=BATCH_SIZE
)from sentence_transformers import losses
loss = losses.MultipleNegativesRankingLoss(model)from sentence_transformers.evaluation import InformationRetrievalEvaluatordataset = val_dataset
corpus = dataset['corpus']
queries = dataset['queries']
relevant_docs = dataset['relevant_docs']evaluator = InformationRetrievalEvaluator(queries, corpus, relevant_docs)#训练epoch 轮次
EPOCHS = 2
warmup_steps = int(len(loader) * EPOCHS * 0.1)
model.fit(train_objectives=[(loader, loss)],epochs=EPOCHS,warmup_steps=warmup_steps,output_path='exp_finetune',       #输出文件夹show_progress_bar=True,evaluator=evaluator,evaluation_steps=50,
)
  1. 评估sentence_transformer模型
import json
from tqdm.notebook import tqdm
import pandas as pd
pd.set_option("display.max_columns",None)
import logging
logging.basicConfig(level=logging.INFO,format="%(asctime)s-%(filename)s-%(message)s")
from llama_index import ServiceContext, VectorStoreIndex
from llama_index.schema import TextNode
from llama_index.embeddings import OpenAIEmbeddingimport os
os.environ["OPENAI_API_KEY"] ="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"'''加载数据集'''
TRAIN_DATASET_FPATH = './data/train_dataset.json'
VAL_DATASET_FPATH = './data/val_dataset.json'
with open(TRAIN_DATASET_FPATH, 'r+') as f:train_dataset = json.load(f)with open(VAL_DATASET_FPATH, 'r+') as f:val_dataset = json.load(f)'''召回方法'''
def evaluate(dataset,embed_model,top_k=5,verbose=False,
):corpus = dataset['corpus']                      #相关节点的文本集合queries = dataset['queries']                     #问题relevant_docs = dataset['relevant_docs']         #答案所在的文章#词向量模型service_context = ServiceContext.from_defaults(embed_model=embed_model)nodes = [TextNode(id_=id_, text=text) for id_, text in corpus.items()]    #将文本转换为张量index = VectorStoreIndex(nodes,service_context=service_context,show_progress=True)retriever = index.as_retriever(similarity_top_k=top_k)eval_results = []for query_id, query in tqdm(queries.items()):retrieved_nodes = retriever.retrieve(query)                        #召回向量retrieved_ids = [node.node.node_id for node in retrieved_nodes]    #检索到的节点id 列表expected_id = relevant_docs[query_id][0]                           #真值idis_hit = expected_id in retrieved_ids  # assume 1 relevant doceval_result = {'is_hit': is_hit,'retrieved': retrieved_ids,'expected': expected_id,'query': query_id,}eval_results.append(eval_result)return eval_results'''词向量召回,评估器'''
from sentence_transformers.evaluation import InformationRetrievalEvaluator
from sentence_transformers import SentenceTransformer
def evaluate_st(dataset,model_id,name,
):corpus = dataset['corpus']queries = dataset['queries']relevant_docs = dataset['relevant_docs']evaluator = InformationRetrievalEvaluator(queries, corpus, relevant_docs, name=name)     #评估器model = SentenceTransformer(model_id)       #模型return evaluator(model, output_path='results/')# openAI 自身的词嵌入模型的命中率
# ada = OpenAIEmbedding()
# ada_val_results = evaluate(val_dataset, ada)
# df_ada = pd.DataFrame(ada_val_results)
# hit_rate_ada = df_ada['is_hit'].mean()'''测试bge-small-en 检索的命中率'''
bge = "local:/home/jiayafei_linux/bge-small-en"
bge_val_results = evaluate(val_dataset, bge)
# #
# # #检索结果评估,命中率
# #
df_bge = pd.DataFrame(bge_val_results)
hit_rate_bge = df_bge['is_hit'].mean()
print(hit_rate_bge)
# #
bge="C:/Users/86188/Downloads/bge-small-en"
evaluate_st(val_dataset, bge, name='bge')bge="bge"
dfs=pd.read_csv(f"./results/Information-Retrieval_evaluation_{bge}_results.csv")
print(dfs)

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

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

相关文章

红日靶场5

目录 前言 外网渗透 信息收集 1、arp探测 2、nmap 3、nikto 4、whatweb 5、gobuster 6、dirsearch 漏洞探测 ThinKPHP漏洞 漏洞利用 get shell 内网渗透 信息收集 CS 启动! CS连接 CS信息收集 1、hashdump 2、猕猴桃 3、端口扫描 MSF启动&…

QT中程序执行时间精准计算的三种方法及对比

一.QT程序在提升程序性能的调试中经常要计算一段程序的执行时间&#xff0c;下面介绍两种简单的实现方式&#xff0c;精确度都可以达到ms。 1.方式一 &#xff08;1&#xff09;代码&#xff1a; #include <QDateTime> qDebug() << "Current_date_and_tim…

ubuntu server配置无线网络

1 配置文件 进入 Netplan 配置目录&#xff0c;查看其中的默认配置文件&#xff1a; $ cd /etc/netplan/ $ ls 50-cloud-init.yaml此机器上的配置文件名为 50-cloud-init.yaml。由于安装方式、系统版本等差异&#xff0c;配置文件的名称可能有所不同&#xff0c;但都是 yaml …

Git使用统一规范

为什么要统一git使用的风格&#xff1f; 统一的风格使我们在工作的时候无需考虑工作流程上该如何去做的问题&#xff0c;按照一个风格去做就好了每个人风格不同&#xff0c;格式凌乱&#xff0c;查看很不方便commit没有准确的message&#xff0c;后续难以追踪问题 git messag…

项目架构之Zabbix部署

1 项目架构 1.1 项目架构的组成 业务架构&#xff1a;客户端 → 防火墙 → 负载均衡&#xff08;四层、七层&#xff09; → web缓存/应用 → 业务逻辑&#xff08;动态应用&#xff09; → 数据缓存 → 数据持久层 运维架构&#xff1a;运维客户端 → 跳板机/堡垒机&#x…

JVM基础(4)——JVM存活判定算法

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 学习必须往深处挖&…

C++ 实现十大排序算法

教你手撕排序&#xff0c;这里有一个概念就是稳定排序。假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&#xff0c;若经过排序&#xff0c;这些记录的相对次序保持不变&#xff0c;即在原序列中&#xff0c;r[i]r[j]&#xff0c;且r[i]在r[j]之前&#…

第十三讲 单片机驱动彩色液晶屏 bin档的烧录方法

单片机驱动TFT彩色液晶屏系列讲座 目录 第一讲 单片机最小系统STM32F103C6T6通过RA8889驱动彩色液晶屏播放视频 第二讲 单片机最小系统STM32F103C6T6控制RA8889驱动彩色液晶屏硬件框架 第三讲 单片机驱动彩色液晶屏 控制RA8889软件:如何初始化 第四讲 单片机驱动彩色液晶屏 控…

Java生成四位数随机验证码

引言&#xff1a; 我们生活中登录的时候都要输入验证码&#xff0c;这些验证码是为了增加注册或者登录难度&#xff0c;减少被人用脚本疯狂登录注册导致的一系列危害&#xff0c;减少数据库的一些压力。 毕竟那些用脚本生成的账号都是垃圾账号 本次实践&#xff1a;生成这样的…

R语言【paleobioDB】——pbdb_scales():返回多个时间刻度的基本信息

Package paleobioDB version 0.7.0 paleobioDB 包在2020年已经停止更新&#xff0c;该包依赖PBDB v1 API。 可以选择在Index of /src/contrib/Archive/paleobioDB (r-project.org)下载安装包后&#xff0c;执行本地安装。 Usage pbdb_scales (...) Arguments 参数【...】&am…

CMake+QT+大漠插件的桌面应用开发

文章目录 CMakeQT大漠插件的桌面应用开发简介环境项目结构配置编译环境代码 CMakeQT大漠插件的桌面应用开发 简介 在CMake大漠插件的应用开发——处理dm.dll&#xff0c;免注册调用大漠插件中已经说明了如何免注册调用大漠插件&#xff0c;以及做了几个简单的功能调用&#x…

【STM32】STM32学习笔记-USART串口收发HEX和文本数据包(29)

00. 目录 文章目录 00. 目录01. 串口简介02. 串口收发HEX数据包接线图03. 串口收发HEX数据包示例104. 串口收发HEX数据包示例205. 串口收发文本数据包接线图06. 串口收发文本数据包示例07. 程序示例下载08. 附录 01. 串口简介 串口通讯(Serial Communication)是一种设备间非常…

itextpdf 之 html 转 pdf 问题处理

1. Font Provider contains zero fonts. At least one font shall be present 此问题出现的原因是 字体设置不成功&#xff0c;解决方法就是排查设置字体的代码。 需要特别注意的是项目打包后项目中所有文件层次会出现变动&#xff0c;使用何种方式获取字体文件会直接影响到字…

科研绘图(五)玫瑰图

柱状图的高级平替可视化 “玫瑰图”&#xff0c;通常也被称为“科克斯图”。它类似于饼图&#xff0c;但不同之处在于每个部分&#xff08;或“花瓣”&#xff09;的角度相同&#xff0c;半径根据它表示的值而变化。这种可视化工具对于周期性地显示信息非常有用&#xff0c;比…

Spring Boot 中批量执行 SQL 脚本的实践

在Spring Boot应用中&#xff0c;有时候我们需要批量执行存储在数据库中的 SQL 脚本。本文将介绍一个实际的案例&#xff0c;演示如何通过 Spring Boot、MyBatis 和数据库来实现这一目标。 0、数据库层 CREATE TABLE batchUpdate (id INT AUTO_INCREMENT PRIMARY KEY,update_…

TCP连接TIME_WAIT

TCP断开过程: TIME_WAIT的作用: TIME_WAIT状态存在的理由&#xff1a; 1&#xff09;可靠地实现TCP全双工连接的终止 在进行关闭连接四次挥手协议时&#xff0c;最后的ACK是由主动关闭端发出的&#xff0c;如果这个最终的ACK丢失&#xff0c;服务器将重发最终的FIN&#xf…

CSS3中多列布局详解

多列布局 概念&#xff1a;在CSS3之前&#xff0c;想要设计类似报纸那样的多列布局&#xff0c;有两种方式可以实现&#xff1a;一种是"浮动布局"&#xff0c;另一种是“定位布局”。 这两种方式都有缺点&#xff1a;浮动布局比较灵活&#xff0c;但不容易控制&…

Speculative Oracles on Memory Tagging

1 引言 PACMAN [1] 的结果引发了对推测机制对 Arm MTE 安全性的关切。 MTE 代表 Memory Tagging Extension [1],它实现了基于锁和密钥的内存访问。可以在每 16 字节的内存上设置 4 位的分配标签(或锁),只有在地址包含匹配的地址标签(或密钥)时才允许对锁定位置进行访问…

用Python“自动连发消息”

自动连发消息&#xff0c;基本上C和Python的思路都是不停的模拟“击键”操作&#xff0c;还有一种VB的脚本写法&#xff0c;反成每种语言都能写&#xff0c;更厉害的可以用java做出个GUI界面&#xff0c;先上代码。 一 代码 import pyautogui # 鼠标 import p…

C++力扣题目101--对称二叉树

101. 对称二叉树 力扣题目链接(opens new window) 给定一个二叉树&#xff0c;检查它是否是镜像对称的。 思路 首先想清楚&#xff0c;判断对称二叉树要比较的是哪两个节点&#xff0c;要比较的可不是左右节点&#xff01; 对于二叉树是否对称&#xff0c;要比较的是根节点…