在上篇文章【AI大模型应用开发】3. RAG初探 - 动手实现一个最简单的RAG应用 中,我们动手实现了一个RAG基本流程。里面涉及到向量数据库和向量检索。对于没接触过的人可能比较懵。本文介绍下文本向量化的概念,以及向量检索的原理,只是简单介绍,不会深入,所以不用担心看不懂,想要详细研究的,可以去搜相关论文,涉及到机器学习和模型训练等。
0. 文本向量
0.1 什么是文本向量
文本向量(Text Vector)是一种将文本数据转换为数值向量的技术,以便于机器学习和数据分析。通过将文本数据转换为数值向量,我们可以使用机器学习算法对文本数据进行处理和分析。
0.2 文本向量是怎么得到的
(1)构建相关(正立)与不相关(负例)的句子对儿样本
(2)训练双塔式模型,让正例间的距离小,负例间的距离大
参考:https://arxiv.org/pdf/1908.10084.pdf
1. 获取文本向量
前面已经说了文本向量是怎么得到的,其实也是训练了一个模型。使用这个训练的模型,给一个输入,就可以得到该输入的向量。
这里我们可以使用OpenAI开放的文本向量化接口embeddings.create
来获取某个文本的向量值。
from openai import OpenAI import os # 加载环境变量 from dotenv import load_dotenv, find_dotenv _ = load_dotenv(find_dotenv()) # 读取本地 .env 文件,里面定义了 OPENAI_API_KEY client = OpenAI() def get_embeddings(texts, model="text-embedding-3-small"): '''封装 OpenAI 的 Embedding 模型接口''' data = client.embeddings.create(input=texts, model=model).data return [x.embedding for x in data]
可以测试一下这个接口,看下这个接口输出的向量长什么样:
test_query = ["测试文本"] vec = get_embeddings(test_query)[0] print(vec[:10]) print(len(vec))
输出结果如下:
可以看到 “测试文本” 这四个字对应的输出是一个 1536 维的向量,这就是 “测试文本” 的向量表示。
注意:相同的文本 使用 不同的向量化模型 获取的向量化结果是不同的,所以请保证你的RAG应用中使用的是同样的向量化模型和方式。
2. 向量间相似度计算
通过上面文本向量化,我们可以将一段文本转换成一串多维的数字,也就是数学上的向量。
2.1 向量间的距离
对于向量,相似度计算很简单,就是计算两个向量之间的距离。
距离的计算有多种,具体可看这篇文章: 向量距离计算的几种方式,这里面最常用的还是余弦距离和欧式距离。(下图来源网络,表示了欧式距离和余弦距离的样子。)
2.2 向量距离计算 Python代码
import numpy as np from numpy import dot from numpy.linalg import norm def cos_sim(a, b): '''余弦距离 -- 越大越相似''' return dot(a, b)/(norm(a)*norm(b)) def l2(a, b): '''欧式距离 -- 越小越相似''' x = np.asarray(a)-np.asarray(b) return norm(x)
3. 向量相似度示例代码
# 能支持跨语言 query = "global conflicts" documents = [ "联合国就苏丹达尔富尔地区大规模暴力事件发出警告", "土耳其、芬兰、瑞典与北约代表将继续就瑞典“入约”问题进行谈判", "日本岐阜市陆上自卫队射击场内发生枪击事件 3人受伤", "国家游泳中心(水立方):恢复游泳、嬉水乐园等水上项目运营", "我国首次在空间站开展舱外辐射生物学暴露实验", ] query_vec = get_embeddings([query])[0] # 计算自身的向量 doc_vecs = get_embeddings(documents) # 计算示例句子的向量 print("Cosine distance:") print(cos_sim(query_vec, query_vec)) # 首先打印自身与自身的余弦距离 for vec in doc_vecs: print(cos_sim(query_vec, vec)) # 打印自身与示例句子的余弦距离 print("\nEuclidean distance:") print(l2(query_vec, query_vec)) # 首先打印自身与自身的欧式距离 for vec in doc_vecs: print(l2(query_vec, vec)) # 打印自身与示例句子的欧式距离
运行结果如下:
可以看出,余弦距离越大表示相似度越高。欧式距离约小,表示相似度越高。
向量检索,就是将相似度最高的k个检索结果召回
如果觉得本文对你有帮助,麻烦点个赞和关注呗 ~~~
- 大家好,我是同学小张
- 欢迎 点赞 + 关注 👏,促使我持续学习,持续干货输出。
- +v: jasper_8017 一起交流💬,一起进步💪。
- 微信公众号也可搜【同学小张】 🙏
- 踩坑不易,感谢关注和围观
本站文章一览: