巧用Embedding 模块实现语义化搜索

还在用 LIKE 查询吗?简单的关键词匹配无法准确捕捉文本中的语义信息。

为了解决这一问题,我们可以借助 嵌入向量(embedding) 技术,将文本转换为高维数学向量,进行更加智能的语义化搜索。本文将详细介绍如何使用 OpenAI 的 embedding 模块,以及如何在此基础上实现语义化搜索。

什么是Embedding?

Embedding 是一种将文本、图像等输入数据映射到一个高维空间中,形成一个向量的过程。在这个高维空间里,相似的文本会被映射到彼此靠近的位置。这种表示方式便于我们通过数学计算(如余弦相似度)来比较不同文本的语义相似性。

语义化搜索

在传统的搜索系统中,我们通常使用关键词匹配(如模糊搜索、正则表达式等)。然而,这些方法在处理自然语言语义时表现不佳。例如,当用户输入“百度前端面试题”,我们不仅要匹配关键词,还要理解搜索内容的语义,找到与其相关的文章。

为此,我们可以使用嵌入向量(embedding) 。向量可以将文本转化为高维空间中的点,每个点表示该文本的语义。通过计算用户输入与文章向量的相似度,我们可以找到最相关的内容。这种方法比传统的字符串匹配更加语义化和智能。

Embedding 模块的使用

安装依赖

首先,我们需要安装项目中使用的依赖包。在项目根目录下,执行以下命令安装依赖:

npm install dotenv openai readline fs/promises

其中涉及到隐私的API密钥就要使用到 dotenv 模块用于从.env文件中加载环境变量。最主要运用的是OPENAIEmbedding 模块,所以要安装 openai 用于与其API进行通信。readline 模块用于处理用户的命令行输入。 fs/promises是Node.js原生的文件系统模块,支持使用Promise的方式读取和写入文件。

文本转化成向量

首先,我们来看如何使用 OpenAI 的 embedding 模块将文本转换为向量。

import OpenAI from 'openai'; // 引入OpenAI模块
import dotenv from 'dotenv'; // 引入dotenv模块以加载环境变量
dotenv.config({
    path: '.env' // 配置环境变量文件的路径
});

// 初始化OpenAI客户端
const client = new OpenAI({
    apiKey: process.env.OPENAI_KEY, // 从环境变量中加载OpenAI API密钥
    baseURL: process.env.BASE_URL   // 基础URL(如果需要自定义,可以修改)
});

// 使用embedding将文字转为向量
const response = await client.embeddings.create({
    model: 'text-embedding-ada-002', // 指定模型,OpenAI 提供的预训练嵌入模型
    input: "百度前端面试题"            // 要转换为向量的文本
});

// 打印生成的嵌入向量
console.log(response.data[0].embedding);

首先初始化 OpenAI 客户端,使用 dotenv 模块加载环境变量文件 .env,以确保 API 密钥安全。client 对象初始化时,通过 apiKeybaseURL 指定了 API 访问密钥和请求的基础地址。

生成 Embedding是调用 client.embeddings.create 方法生成文本嵌入向量。参数包括 modelinput,其中 model 使用了 text-embedding-ada-002(这是 OpenAI 提供的一个用于文本嵌入的模型),input 是需要进行向量化的文本,在这个示例中为“百度前端面试题”。

可以看到已经将我们输入的文本转化成了一个有上千维度的向量。

在这里插入图片描述

这个生成的向量数据可以表示输入文本的语义信息。对于不同的文本,我们可以生成相应的向量并通过数学计算(如余弦相似度)来衡量这些文本之间的语义相似性。接下来我们将基于此进一步讨论如何使用这些向量实现语义化搜索。

实现语义化搜索

文件转向量

这里我们将存放文章数组的文件生成对应的嵌入向量为例,并将这些向量保存到一个新的文件中。这一过程使用了 OpenAI 的 embedding 模块,将文本转换为高维向量,最终存储用于后续的语义搜索。

import fs from 'fs/promises';  // 引入fs模块以便使用promise API读取和写入文件
import OpenAI from 'openai';   // 引入OpenAI模块,用于调用API
import dotenv from 'dotenv';   // 引入dotenv模块,用于加载环境变量

// 加载环境变量
dotenv.config({
    path: '.env'
});

// 初始化OpenAI客户端,传入API密钥和基础URL
const client = new OpenAI({
    apiKey: process.env.OPENAI_KEY,
    baseURL: process.env.BASE_URL
});

// 输入和输出文件路径
const inputFilePath = './data/posts.json';  // 原始数据文件
const outputFilePath = './data/posts_with_embeddings.json';  // 输出文件

// 读取原始文章数据
const data = await fs.readFile(inputFilePath, 'utf-8');
const posts = JSON.parse(data);  // 将读取到的JSON数据解析为JavaScript对象

const postsWithEmbedding = [];  // 创建一个数组用于存储带嵌入向量的文章

// 遍历每篇文章,生成嵌入向量
for (const { title, category } of posts) {
    // 生成嵌入向量,基于文章标题
    const response = await client.embeddings.create({
        model: 'text-embedding-ada-002',  // 使用text-embedding-ada-002模型
        input: `标题: ${title}`  // 将文章标题作为嵌入输入
    });

    // 将标题、分类和生成的嵌入向量保存到新的数据结构中
    postsWithEmbedding.push({
        title,
        category,
        embedding: response.data[0].embedding  // 提取生成的嵌入向量
    });
}

// 将生成的文章和嵌入向量保存到输出文件
await fs.writeFile(outputFilePath, JSON.stringify(postsWithEmbedding));

fs/promises这个模块提供了文件系统的异步操作版本,通过 await 可以方便地读取和写入文件。

