引言
RAG作为减少模子幻觉和让模子分析、回答私域相干知识最简朴高效的方式,我们除了使用之外可以尝试了解其是如何实现的。在实现RAG的过程中Embedding是非常重要的手段。本文将带你简朴地了解AI工具都是如何通过Embedding去完成语义分析匹配的。
Embedding技术简介
Embedding是一种将高维数据映射到低维空间的技术。在NLP中,Embedding通常用于将单词、句子或文档转换为连续的向量体现。这些向量不仅保留了原始数据的关键信息,还可以或许在低维空间中捕捉到语义上的相似性。
简朴来说,就是呆板无法直接识别人类的语言,以是须要通过Embedding去转化成呆板可以或许明白和处理的数值情势。比如:"猫"和"狗"由于都是动物,以是它们的Embedding向量在空间上比力靠近,而"猫"和"书"由于语义上没有直接关系,以是它们的Embedding向量在空间上间隔较远。呆板就是通过这样去明白人类语言的。
RAG知识库与Embedding的结合
RAG(Retrieval-Augmented Generation)是一种结合了检索和生成的模子架构。在RAG中,知识库的匹配是至关重要的一环。传统的匹配方法通常依赖于关键词匹配,这种方法在处理复杂语义时往往体现不佳。
通过使用Embedding技术,我们可以将知识库中的文档和查询语句转换为向量体现。这样,我们就可以使用向量之间的相似度来实现更精确的匹配。详细来说,我们可以通过盘算查询向量与知识库中每个文档向量的余弦相似度,来确定最相干的文档,也就是类似上面提到的通过盘算能用"猫"匹配出"狗",而不是"书"。
而通过这个我们就可以用用户输入的句子去匹配我们的数据库找到最相干的文档,从而实现RAG。
实践案例:Embedding在RAG知识库匹配中的应用
如今我们来做个简朴的实践帮助大家去明白Embedding在RAG知识库匹配中的应用。
使用Qwen的embedding模子
- import dashscope
- from http import HTTPStatus
- import numpy as np
- # 设置Qwen API密钥
- dashscope.api_key = 'sk-xxx'
- def embed_text(text):
- """
- 将输入的文本转换为嵌入向量
-
- Args:
- text (str): 需要转换的文本
-
- Returns:
- list: 文本的嵌入向量
-
- Raises:
- Exception: 如果获取嵌入向量失败,抛出异常
- """
- resp = dashscope.TextEmbedding.call(
- model=dashscope.TextEmbedding.Models.text_embedding_v2,
- input=text)
-
- # 检查响应状态码,如果成功则返回嵌入向量
- if resp.status_code == HTTPStatus.OK:
- return resp.output['embeddings'][0]['embedding'] # 提取嵌入向量
- else:
- raise Exception(f"Failed to get embedding: {resp.status_code}")
- def cosine_similarity(vec1, vec2):
- """
- 计算两个向量之间的余弦相似度
-
- Args:
- vec1 (list): 第一个向量
- vec2 (list): 第二个向量
-
- Returns:
- float: 两个向量之间的余弦相似度
- """
- dot_product = np.dot(vec1, vec2) # 计算点积
- norm_vec1 = np.linalg.norm(vec1) # 计算第一个向量的范数
- norm_vec2 = np.linalg.norm(vec2) # 计算第二个向量的范数
- return dot_product / (norm_vec1 * norm_vec2) # 返回余弦相似度
- def calculate_similarity(text1, text2):
- """
- 计算两个文本之间的相似度
-
- Args:
- text1 (str): 第一个文本
- text2 (str): 第二个文本
-
- Returns:
- float: 两个文本之间的余弦相似度
- """
- embedding1 = embed_text(text1) # 获取第一个文本的嵌入向量
- embedding2 = embed_text(text2) # 获取第二个文本的嵌入向量
- return cosine_similarity(embedding1, embedding2) # 返回两个文本的余弦相似度
- if __name__ == '__main__':
- text1 = '一起去运动吧'
- text2 = '一起去踢足球吧'
- text3 = '一起去坐飞机吧'
-
- # 计算文本1和文本2之间的相似度
- similarities1 = calculate_similarity(text1, text2)
-
- # 计算文本1和文本3之间的相似度
- similarities2 = calculate_similarity(text1, text3)
-
- # 打印相似度结果
- print(f"Similarity1: {similarities1} \nSimilarity2: {similarities2}")
复制代码 结果:
- Similarity1: 0.6644462831108588
- Similarity2: 0.49586189950477266
复制代码 可以看到Similarity1 是高于 Similarity2的,说明text1(活动)更匹配与text2(踢足球),假设text1是用户输入的输入,text2和text3是知识库,我们通过embedding后盘算用户输入与知识库各个文档的余弦值,就可以匹配出text2与用户输入更相干(活动与踢足球更相干,而不是坐飞机),从而将对应文档输出出来。
固然,这样相当于使用整句举行对应的语义分析,实际RAG匹配过程中还涉及到很多技术,比如:语义检索、关键词检索、双路召回,双检索占比配置等。之后文章会再详细介绍。
用spacy举行Embedding
我们可以尝试直接用spacy库举行embedding,并盘算相似度。
- import spacy
- nlp = spacy.load('zh_core_web_sm')
- def contains_phrase_nlp(text, phrase):
- doc = nlp(text)
- phrase_doc = nlp(phrase)
- for sent in doc.sents:
- similarity = phrase_doc.similarity(sent)
- return similarity
- if __name__ == '__main__':
- text1 = '一起去运动吧'
- text2 = '一起去踢足球吧'
- text3 = '一起去坐飞机吧'
- similarities1 = contains_phrase_nlp(text1, text2)
- similarities2 = contains_phrase_nlp(text1, text3)
- print(f"Similarity1: {similarities1} \nSimilarity2: {similarities2}")
复制代码 结果:
- Similarity1: 0.8225547086542833
- Similarity2: 0.8069693841904839
复制代码 结果并不是很显着,第一组没有比第二组多,仅做一种方法参考。如今的例子比力简朴,如果遇到复杂语义,大概效果会更好。
总结
Embedding技术在匹配RAG知识库中扮演着至关重要的脚色。本文我们主要用Embedding举行语义匹配,之后文章会带来更丰富的方法。本文实践可以或许帮助各位更好地明白Embedding技术在RAG知识库匹配中的应用,以及Embedding本身。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |