【AIGC】AI如何匹配RAG知识库:关键词搜索

关键词搜索

  • 引言
  • jieba库简介
  • TF-IDF简介
  • 实践
    • 例子
    • 用jieba库提取关键词
    • 计算TF-IDF
    • 计算文档和查询相似度
    • 结果
    • 完整代码:
  • 总结

引言

RAG作为减少模型幻觉和让模型分析、回答私域相关知识最简单高效的方式,我们除了使用之外可以尝试了解其是如何实现的。在实现RAG的过程中,有语义搜索也有关键词搜索,我们这篇文章来用jieba库以及TF-IDF实现关键词搜索RAG。

jieba库简介

jieba(结巴)是一个在Python中广泛使用的分词库,特别适用于中文文本处理。jieba库不仅支持基本的分词功能,还提供了关键词提取、词性标注、命名实体识别等多种功能。在关键词检测领域,jieba库的TF-IDF和TextRank算法被广泛应用于提取文本中的关键词。

TF-IDF简介

TF-IDF(Term Frequency-Inverse Document Frequency)是一种用于信息检索和文本挖掘的常用加权技术。它通过计算词汇在文档中的频率(Term Frequency, TF)和在整个语料库中的逆文档频率(Inverse Document Frequency, IDF),来评估词汇的重要性和相关性。

TF-IDF的计算公式如下:
在这里插入图片描述

简单来说关键词出现的次数越多且存在于其他文档中的频率越低,那么这个关键词就越重要。

实践

我们来模拟用户询问问题,模型根据问题从知识库中检索出相关文档,并根据检索到的文档生成回答。

我们假设用户输出是text1,text2中是多个以";"隔开的文档,我们使用jieba库分割关键词并使用TF-IDF去实现关键词搜索RAG,搜索text2中最适配text1的文档。
在这里插入图片描述

例子

# Example text
text = "发到顺丰"# Example text2
text2 = "您好,是您拨打的客服电话吗;你好,我的这个货想要通过顺丰去发;订单号发我一下;xxxxxx;好的我这边给您发顺丰"

用jieba库提取关键词

# 切割 text2 并将其作为文档
documents = text2.split(';')# 提取关键词的函数
def extract_keywords(text):return jieba.analyse.extract_tags(text)# 提取查询关键词
query_keywords = extract_keywords(text)# 提取文档关键词
documents_keywords = [extract_keywords(doc) for doc in documents]

计算TF-IDF

各自计算查询关键词和文档关键词的TF-IDF为之后计算余弦相似度进行准备

# 计算查询关键词的词频 (TF)
query_keyword_counts = Counter(query_keywords)# 总文档数
total_documents = len(documents)# 计算所有关键词的逆文档频率 (IDF)
all_keywords = set()
for doc_keywords in documents_keywords:all_keywords.update(doc_keywords)keyword_idf = {}
for keyword in all_keywords:doc_count_containing_keyword = sum(1 for doc_keywords in documents_keywords if keyword in doc_keywords)keyword_idf[keyword] = math.log((1 + total_documents) / (1 + doc_count_containing_keyword)) + 1# 计算查询关键词的 TF-IDF
query_tfidf = {}
for keyword, count in query_keyword_counts.items():tf = countidf = keyword_idf.get(keyword, 0)query_tfidf[keyword] = tf * idf# 计算所有文档的 TF-IDF
documents_tfidf = []
for doc_keywords in documents_keywords:doc_keyword_counts = Counter(doc_keywords)doc_tfidf = {}for keyword, count in doc_keyword_counts.items():tf = countidf = keyword_idf.get(keyword, 0)doc_tfidf[keyword] = tf * idfdocuments_tfidf.append(doc_tfidf)

计算文档和查询相似度

通过计算余弦相似度来计算查询词与文档相似度

