使用 OpenAI 的 Embedding模型 构建知识向量库并进行相似搜索

news2025/1/13 2:48:05

OpenAI的embedding模型的使用

       首先第一篇文章中探讨和使用了ChatGPT4的API-Key实现基础的多轮对话和流式输出,完成了对GPT-API的一个初探索,那第二步打算使用OpenAI的embedding模型来构建一个知识向量库,其实知识向量库本质上就是一个包含着一组向量的数组,然后通过查询输入文本生成的向量和数据库文本中的向量的余弦相似度来进行相似度判断,在使用的过程中还是非常舒服的。

前置文章:ChatGPT4 API-Key初探-本地调用API进行多轮对话方和流式输出

文章目录

  • OpenAI的embedding模型的使用
    • 1.什么是Embedding
    • 2.使用OpenAI的embedding模型生成一个词向量
    • 3.使用OpenAI的embedding模型获得一个知识向量库
    • 3.从知识向量库中进行相似文本的查询
  • 结束

1.什么是Embedding


       Embedding在AI领域被翻译成词嵌入,但是光看这三个字其实不好理解,如果用一句话解释的话:embedding就是将文字转换成一个向量


在这里插入图片描述

图: Embedding的工作过程


  • 那为什么要转换成向量?
    因为要获得两段文字在空间中的关系进行运算,例如后续需要做的计算两个词的相似度,就需要首先经过embedding模型将两端文字转换成向量,然后算两个向量的余弦相似度。

       如果你不是研究自然语言处理的研究生或者算法工程师,那你只需要了解这一点就可以了,至于怎么转换的这一点可以不用深究,就像你可能不了解计算机组成原理但是你依然可以熟练的使用计算机。

2.使用OpenAI的embedding模型生成一个词向量


       OpenAI为我们提供了了一个方便的API接口来将输入文本直接转换为词向量,在官方文档的代码中其实并没有新手向的代码的表达都会集成一些功能一起发布,但是为了学习和理解要把其中最简单和核心的部分抽出来。

       下面的代码使用的是OpenAI的text-embedding-3-small模型将文本"父亲"转换为词向量。经过API之后得到了一个长度为1536的向量。

from openai import OpenAI
import numpy as np

# client = OpenAI(api_key="your-api-key-here") # 如果想在代码中设置Api-key而不是全局变量就用这个代码
client = OpenAI()

model = "text-embedding-3-small"


def get_embedding(text, model=model):
    return client.embeddings.create(input=text, model=model).data[0].embedding


text = '父亲'
vector = np.array(get_embedding(text))
print(vector.shape)
# (1536,)

3.使用OpenAI的embedding模型获得一个知识向量库


       OK那既然一条文本能转换成向量,那多条文本那就必然能转换成多个词向量,且词向量的长度是一致的,然后将这些词向量转换成数组然后保存这样就得到了一个知识向量库,本质上就是保存一个数组,返璞归真。

       首先我们得有一段文本,我让ChatGPT给我生成了50个医疗词汇,每个词汇一行,文本内容我放在文章最后。接下来给出代码。

       下列代码将本文中的医疗词汇逐行读取然后转换成词向量,保存到一个numpy数组当中,然后再将Numpy数组保存到本地,这样就得到了一个知识向量库。

from openai import OpenAI
import pandas as pd
import numpy as np
import time

# client = OpenAI(api_key="your-api-key-here") # 如果想在代码中设置Api-key而不是全局变量就用这个代码
client = OpenAI()

model = "text-embedding-3-small"

with open('test.txt', 'r', encoding='utf-8') as file:
    lines = file.readlines()

embedding = [client.embeddings.create(input=i.strip(), model=model).data[0].embedding for i in lines]

t = time.time()
np.save('embedding.npy', np.array(embedding))
print(time.time() - t)
# 0.002991914749145508 (运行时间/s)

测试用的文本内容

糖尿病
高血压
抑郁症
阿尔茨海默症
慢性阻塞性肺疾病(COPD)
骨折
哮喘
乳腺癌
心肌梗塞
脑卒中
化疗
放射疗法
心脏搭桥手术
经皮冠状动脉介入治疗(PCI)
腹腔镜手术
物理疗法
认知行为疗法
血液透析
绝育手术
骨髓移植
MRI扫描仪
CT扫描仪
心电图机
超声波设备
血糖仪
血压计
吸氧机
呼吸机
脉搏血氧仪
自动体外除颤器(AED)
青霉素
阿司匹林
他汀类药物
阿片类镇痛药
抗生素
抗抑郁药
胰岛素
利尿剂
抗凝血药
抗病毒药
免疫疗法
基因编辑
微创手术
患者健康记录(PHR)
电子医疗记录(EMR)
临床试验
医疗保健大数据
精准医疗
遥感监测
医疗伦理

3.从知识向量库中进行相似文本的查询


       首先在介绍查询方法之需要说一下计算相似度的余弦相似度,当两个向量夹角越小的时候两个向量的相似度越高,其计算公式如下:


cosine similarity ( A , B ) = A ⋅ B ∥ A ∥ ∥ B ∥ = ∑ i = 1 n A i B i ∑ i = 1 n A i 2 ∑ i = 1 n B i 2 \text{cosine similarity}(\mathbf{A}, \mathbf{B}) = \frac{\mathbf{A} \cdot \mathbf{B}}{\|\mathbf{A}\| \|\mathbf{B}\|} = \frac{\sum_{i=1}^{n}A_iB_i}{\sqrt{\sum_{i=1}^{n}A_i^2} \sqrt{\sum_{i=1}^{n}B_i^2}} cosine similarity(A,B)=A∥∥BAB=i=1nAi2 i=1nBi2 i=1nAiBi


       在查询任务中我们需要计算输入文本的向量和知识向量库中所有文本向量的余弦相似度,然后进行排序,当然作为一个算法工程师我们当然不能直接用for循环进行计算,本文基于numpy的广播机制,自己实现了一个高效的计算一个向量和一群向量的余弦相似度的代码。同时由于算法本身使用的是numpy,基于numpy底层为C语言实现,因此本程序的效率较高,作为新手的话只需要知道输入输出是什么就行了。代码如下。

import numpy as np

def cos_similarity(target, embedding):
    numerator = np.sum(target * embedding, axis=1)
    denominator = np.sqrt(np.sum(np.square(target)) * np.sum(np.square(embedding),axis=1))
    return numerator / denominator


if __name__ == '__main__':

    x = np.array([1, 2])
    y = np.array([[1, 2], [1, 1]])

    print(cos_similarity(x, y))
	# [1.        0.9486833]

将知识向量库中的文本按照相似度从大到小输出,代码如下:

  • 生成知识向量库和查询使用的模型得是一个模型别忘了,不然会报维度错误。
import numpy as np
from openai import OpenAI

model="text-embedding-3-small"
# client = OpenAI(api_key="your-api-key-here") # 如果想在代码中设置Api-key而不是全局变量就用这个代码
client = OpenAI()

def get_embedding(text, model=model):
   return client.embeddings.create(input=text, model=model).data[0].embedding

def cos_similarity(target, embedding):
    numerator = np.sum(target * embedding, axis=1)
    denominator = np.sqrt(np.sum(np.square(target)) * np.sum(np.square(embedding),axis=1))
    return numerator / denominator

with open('test.txt', 'r', encoding='utf-8') as file:
    lines = file.readlines()

# 获得文本数据
name = np.array([i.strip() for i in lines])
# 获得向量库
embedding = np.load("embedding.npy",allow_pickle=True)


# 获取用户的输入文本
search_text = input("User:")
# 获取用户输入文本使用embedding模型转换得到的词向量
search_embedding = get_embedding(search_text)
# 计算用户输入文本
embedding_similarity = cos_similarity(search_embedding,embedding)


# 由上到下输入相似度
for i in np.argsort(embedding_similarity)[::-1]:
    print(name[i],embedding_similarity[i])

接下来让GPT解释一下这段代码助于理解,我看了一下基本没有问题。

  1. 导入所需的库:使用了numpy库来处理数学运算和数组操作,以及OpenAI的API客户端来获取文本的嵌入向量。

  2. 设置模型和客户端:选择了一个特定的模型text-embedding-3-small来从OpenAI获取文本嵌入。这里有一段被注释掉的代码,用于手动设置API密钥,但在这个例子中,默认使用了全局变量设置的API密钥。

  3. 定义函数获取嵌入向量get_embedding函数通过OpenAI的API将文本转换成嵌入向量。这个向量是文本的数学表示,用于计算相似度。

  4. 定义余弦相似度函数cos_similarity函数计算两组向量之间的余弦相似度,这是衡量向量相似度的一种方法。余弦相似度越接近1,表示两个向量越相似。

  5. 读取文本数据:从test.txt文件中读取每行文本,每行代表一个可查询的项,并将其存储在名为name的数组中。

  6. 加载嵌入向量库:从embedding.npy文件加载预先计算好的嵌入向量,这些向量对应于test.txt文件中的文本项。

  7. 获取用户输入:通过input函数获取用户的查询文本。

  8. 获取查询文本的嵌入向量:使用get_embedding函数将用户的查询文本转换为嵌入向量。

  9. 计算相似度:使用cos_similarity函数计算用户查询的嵌入向量与嵌入向量库中所有向量之间的余弦相似度。

输出结果如下,这里就不全部粘贴了,把前面的几个粘贴上。

User:糖尿病
糖尿病 1.0
血糖仪 0.6027716430115105
高血压 0.4807989892102901
乳腺癌 0.46976679922966263
利尿剂 0.44671493260605705
抑郁症 0.3989793244972647
胰岛素 0.3678633339750386
心肌梗塞 0.3630205294730911
阿尔茨海默症 0.3554829250733137
血压计 0.3527248065537073
抗病毒药 0.3223748925983246

在这里插入图片描述

结束


官方文档:https://platform.openai.com/docs/guides/embeddings/embedding-models
目前支持的Embedding模型如下。
在这里插入图片描述
       在官方文档中还详细讲了很多的使用方式,例如如何进行可视化,如何进行机器学习技术等,但是文章中的内容是我抽出主要内容然后加上自己的理解实现的。如果有什么不对或者更好的方式非常欢迎交流。

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

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

相关文章

四、HarmonyOS应用开发-ArkTS开发语言介绍

目录 1、TypeScript快速入门 1.1、编程语言介绍 1.2、基础类型 1.3、条件语句 1.4、函数 1.5、类 1.6、模块 1.7、迭代器 2、ArkTs 基础(浅析ArkTS的起源和演进) 2.1、引言 2.2、JS 2.3、TS 2.4、ArkTS 2.5、下一步演进 3、ArkTs 开发实践…

【Linux】网络基础一

网络基础一 1.计算机网络背景1.1 网络发展1.2 认识 “协议” 2.网络协议初识2.1 协议分层2.2 OSI七层模型2.3 TCP/IP五层(或四层)模型 3. 网络传输基本流程3.1 网络传输流程图 4.数据包封装和分用5.网络中的地址管理 从今天开始我们将要从系统横跨到网络的学习了,因…

微信支付宝--充ChatGPTPLUS/openAI key

ChatGPT是人工智能技术驱动的自然语言处理工具,它能够基于在预训练阶段所见的模式和统计规律,来生成回答,还能根据聊天的上下文进行互动,真正像人类一样来聊天交流,甚至能完成撰写论文、邮件、脚本、文案、翻译、代码等…

MFC界面美化第四篇----自绘list列表(重绘列表)

1.前言 最近发现读者对我的mfc美化的专栏比较感兴趣,因此在这里进行续写,这里我会计划写几个连续的篇章,包括对MFC按钮的美化,菜单栏的美化,标题栏的美化,list列表的美化,直到最后形成一个完整…

【Python】反编译PyInstaller打包的exe

查看exe基本信息 需要反编译的exe 查看exe文件的打包工具,查看exe信息的软件叫Detect It Easy(查壳工具) 由图我们可以看出当前选中的exe文件是由名叫PyInstaller的打包工具打包好的exe 反编译 exe反编译工具:pyinstxtractor.py 使用方法 python py…

VMWare虚拟机使用openmediavault搭建NAS服务器完整步聚

下载: gopenmediavault - The open network attached storage solution 下载好openmediavault的ISO镜像后,打开虚拟机并安装 系统类型选择Debian 启动虚拟机并安装openmediavault 选择中文 地区选中国 键盘配置选汉语 开始安装 配置网络信息 配置root密码 确认密码 系统安装中…

spark基本原理UI界面解读

这里是引用 1 八股文 1.1 基本原理 driver节点是整个应用程序的指挥所 指挥官是sparkcontext 环境:构建一个集群 应用程序提交 确定主节点,确定指挥所driver,确定指挥官sparkcontext sparkcontext会向资源管理器申请资源 会将作业分…

英伟达出品:全球最强大芯片Blackwell来了!采用4nm制程,2080 亿个晶体管组,支持10万亿参数模型

更多精彩内容在 美国加利福尼亚州圣何塞 —— 2024 年 3 月 18 日 —— NVIDIA 于今日宣布推出 NVIDIA Blackwell 平台以赋能计算新时代。该平台可使世界各地的机构都能够在万亿参数的大语言模型(LLM)上构建和运行实时生成式 AI,其成本和能耗…

机器视觉系统选型-精度计算

eg:1.康耐视500w相机拍照,视野为50mm40mm,所使用的视觉工具精度为个像素,求测量精度?(500w相机分辨率为25921944) 相机精度:(即像素分辨率) 相机精度50mm/25920.0193mm 测量精度:测量…

Source Insight使用-添加新的文件类型

目录 遇到的问题解决方法结果 遇到的问题 在Source Insight中我们通常查看.c和.h文件,当使用其查看.java 或者.hal等类型文件时,发现找不到 解决方法 以添加.hal文件为例: 选择Options 下面的File Type Options… 选项。 点击左侧的 “C/C Source F…

mysql索引实现

什么是索引失效 在MySQL中,索引失效指的是查询语句无法有效地使用索引,而必须进行全表扫描。索引失效可能会导致查询性能下降,特别是在处理大量数据时。 索引失效的原因 1.索引列进行了运算或函数操作 如果对索引列进行了运算或使用了函数…

Linux命令进程管理工具top、ps、jps和tar以及守护进程nohup

进程管理工具top ps 概述 top 和 ps 是 Linux 系统中两个非常重要的用于管理和监控进程的命令工具。以下是它们的主要功能和区别: top: 动态视图:top 提供了一个实时动态更新的视图,能够持续显示系统中当前正在运行的进程信息及其…

软考 网工 每日学习打卡 2024/3/19

学习内容 第8章 网络安全 本章主要讲解网络安全方面的基础知识和应用技术。针对考试应该掌握诸如数据加密、报文认 证、数字签名等基本理论,在此基础上深入理解网络安全协议的工作原理,并能够针对具体的 网络系统设计和实现简单的安全解决方案。 本章共有…

C++ —— 类和对象(终)

目录 1. 日期类的实现 1.1 前置 和 后置 重载 1.2 >> 和 << 的重载 2. const 成员 3. 取地址及const取地址操作符重载 4. 再谈构造函数 4.1 构造函数体赋值 4.2 初始化列表 4.3 隐式类型转换 4.4 explict 关键字 5. static 成员 5.1 概念 5.2 特性 …

Java 的强引用、弱引用、软引用、虚引用

1、强引用&#xff08;StrongReference&#xff09; 强引用是使用最普遍的引用。如果一个对象具有强引用&#xff0c;那垃圾回收器绝不会回收它。如下&#xff1a; Object onew Object(); // 强引用 当内存空间不足&#xff0c;Java虚拟机宁愿抛出OutOfMemoryError错误&am…

Java多线程实战-CompletableFuture异步编程优化查询接口响应速度

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️本系列源码仓库&#xff1a;多线程并发编程学习的多个代码片段(github) &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正…

Spring 6.0和SpringBoot 3.0有什么新特性?

Spring在2022年相继推出了Spring Framework 6.0和SpringBoot 3.0&#xff0c;Spring把这次升级称之为新一代框架的开始&#xff0c;下一个10年的新开端 一、问题解析 主要更新内容是以下几个&#xff1a; ● A Java 17 baseline ● Support for Jakarta EE 10 with an EE 9 ba…

永磁同步电机无位置传感器系列(1)——非线性磁链观测器的仿真复现过程

无位置传感器控制&#xff0c;这个方向也是电机控制里面的大热门了。最近在看PLL&#xff0c;中国电机有一篇ESO-PLL获得了23年的高影响力论文&#xff0c;标题如下。因为这篇ESO-PLL需要用到下面这篇英文文献的转子位置观测器&#xff0c;想着就先把这个观测器的文章给复现了。…

【工具】vscode终端打不开

问题 1The terminal process failed to launch: A native exception occurred during launch (forkpty(3) failed.). 参考方案 下面参考链接是针对windows系统上vscode 出现的相同问题的解答 参考链接&#xff1a;https://blog.csdn.net/weixin_40921421/article/details/122…

农业四情监测设备—全面、准确地收集农田环境数据

型号推荐&#xff1a;云境天合TH-Q3】农业四情监测设备是一种高科技的农田监测工具&#xff0c;旨在实时监测和管理农田中的土壤墒情、作物生长、病虫害以及气象条件。这些设备综合运用了传感器、摄像头、气象站等技术手段&#xff0c;能够全面、准确地收集农田环境数据&#x…