使用UMAP降维可视化RAG嵌入

news2024/11/25 2:59:20

大型语言模型(LLMs)如 GPT-4 已经展示了出色的文本理解和生成能力。但它们在处理领域特定信息方面面临挑战,比如当查询超出训练数据范围时,它们会产生错误的答案。LLMs 的推理过程也缺乏透明度,使用户难以理解达成结论的方式。

检索增强生成(RAG)在 LLMS 的工作流程中添加了一个检索步骤,使其能够在响应查询时从其他来源(如私人文本文档)中查询相关数据。这些文档事先分成小段,然后使用embedding的 ML 模型生成嵌入。具有相似内容的段将具有相似的嵌入。当 RAG 应用程序收到一个问题时,它使用查询检索相关文档片段。然后 LLMS 使用这些文档片段作为上下文来回答问题。这种方法可以提供回答查询所需的信息,并通过展示使用的片段来增加回答的透明度。

对于RAG来说,可视化嵌入空间是一个非常重要的方法,因为RAG应用程序使用该空间来查找相关信息。查询的结果与文档片空间息息相关,所以可以使用像UMAP这样的可视化方法,将高维嵌入减少到更易于展示的2D进行可视化。虽然高维嵌入被简化为两个分量,但问题及其相关文档片段在嵌入空间中形成簇,仍然是可以被识别出来,尤其是这时肉眼可见的,所以这有助于深入了解数据的本质。

在本文中,我们将使用HTML格式的Wikipedia中的f1数据集,使用嵌入模型将它们转换为紧凑的矢量表示,并存储到ChromaDB中。使用LangChain构建RAG应用,并在2D中可视化嵌入,分析查询和文档片段之间的关系和接近度。

首先我们安装需要的库

 !pip install langchain langchain-openai chromadb renumics-spotlight

我们使用了Renumics-Spotlight python包,Renumics-Spotlight是一个交互式探索非结构化ML数据集的可视化工具。

而获得嵌入我们则直接使用了OpenAI的embedding-ada-002,所以这里要设置API的Key

 %env OPENAI_API_KEY=<your-api-key>

准备文件

对于数据集是使用wikipedia-api和BeautifulSoup创建的。

本数据集基于维基百科的文章,并在知识共享署名-相同方式共享许可下获得许可。原始文章和作者名单可以在各自的维基百科页面上找到。

将提取的html放到docs/子文件夹中,或者可以通过创建docs/子文件夹的方式将你自己的文件复制到其中来使用自己的Dataset。

创建嵌入

要创建嵌入,首先需要设置嵌入模型和vectorstore。这里我们使用OpenAIEmbeddings中的text- embeddings -ada-002和使用ChromaDB的vectorstore:

 from langchain_openai import OpenAIEmbeddings
 from langchain.vectorstores.chroma import Chroma
 
 embeddings_model = OpenAIEmbeddings(model="text-embedding-ada-002")
 docs_vectorstore = Chroma(
     collection_name="docs_store",
     embedding_function=embeddings_model,
     persist_directory="docs-db",
 )

vectorstore将持久化到docs-db 文件夹中。然后使用BSHTMLLoader加载html文档:

 from langchain_community.document_loaders import BSHTMLLoader, DirectoryLoader
 loader = DirectoryLoader(
     "docs",
     glob="*.html",
     loader_cls=BSHTMLLoader,
     loader_kwargs={"open_encoding": "utf-8"},
     recursive=True,
     show_progress=True,
 )
 docs = loader.load()

将文档分成小块

 from langchain.text_splitter import RecursiveCharacterTextSplitter
 text_splitter = RecursiveCharacterTextSplitter(
     chunk_size=1000, chunk_overlap=200, add_start_index=True
 )
 splits = text_splitter.split_documents(docs)

从元数据重建的id,这样可以在数据库中查找嵌入。

 import hashlib
 import json
 from langchain_core.documents import Document
 
 def stable_hash(doc: Document) -> str:
     """
     Stable hash document based on its metadata.
     """
     return hashlib.sha1(json.dumps(doc.metadata, sort_keys=True).encode()).hexdigest()
 
 split_ids = list(map(stable_hash, splits))
 docs_vectorstore.add_documents(splits, ids=split_ids)
 docs_vectorstore.persist()