# 计算余弦相似度
def cosine_similarity(vec1, vec2):intersection = set(vec1.keys()) & set(vec2.keys())numerator = sum(vec1[x] * vec2[x] for x in intersection)sum1 = sum(vec1[x] ** 2 for x in vec1)sum2 = sum(vec2[x] ** 2 for x in vec2)denominator = math.sqrt(sum1) * math.sqrt(sum2)if not denominator:return 0.0else:return float(numerator) / denominator# 计算文档与查询的相似度
similarities = []
for doc_tfidf in documents_tfidf:similarity = cosine_similarity(query_tfidf, doc_tfidf)similarities.append(similarity)# 按相似度排序并返回结果
sorted_documents = sorted(zip(documents, similarities), key=lambda x: x[1], reverse=True)# 打印结果
for i, (doc, score) in enumerate(zip(documents, similarities)):print(f"Document {i+1}: {doc}\nScore: {score}\n")

结果

Score得分越高,则文档越匹配查询词,可以看到,我们根据关键词搜索,找到了最适配text1的文档,Document 2。

Document 1: 您好,是您拨打的客服电话吗
Score: 0.0Document 2: 你好,我的这个货想要通过顺丰去发
Score: 0.4472135954999579Document 3: 订单号发我一下
Score: 0.0Document 4: xxxxxx
Score: 0.0Document 5: 好的我这边给您发顺丰
Score: 0.0

完整代码:


import jieba
from jieba.analyse import default_tfidf
from collections import Counter
import math# Example text
text = "发到顺丰"# Example text2
text2 = "您好,是您拨打的客服电话吗;你好,我的这个货想要通过顺丰去发;订单号发我一下;xxxxxx;好的我这边给您发顺丰"# 切割 text2 并将其作为文档
documents = text2.split(';')# 提取关键词的函数
def extract_keywords(text):return jieba.analyse.extract_tags(text)# 提取查询关键词
query_keywords = extract_keywords(text)# 提取文档关键词
documents_keywords = [extract_keywords(doc) for doc in documents]# 计算查询关键词的词频 (TF)
query_keyword_counts = Counter(query_keywords)# 总文档数
total_documents = len(documents)# 计算所有关键词的逆文档频率 (IDF)
all_keywords = set()
for doc_keywords in documents_keywords:all_keywords.update(doc_keywords)keyword_idf = {}
for keyword in all_keywords:doc_count_containing_keyword = sum(1 for doc_keywords in documents_keywords if keyword in doc_keywords)keyword_idf[keyword] = math.log((1 + total_documents) / (1 + doc_count_containing_keyword)) + 1# 计算查询关键词的 TF-IDF
query_tfidf = {}
for keyword, count in query_keyword_counts.items():tf = countidf = keyword_idf.get(keyword, 0)query_tfidf[keyword] = tf * idf# 计算所有文档的 TF-IDF
documents_tfidf = []
for doc_keywords in documents_keywords:doc_keyword_counts = Counter(doc_keywords)doc_tfidf = {}for keyword, count in doc_keyword_counts.items():tf = countidf = keyword_idf.get(keyword, 0)doc_tfidf[keyword] = tf * idfdocuments_tfidf.append(doc_tfidf)# 计算余弦相似度
def cosine_similarity(vec1, vec2):intersection = set(vec1.keys()) & set(vec2.keys())numerator = sum(vec1[x] * vec2[x] for x in intersection)sum1 = sum(vec1[x] ** 2 for x in vec1)sum2 = sum(vec2[x] ** 2 for x in vec2)denominator = math.sqrt(sum1) * math.sqrt(sum2)if not denominator:return 0.0else:return float(numerator) / denominator# 计算文档与查询的相似度
similarities = []
for doc_tfidf in documents_tfidf:similarity = cosine_similarity(query_tfidf, doc_tfidf)similarities.append(similarity)# 按相似度排序并返回结果
sorted_documents = sorted(zip(documents, similarities), key=lambda x: x[1], reverse=True)# 打印结果
for i, (doc, score) in enumerate(zip(documents, similarities)):print(f"Document {i+1}: {doc}\nScore: {score}\n")

总结

关键词匹配是RAG搜索中的一个很重要的方法之一,但是关键词匹配的缺点也很明显,就是关键词匹配的召回率很低,因为关键词匹配只匹配了关键词,而没有匹配到关键词的上下文。所以一般需要结合语义搜索去一起进行。可以参考我的另一片介绍语义搜索的文章去进行双路召回搜索。【AIGC】AI如何匹配RAG知识库: Embedding实践,语义搜索

在上面我们的实践中,我们使用jieba库去进行分词,然后通过TF-IDF算法去计算关键词的权重,然后通过余弦相似度去计算文档和查询的相似度,最后通过相似度去排序,返回结果。基本上这个一个比较通用的关键词匹配RAG数据库的方法。

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

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

相关文章

写一个自动采集地球前30行业的小程序

创建一个自动采集地球前30行业信息的小程序可以使用Python和一些常用的库,如BeautifulSoup和Requests。以下是一个基本示例,展示如何从网页上抓取行业信息: 环境准备 安装Python:确保你的计算机上已安装Python。安装库&#xff…

电影评论网站开发:Spring Boot技术指南

3系统分析 3.1可行性分析 通过对本电影评论网站实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本电影评论网站采用SSM框架,JAVA作为开发语言&#…

从传统到智能,从被动监控到主动预警,解锁视频安防平台EasyCVR视频监控智能化升级的关键密钥

视频监控技术从传统监控到智能化升级的过程是一个技术革新和应用场景拓展的过程。智能视频监控系统通过集成AI和机器学习算法,能够实现行为分析、人脸识别和异常事件检测等功能,提升了监控的准确性和响应速度。这些系统不仅用于传统的安全防护&#xff0…

【linux009】文件操作命令篇 - touch 命令

文章目录 touch 命令1、基本用法2、常见选项3、举例4、注意事项 touch 命令 touch 是 Linux 系统中的一个常用命令,用于创建空文件或更新已有文件的时间戳。它既可以用来快速生成新文件,也可以用来修改文件的访问时间(access time, atime&am…

react18中如何监听localstorage的变化获取最新的本地缓存

有时候业务中会需要监听缓存的变化,实时更新页面的内容获取发送接口请求。这就要我们来监听对localstorage的修改,实时响应变化!!一下方法同样实用于vue项目。 同一个项目中不同页面的实现 实现效果 代码分析 修改localstoare的…

【算法】KMP算法

写在前面 在学习KMP算法前,不才也曾在众多博客中阅读过KMP算法的文章,但是都看得迷迷糊糊,所以不才在学透了KMP算法后,详细编写了这篇笔记,希望对你有帮助🥰🥰。 KMP算法的核心思想不分任何语…

二叉树习题其二Java【力扣】【算法学习day.9】

前言 前言 书接上篇文章二叉树习题其一,这篇文章我们将基础拓展 ###我做这类文档一个重要的目的还是给正在学习的大家提供方向(例如想要掌握基础用法,该刷哪些题?)我的解析也不会做的非常详细,只会提供思…

云计算第四阶段-----CLOUND二周目 04-06

cloud 04 今日目标: 一、Pod 生命周期 图解: [rootmaster ~]# vim web1.yaml --- kind: Pod apiVersion: v1 metadata:name: web1 spec:initContainers: # 定义初始化任务- name: task1 # 如果初始化任务失败&#…

目前最新 dnSpy V6.5.1版本,最好的 .NET 程序调试、编辑、反编译软件

目前最新 dnSpy V6.5.1版本,最好的 .NET 程序调试、编辑、反编译软件 一、 简介二、新发布程序更新功能三、官方下载: 一、 简介 dnSpy 是一个调试器 .NET 程序集的编辑器。即使没有源代码,也可以使用它来编辑和调试程序集。主要特点&#x…

连锁收银系统

商淘云连锁管理系统助力连锁企业实现“人货账”全方位数字化管理,它依托连锁品牌进销存管理实现门店订货、线下收银、线上商城、会员营销等一体化管理。 门店订货补货支持连锁直营、加盟 不同门店不同进货价、不同门店不同商品、不同门店在线或者账期支付、门店PC或…

分布式---raft算法

1、Leader的选举和Failover过程 首先了解raft中节点的三种状态: 1、Follower:Follower是请求的被动更新者,从Leader接收更新请求,将日志写入到本地文件2、Candidate:如果Follower在一定时间内,如果每收到Leader的心跳…

uniapp 获取签名证书 SHA1 自有证书签名打包

1.登录你的Dcloud 账户 2.找到我的应用菜单 3.点开某个应用 4.查看证书详情,里面有SHA1 和别名,密码,下载证书用于云打包,可以选择自有证书,输入别名,密码打包

GPT+Python)近红外光谱数据分析与定性/定量建模技巧