读取输入数据使用 fs.readFile 从指定路径读取包含文章数据的 JSON 文件。文件中的数据被解析为一个包含文章对象的数组,每个文章对象包含 titlecategory

生成嵌入向量是通过遍历每篇文章,使用 title 生成文本的嵌入向量。通过 OpenAI 的 embeddings.create 接口,指定模型(text-embedding-ada-002)并将文章标题作为输入。 调用后,API 返回一个嵌入向量(高维向量),该向量表示输入文本的语义信息。

对于每篇文章,将生成的向量和文章的 titlecategory 一起存入 postsWithEmbedding 数组中。

向量计算

通过 OpenAI 的 embedding 模块生成向量后,我们可以利用这些向量来比较用户输入与现有内容的相似度,实现语义化搜索。

import fs from 'fs/promises'; // 引入文件系统模块,支持Promise
import OpenAI from 'openai';   // 引入OpenAI模块
import dotenv from 'dotenv';   // 引入dotenv模块
dotenv.config({
    path: '.env'
});

// 初始化OpenAI客户端
const client = new OpenAI({
    apiKey: process.env.OPENAI_KEY,
    baseURL: process.env.BASE_URL
});

// 读取文章数据及其嵌入向量
const inputFilePath = './data/posts_with_embeddings.json';
const data = await fs.readFile(inputFilePath, 'utf-8');
const posts = JSON.parse(data); // 解析读取的JSON数据

// 计算向量之间的余弦相似度
const cosineSimilarity = (v1, v2) => {
    const dotProduct = v1.reduce((acc, curr, i) => acc + curr * v2[i], 0);  // 计算点积
    const lengthV1 = Math.sqrt(v1.reduce((acc, curr) => acc + curr * curr, 0)); // 计算v1向量的长度
    const lengthV2 = Math.sqrt(v2.reduce((acc, curr) => acc + curr * curr, 0)); // 计算v2向量的长度
    return dotProduct / (lengthV1 * lengthV2); // 返回余弦相似度
};

// 输入要搜索的内容
const input = "前端性能优化";

// 生成输入文本的嵌入向量
const response = await client.embeddings.create({
    model: 'text-embedding-ada-002',
    input: input
});

const { embedding } = response.data[0];

// 计算输入向量与每篇文章向量的相似度并排序
const results = posts.map(item => ({
    ...item,
    similarity: cosineSimilarity(embedding, item.embedding)
}))
.sort((a, b) => b.similarity - a.similarity) // 按相似度降序排序
.slice(0, 3)  // 只取最相似的3篇文章
.map((item, index) => `${index + 1}. ${item.title} - ${item.category}`);

// 打印搜索结果
console.log(`\n搜索结果:\n${results.join("\n")}\n`);


posts_with_embeddings.json 文件中读取包含文章标题、分类及其嵌入向量的数据。这些数据提前通过 OpenAI 的 embedding 模块生成并存储在文件中。

计算余弦相似度 cosineSimilarity 函数用于计算两组向量之间的余弦相似度。通过向量的点积及其长度,计算出两个向量的夹角,夹角越小,相似度越高。余弦相似度是一个常用的衡量向量之间相似性的指标,其值在 -11 之间,1 表示两个向量完全相同,0 表示它们不相关,-1 表示它们完全相反。在这个搜索系统中,余弦相似度越高的文章越符合用户的输入语义。

使用 client.embeddings.create 方法将用户输入的文本转换为向量,用以与文章的嵌入向量进行对比。遍历每篇文章的嵌入向量,与输入文本的向量进行相似度计算,将结果存入一个新的数组。按相似度降序排序,取出最相似的3篇文章,并输出结果。

在这里插入图片描述

总结

通过本文的讲解,我们实现了一个简单的语义化搜索系统。首先,我们介绍了如何使用 OpenAI 的 embedding 模块将文本转换为嵌入向量。然后,基于这些向量,我们可以通过计算余弦相似度,来衡量不同文本之间的语义相似性,从而实现智能搜索。

这种语义化搜索的优势在于,它不仅能找到包含特定关键词的文章,还能理解文本的语义,提供更加精准的搜索结果!文章编写不易,如果对你有帮助可以点个赞哦😊!

如何学习大模型

现在社会上大模型越来越普及了,已经有很多人都想往这里面扎,但是却找不到适合的方法去学习。

作为一名资深码农,初入大模型时也吃了很多亏,踩了无数坑。现在我想把我的经验和知识分享给你们,帮助你们学习AI大模型,能够解决你们学习中的困难。

我已将重要的AI大模型资料包括市面上 AI大模型各大白皮书、AGI大模型系统学习路线、AI大模型视频教程、实战学习,等录播视频免费分享 出来,需要的小伙伴可以扫取。

一、AGI大模型系统学习路线

很多人学习大模型的时候没有方向,东学一点西学一点,像只无头苍蝇乱撞,我下面分享的这个学习路线希望能够帮助到你们学习AI大模型。

在这里插入图片描述

二、AI大模型视频教程

在这里插入图片描述

三、AI大模型各大学习书籍

在这里插入图片描述

四、AI大模型各大场景实战案例

在这里插入图片描述

五、结束语

学习AI大模型是当前科技发展的趋势,它不仅能够为我们提供更多的机会和挑战,还能够让我们更好地理解和应用人工智能技术。通过学习AI大模型,我们可以深入了解深度学习、神经网络等核心概念,并将其应用于自然语言处理、计算机视觉、语音识别等领域。同时,掌握AI大模型还能够为我们的职业发展增添竞争力,成为未来技术领域的领导者。

再者,学习AI大模型也能为我们自己创造更多的价值,提供更多的岗位以及副业创收,让自己的生活更上一层楼。

因此,学习AI大模型是一项有前景且值得投入的时间和精力的重要选择。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值