LangChain

首先,你需要选择一个LLM模型。我们使用GPT-4

 from langchain_openai import ChatOpenAI
 
 llm = ChatOpenAI(model="gpt-4", temperature=0.0)
 retriever = docs_vectorstore.as_retriever(search_kwargs={"k": 20})

在初始化ChatOpenAI模型时,将temperature参数设置为0.0可确保确定性输出。

我们使用下面的提示:

 from langchain_core.prompts import ChatPromptTemplate
 
 template = """
 You are an assistant for question-answering tasks.
 Given the following extracted parts of a long document and a question, create a final answer with references ("SOURCES").
 If you don't know the answer, just say that you don't know. Don't try to make up an answer.
 ALWAYS return a "SOURCES" part in your answer.
 
 QUESTION: {question}
 =========
 {source_documents}
 =========
 FINAL ANSWER: """
 prompt = ChatPromptTemplate.from_template(template)

然后对检索到的文档进行格式化,使其包含页面内容和源文件路径,将这个格式化的输入输入到语言模型(LLM),模型就可以根据合并的用户问题和文档上下文生成答案。

 from typing import List
 
 from langchain_core.runnables import RunnableParallel, RunnablePassthrough
 from langchain_core.output_parsers import StrOutputParser
 
 
 def format_docs(docs: List[Document]) -> str:
     return "\n\n".join(
         f"Content: {doc.page_content}\nSource: {doc.metadata['source']}" for doc in docs
     )
 
 
 rag_chain_from_docs = (
     RunnablePassthrough.assign(
         source_documents=(lambda x: format_docs(x["source_documents"]))
     )
     | prompt
     | llm
     | StrOutputParser()
 )
 rag_chain = RunnableParallel(
     {
         "source_documents": retriever,
         "question": RunnablePassthrough(),
     }
 ).assign(answer=rag_chain_from_docs)

RAG的为问题回答

RAG应用程序现在已经准备好回答问题了:

 question = "Who built the nuerburgring"
 response = rag_chain.invoke(question)
 response["answer"]

回答如下:

 'The Nürburgring was built in the 1920s, with the construction of the track beginning in September 1925. The track was designed by the Eichler Architekturbüro from Ravensburg, led by architect Gustav Eichler. The original Nürburgring was intended to be a showcase for German automotive engineering and racing talent (SOURCES: data/docs/Nürburgring.html).'

这个问题也将在下一步中用于进一步得到确认。

可视化

为了进行可视化,我们使用Pandas DataFrame来组织数据。从从矢量存储中提取文本片段及其嵌入。我们还要标出正确的答案:

 import pandas as pd
 
 response = docs_vectorstore.get(include=["metadatas", "documents", "embeddings"])
 df = pd.DataFrame(
     {
         "id": response["ids"],
         "source": [metadata.get("source") for metadata in response["metadatas"]],
         "page": [metadata.get("page", -1) for metadata in response["metadatas"]],
         "document": response["documents"],
         "embedding": response["embeddings"],
     }
 )
 df["contains_answer"] = df["document"].apply(lambda x: "Eichler" in x)
 df["contains_answer"].to_numpy().nonzero()

问题和相关的答案也被投影到嵌入空间中。它们的处理方式与文本片段相同:

 question_row = pd.DataFrame(
     {
         "id": "question",
         "question": question,
         "embedding": embeddings_model.embed_query(question),
     }
 )
 answer_row = pd.DataFrame(
     {
         "id": "answer",
         "answer": answer,
         "embedding": embeddings_model.embed_query(answer),
     }
 )
 df = pd.concat([question_row, answer_row, df])

首先打印问题与文档片段之间的距离:

 import numpy as np
 question_embedding = embeddings_model.embed_query(question)
 df["dist"] = df.apply(
     lambda row: np.linalg.norm(
         np.array(row["embedding"]) - question_embedding
     ),
     axis=1,
 )

这个距离还可以用于可视化:

 from renumics import spotlight
 spotlight.show(df)

上面的语句会打开一个新的浏览器窗口。左上角的表格部分显示数据集的所有字段。右上方的相似性图中突出显示它们。

可以看到,包含正确答案的单个文档片段和最相关的文件离问题和答案很近。

总结

