如何利用OpenAI Embedding实现网页“相关推荐”功能?

在当今互联网的时代里,个性化已经成为吸引用户关注和提升用户体验的重要策略之一。当我们浏览网站时,经常可以看到一个名为“相关推荐”的版块,它能精准地展示出符合我们兴趣的内容。但是,您是否好奇过这些推荐是如何生成的,它们又是如何如此准确地捕捉到我们的偏好 在本文中我将为大家介绍OpanAI中的embedding,向量计算模型实现相似度/推荐等功能。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

正文

首先我们先阐述一下向量计算模型实现相似度/推荐等功能的理论依据。我们使用OpenAI的embedding接口,把我们输入的关键字变成数学向量,然后在一个空间中是可以存在多个向量的,向量与向量之间存在角度,这里我们使用cosin(cos)表示向量与向量之间的关系,众所周知cos越大,其角度越小,当两个向量的cos值越大,我们就可以理解为这两条数据的相似度越高,也就是文章内容越接近,然后我们把相似度高的数据拿出来,就可以实现推荐功能了。

接下来我们就正式开始实现这个功能了。第一步我们先在Vscode中初始化一个后端项目,使用npm执行,然后完成一些配置项
//初始化后端
npm init -y
//安装OpenAI依赖
npm i openai
//安装dotenv依赖
npm i dotenv

创建文件app.service.mjs在这个文件中我们把模块引入项目中

// 模块化输出client 给各项ai任务调用
import OpenAI from 'openai'
import dotenv from 'dotenv'
dotenv.config({path:'.env'})

export const client = new OpenAI({
    apiKey: process.env.OPENAI_KEY,
    baseURL: 'https://api.302.ai/v1'
})

最后要记得抛出client. 接下来我们创建一个embedding,创建文件create-embeddings.mjs,这里我们的读取的数据已经写好在一个json文件中,所以这里我们使用fs文件系统读取数据

// 更年轻的fs模块
import fs from 'fs/promises';

获取app.service.mjs抛出的client

import {client} from './app.service.mjs'

在我们文件create-embedding.mjs中的主要任务是将源数据posts.json里面的所有内容计算向量,所以这里我们准备了两个变量,一个存放源数据inputFilePath,一个存放向量计算后的数据outputFilePath.现在我们读取源数据中的数据并JSON化数据,使用fs文件系统中的readFile

const data = await fs.readFile(inputFilePath, 'utf8');
const posts = JSON.parse(data)

这里我们加了一个await是因为fs/promises返回的是一个Promise对象,这里我们需要使用到await. 定义一个新数组postsWithEmbedding存放向量计算后的数据,现在我们遍历JSON化后的源数据posts并且解构数据title,category.然后使用client.embedding.create()创建一个embedding接口,这里我们需要给一个模型model和输入input,当接口embedding接口数据处理完成之后,我们把解构出来的title,category,以及向量计算后的数据存入postsWithEmbedding中。最后把数据写入outputFilePath中,我们这个创建embedding接口这个文件就算是写好了。

// 先把所有的内容计算向量
// 更年轻的fs模块
import fs from 'fs/promises';
//将openai的实例封装
import {client} from './app.service.mjs'

//源数据,麻烦
const inputFilePath = './data/posts.json';
// 整整数据 让每一个数据多一个1536维的向量数字
const outputFilePath = './data/posts_with_embedding.json';

// promisify  重点 
const data = await fs.readFile(inputFilePath, 'utf8');
const posts = JSON.parse(data)
// 新数组
const postsWithEmbedding = [];

for(const {title,category} of posts){
    const response = await client.embeddings.create({
        model: 'text-embedding-ada-002',
        // 当搜索vue是,也可以搜索到vue相关的文章 搜索vue+分类
        input: `标题 ${title} 分类 ${category}`
    })
    postsWithEmbedding.push({
        title,
        category,
        embedding: response.data[0].embedding  // 取得embedding的第一个元素
    })
}

await fs.writeFile(outputFilePath, JSON.stringify(postsWithEmbedding))

// console.log(data);