2022年11月30日,可能将成为一个改变人类历史的日子——美国人工智能开发机构OpenAI推出了聊天机器人ChatGPT3.5,将人工智能的发展推向了一个新的高度。2023年4月,更强版本的ChatGPT4.0上线,文本、语音、图像等多模态交互方式使其在…

高效实现用友BIP与旺店通数据无缝对接

用友BIP与旺店通企业奇门的YS其他入库单数据集成方案 在企业日常运营中,数据的高效流转和准确对接是确保业务顺畅运行的关键。本文将分享一个具体的系统对接案例,即如何将用友BIP平台中的YS其他入库单数据集成到旺店通企业奇门中,实现两大系…

简历修订与求职经历 - Chap05

现在是又一个周一。上周最值得记录的有这么几件事: 1.拿到了D照。 周二科目一,周四科目二三四联考——是打算为逆行人生准备的。有备无患。然后拿到驾照后发现又有一些问题。看了honda的125,感觉车身好胖。我不喜欢这类很胖的车。然后按照驾…

光伏行业如何借助ERP领跑绿色经济?

在全球能源结构转型和绿色能源转型的大背景下,现在光伏行业呈现出技术创新、市场需求扩大、产能调整和竞争加剧等特点,也预示行业的持续成长和未来的发展潜力。但企业仍然需要不断提高技术水平和管理水平以应对激烈的市场竞争,SAP ERP制定符合…

Maven基于构建阶段分析多余的依赖

基于构建阶段 test compile 实现依赖分析 执行maven 命令: mvn dependency:analyze 关注:Maven-dependency-plugin 分析结果: [INFO] --- maven-dependency-plugin:2.10:analyze (default-cli) impl --- 配置依赖未使用的依赖项: [INFO] --- maven-dependency-…

Lucas带你手撕机器学习——线性回归

什么是线性回归 线性回归是机器学习中的基础算法之一,用于预测一个连续的输出值。它假设输入特征与输出值之间的关系是线性关系,即目标变量是输入变量的线性组合。我们可以从代码实现的角度来学习线性回归,包括如何使用 Python 进行简单的线…

git的安装以及入门使用

文章目录 git的安装以及入门使用什么是git?git安装git官网 git初始化配置使用方式初始化配置: git的安装以及入门使用 什么是git? Git 是一个免费开源的分布式版本控制系统,使用特殊的仓库数据库记录文件变化。它记录每个文件的…

WebGl 使用uniform变量动态修改点的颜色

在WebGL中,uniform变量用于在顶点着色器和片元着色器之间传递全局状态信息,这些信息在渲染过程中不会随着顶点的变化而变化。uniform变量可以用来设置变换矩阵、光照参数、材料属性等。由于它们在整个渲染过程中共享,因此可以被所有使用该着色…