使用降维技术可以使用户和开发人员访问嵌入空间。在可视化空间中,可以通过浏览相邻的数据点来进行检索增强的检查。降维可视化虽然有助于理解数据,但也可能存在信息损失,因为它将高维数据映射到一个较低维度的空间中。因此,在进行检查时,需要权衡信息丢失和效果提升之间的关系。

完整代码:
https://avoid.overfit.cn/post/31e45d66ef1547e397bbbef2ebcf38c8

作者:Markus Stoll

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

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

相关文章

Win10截图的四种方式

截图不一定要依靠通讯软件&#xff0c;现在系统自己就带有这些功能。 1.Win Shift S组合键&#xff1a;选择微信截图&#xff0c;部分截图&#xff0c;随心所欲&#xff1b; 2.Win W组合键&#xff1a;呼出屏幕右侧的工作区&#xff0c;选择屏幕草图&#xff0c;支持裁剪、编辑…

flask+python高校学生综合测评管理系统 phl8b

系统包括管理员、教师和学生三个角色&#xff1b; 。通过研究&#xff0c;以MySQL为后端数据库&#xff0c;以python为前端技术&#xff0c;以pycharm为开发平台&#xff0c;采用vue架构&#xff0c;建立一个提供个人中心、学生管理、教师管理、课程类型管理、课程信息管理、学…

网络安全工程师技能手册(附学习路线图)

关键词&#xff1a;网络安全入门、渗透测试学习、零基础学安全、网络安全学习路线 安全是互联网公司的生命&#xff0c;也是每位网民的基本需求。现在越来越多的人对网络安全感兴趣&#xff0c;愿意投奔到网络安全事业之中&#xff0c;这是一个很好的现象。 很多对网络安全感…

线程池7个参数描述

所谓的线程池的 7 大参数是指&#xff0c;在使用 ThreadPoolExecutor 创建线程池时所设置的 7 个参数&#xff0c;如以下源码所示&#xff1a; public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable&…

游泳时可以听歌的耳机有哪些?戴游泳耳机有哪些好处?

游泳和跑步在某种程度上相似&#xff0c;特别是在短距离冲刺时&#xff0c;大脑似乎变得空白&#xff0c;而在中长距离的有氧运动中&#xff0c;身体感到疲劳&#xff0c;但大脑却异常清晰&#xff0c;时间却显得格外漫长。如何打发时间&#xff0c;让游泳锻炼变得不无聊&#…

「深度学习」dropout 技术

一、工作原理 1. 正则化网络 dropout 将遍历网络的每一层&#xff0c;并设置消除神经网络中节点的概率。 1. 每个节点保留/消除的概率为0.5: 2. 消除节点&#xff1a; 3. 得到一个规模更小的神经网络&#xff1a; 2. dropout 技术 最常用&#xff1a;反向随机失活 "…

Ubuntu Desktop - Terminal 输出全部选中 + 复制

Ubuntu Desktop - Terminal 输出全部选中 复制 1. Terminal2. Terminal 最大化3. Edit -> Select All4. Copy & PasteReferences 1. Terminal 2. Terminal 最大化 3. Edit -> Select All 4. Copy & Paste Edit -> Copy or Shift Ctrl C Edit -> Paste…

线程-线程的创建方式与线程池基础知识

创建线程有四种方式&#xff0c;继承Thread类、实现Runnable接口、实现Callable接口、线程池创建线程&#xff0c;常用的还是线程池创建线程。 1.继承Thread类 自定义类MyThread&#xff08;叫什么都行&#xff09;去extends Thread 重写里面的run方法&#xff0c;new MyThr…

2024-02-12 Unity 编辑器开发之编辑器拓展3 —— EditorGUI

文章目录 1 GUILayout2 EditorGUI 介绍3 文本、层级、标签、颜色拾取3.1 LabelField3.2 LayerField3.3 TagField3.4 ColorField3.5 代码示例 4 枚举选择、整数选择、按下按钮4.1 EnumPopup / EnumFlagsField4.2 IntPopup4.3 DropdownButton4.4 代码示例 5 对象关联、各类型输入…

【北邮鲁鹏老师计算机视觉课程笔记】05 Hough 霍夫变换