最后一部分我们实现数据查询就好了,创建文件semantic-search.mjs 获取所有的向量计算后的数据

const posts = JSON.parse(await fs.readFile(inputFilePath));

计算向量的余弦相似度函数(这个函数我们直接在网上找就好了)

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));
    const lengthV2 = Math.sqrt(v2.reduce((acc, curr) => acc + curr * curr, 0));
  
    // 计算余弦相似度
    const similarity = dotProduct / (lengthV1 * lengthV2);
  
    return similarity;
  };

然后我再定义一个变量。用来存放我们想要查询的内容,并进行向量计算。最后解构出向量值

const searchText = 'vue组件开发'
//先向量化
const response = await client.embeddings.create({
    model:'text-embedding-ada-002',
    input: searchText
})
//要推荐的原文embedding
const { embedding } = response.data[0]

最后一步就是遍历数据,对数据中进行一个排序,取得前三项

const results = posts.map(item=>({
    ...item,
    similarity:cosineSimilarity(embedding,item.embedding)
}))

    .sort((a,b)=>a.similarity - b.similarity)
    .reverse()
    .slice(0,3)
    .map((item,index)=>`${index+1},${item.title},${item.category}`)
    .join('\n')

console.log(results);

完整代码

// nlp 相似性搜索
import fs from 'fs/promises'
import { client} from './app.service.mjs'

const inputFilePath = './data/posts_with_embedding.json';

// select * 让数据在内存之中
const posts = JSON.parse(await fs.readFile(inputFilePath));

// 计算向量的余弦相似度 cosine 
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));
    const lengthV2 = Math.sqrt(v2.reduce((acc, curr) => acc + curr * curr, 0));
  
    // 计算余弦相似度
    const similarity = dotProduct / (lengthV1 * lengthV2);
  
    return similarity;
  };
// vue | 组件 | 开发  LLM 基于语义搜索,而不是简单的文字匹配
const searchText = 'vue组件开发'
//先向量化
const response = await client.embeddings.create({
    model:'text-embedding-ada-002',
    input: searchText
})
//要推荐的原文embedding
const { embedding } = response.data[0]
// posts每一项embedding 进行cosin计算
const results = posts.map(item=>({
    ...item,
    similarity:cosineSimilarity(embedding,item.embedding)
}))

    .sort((a,b)=>a.similarity - b.similarity)
    .reverse()
    .slice(0,3)
    .map((item,index)=>`${index+1},${item.title},${item.category}`)
    .join('\n')

console.log(results);

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

感谢大家阅读,若有不足,恳请各位指出!!!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

读者福利:如果大家对大模型感兴趣,这套大模型学习资料一定对你有用

对于0基础小白入门:

如果你是零基础小白,想快速入门大模型是可以考虑的。

一方面是学习时间相对较短,学习内容更全面更集中。
二方面是可以根据这些资料规划好学习计划和方向。

包括:大模型学习线路汇总、学习阶段,大模型实战案例,大模型学习视频,人工智能、机器学习、大模型书籍PDF。带你从零基础系统性的学好大模型!

😝有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓
在这里插入图片描述

👉AI大模型学习路线汇总👈

大模型学习路线图,整体分为7个大的阶段:(全套教程文末领取哈)

第一阶段: 从大模型系统设计入手,讲解大模型的主要方法;

第二阶段: 在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用;

第三阶段: 大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统;

第四阶段: 大模型知识库应用开发以LangChain框架为例,构建物流行业咨询智能问答系统;

第五阶段: 大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型;

第六阶段: 以SD多模态大模型为主,搭建了文生图小程序案例;

第七阶段: 以大模型平台应用与开发为主,通过星火大模型,文心大模型等成熟大模型构建大模型行业应用。

👉大模型实战案例👈

光学理论是没用的,要学会跟着一起做,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

在这里插入图片描述

👉大模型视频和PDF合集👈

观看零基础学习书籍和视频,看书籍和视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
在这里插入图片描述
在这里插入图片描述

👉学会后的收获:👈

• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;

• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;

• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;

• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。

👉获取方式:

😝有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓
在这里插入图片描述

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值