【北邮鲁鹏老师计算机视觉课程笔记】05 Hough 霍夫变换 1 投票策略 考虑到外点率太高 ①让直线上的每一点投票 ②希望噪声点不要给具体的任何模型投票&#xff0c;即噪声点不会有一致性的答案 ③即使被遮挡了&#xff0c;也能把直线找出来 参数空间离散化 直线相当于就是m,b两…

【Web】vulhub Fastjson反序列化漏洞复现学习笔记

目录 1.2.24 RCE CVE-2017-18349 复现流程 原理分析 1.2.47 RCE CNVD-2019-22238 复现流程 原理分析 漏洞探测 1.2.24 RCE CVE-2017-18349 复现流程 vulhub启动靶场 用marshalsec启动LDAP/RMI服务 java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRef…

使用securecrt+xming通过x11访问ubuntu可视化程序

windows使用securecrtxming通过x11访问ubuntu可视化程序 windows机器IP&#xff1a;192.168.9.133 ubuntu-desktop20.04机器IP&#xff1a;192.168.9.190 windows下载xming并安装 按照图修改xming配置 开始->xming->Xlaunch 完成xming会在右下角后台运行 windows在…

Vue源码系列讲解——模板编译篇【一】(综述)

目录 1. 前言 2. 什么是模板编译 3. 整体渲染流程 4. 模板编译内部流程 4.1 抽象语法树AST 4.2 具体流程 5. 总结 1. 前言 在前几篇文章中&#xff0c;我们介绍了Vue中的虚拟DOM以及虚拟DOM的patch(DOM-Diff)过程&#xff0c;而虚拟DOM存在的必要条件是得先有VNode&…

Oracle11g安装配置详细教程

Oracle Database 11g是一款广泛使用的关系型数据库管理系统&#xff0c;它为企业级的应用提供了强大的数据管理功能。本文将详细介绍如何在Windows环境下安装和配置Oracle 11g。 准备工作 系统要求&#xff1a;确保你的系统满足安装Oracle 11g的最低要求。对于Oracle 11g Rele…

linux系统下vscode portable版本的python环境搭建003:venv

这里写自定义目录标题 python安装方案一. 使用源码安装&#xff08;有[构建工具](https://blog.csdn.net/ResumeProject/article/details/136095629)的情况下&#xff09;方案二.使用系统包管理器 虚拟环境安装TESTCG 本文目的&#xff1a;希望在获得一个新的系统之后&#xff…

Oracle的学习心得和知识总结(三十二)|Oracle数据库数据库回放功能之论文四翻译及学习

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《Oracle Database SQL Language Reference》 2、参考书籍&#xff1a;《PostgreSQL中文手册》 3、EDB Postgres Advanced Server User Gui…

S32 Design Studio PE工具配置GPIO

首先我们来讲最简单的GPIO配置 代码生成 按照下图步骤就能配置一个基本的GPIO口&#xff0c;在组件里面选择pin_mux&#xff0c;选中就能配置使能和方向&#xff0c;no pin routed就是没有配置的。GPIO口分ABCDE组&#xff0c;每组从0到最大的序号。 然后在functional prope…

互联网加竞赛 基于深度学习的行人重识别(person reid)

文章目录 0 前言1 技术背景2 技术介绍3 重识别技术实现3.1 数据集3.2 Person REID3.2.1 算法原理3.2.2 算法流程图 4 实现效果5 部分代码6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习的行人重识别 该项目较为新颖&#xff0c;适合…

政安晨:在Jupyter中【示例演绎】Matplotlib的官方指南(二){Image tutorial}·{Python语言}

咱们接着上一篇&#xff0c;这次咱们讲使用Matplotlib绘制图像的简短尝试。 我的这个系列的上一篇文章在这里&#xff1a; 政安晨&#xff1a;在Jupyter中【示例演绎】Matplotlib的官方指南&#xff08;一&#xff09;{Pyplot tutorial}https://blog.csdn.net/snowdenkeke/ar…

创建菜单与游戏页面

bootstrap地址 Bootstrap v5 中文文档 Bootstrap 是全球最受欢迎的 HTML、CSS 和 JS 前端工具库。 | Bootstrap 中文网 (bootcss.com) 创建导航栏组件 web--src--components--NavBar.vue <!-- html --> <template><nav class"navbar navbar-expand-lg n…