likes
comments
collection
share

前端开发AI新尝试,使用Embeddings模拟实现浏览器搜索推荐,简直不要太高级!!!Embeddings是机器学习和

作者站长头像
站长
· 阅读数 20

当你在浏览器中输入内容时,会出现以下这种的推荐:

前端开发AI新尝试,使用Embeddings模拟实现浏览器搜索推荐,简直不要太高级!!!Embeddings是机器学习和

前端开发AI新尝试,使用Embeddings模拟实现浏览器搜索推荐,简直不要太高级!!!Embeddings是机器学习和

大家肯定会很好奇,这种炫酷的功能是怎么实现的?

前端开发AI新尝试,使用Embeddings模拟实现浏览器搜索推荐,简直不要太高级!!!Embeddings是机器学习和

下面我将为大家介绍一种全新的AI开发方式--Embedding数据向量化,来实现这一推荐搜索功能。

什么是Embeddings

Embeddings是机器学习和深度学习中一个重要的概念,主要用于将高维的、通常是稀疏的、非数值型的数据转换为低维的、密集的、数值型的向量表示。这些向量通常位于一个连续的向量空间中,能够有效地捕捉原始数据中的模式和结构。

在计算机的内部世界,任何事物的表现形式都是一串串简单的数字,在传统的表结构表示数据时,传入计算机内部的数据也只能是二维的,这种简单结构的数据在表现复杂的事物时难免会出现模糊。

为了解决这个问题,出现一种全新的数据表现形式--向量数据。向量数据可以将一个事物的特征具体细分为多个点,然后每个点都是全新的一个维度,连接这些点组成的一个多维向量数据。

比如一个苹果,计算机是怎么认识的他的呢?

前端开发AI新尝试,使用Embeddings模拟实现浏览器搜索推荐,简直不要太高级!!!Embeddings是机器学习和

在我们人的大脑中,认识一个苹果可以分为以下几个过程:

  1. 苹果是浅红色的
  2. 苹果是椭球状的
  3. 苹果带有它特定的香味 4.....

在计算内部,一个苹果的表示也是将这一个个的特点转化为一个个的多维坐标点,然后将这些点连接起来组成一个向量数据,最后通过大模型的训练,来判断所识别的物品是否为苹果。浏览器推荐功能的实现原理,也和上述过程类似,下面我将通过一个demo来为大家展示。

创建向量数据

本demo展示所用的语言为Node.js。

一.创建自然语言数据

创建文件:posts.json里面存放的数据为自然语言数据,形如:

前端开发AI新尝试,使用Embeddings模拟实现浏览器搜索推荐,简直不要太高级!!!Embeddings是机器学习和

二.将自然语言数据转为向量数据

要实现该功能我们需要在项目中引入opeanai的emdedding库,借助ai帮我们将数据向量化。

新建文件夹:

前端开发AI新尝试,使用Embeddings模拟实现浏览器搜索推荐,简直不要太高级!!!Embeddings是机器学习和

app.service.mjs文件夹中,我们导入openai的接口服务:

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'
})

注意:这段代码中的apiKey为自己特有的,本项目中将该key封装在了.env文件当中

create-embedding.mjs文件夹中,使用openai中的embedding模块创建向量数据:

import fs from 'fs/promises'
import { client } from './app.service.mjs'
const inputFilePath = './data/posts.json'
const outputFilePath = './data/posts_with_embeddings.json'
const data = await fs.readFile(inputFilePath, 'utf-8')
//console.log(data)
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-router react
        input: `标题:${title} 分类:${category}`
    })
    postsWithEmbedding.push({
        title,
        category,
        embedding: response.data[0].embedding
    })
}
await fs.writeFile(outputFilePath, JSON.stringify(postsWithEmbedding))

这段代码的主要目的是从一个JSON文件中读取一系列自然语言数据(posts),然后使用OpenAI的API为每个帖子的标题和分类计算嵌入向量,并将原始数据与计算得到的嵌入向量一起保存到一个新的JSON文件中。下面是代码的详细梳理:

  1. 导入必要的模块:

    • import fs from 'fs/promises';: 导入Node.js的fs模块的Promises版本,用于异步文件操作。
    • import { client } from './app.service.mjs';: 导入自定义的client对象,它封装了与OpenAI API交互的功能。
  2. 定义输入输出文件路径:

    • const inputFilePath = './data/posts.json';: 定义输入文件路径,这是包含原始帖子数据的JSON文件。
    • const outputFilePath = './data/posts_with_embeddings.json';: 定义输出文件路径,这是将保存带有嵌入向量的帖子数据的JSON文件。
  3. 读取输入文件:

    • 使用fs.readFile异步读取输入文件的内容,并以UTF-8编码解析为字符串。
  4. 解析数据:

    • const posts = JSON.parse(data);: 将读取到的字符串数据解析为JavaScript对象数组。
  5. 计算嵌入向量并构建新数组:

    • 遍历posts数组,对于每一个帖子,使用client.embeddings.create方法调用OpenAI的嵌入向量计算API。
    • input: 标题:title分类:{title} 分类:title分类:{category}``: 构造输入字符串,包括帖子的标题和分类。
    • model: 'text-embedding-ada-002': 指定使用的嵌入模型。
    • response.data[0].embedding: 获取API响应中的嵌入向量。
    • 将原始的帖子数据与计算得到的嵌入向量合并,添加到postsWithEmbedding数组中。
  6. 写入输出文件:

    • 使用fs.writeFilepostsWithEmbedding数组转换为JSON字符串,并写入到输出文件中。

最终,这段代码会生成一个新的JSON文件,其中每个帖子对象都额外包含了一个1536维的嵌入向量,这个向量是基于帖子的标题和分类计算得到的。这样的处理对于后续的数据分析、搜索和推荐系统等应用非常有用。

执行成功这段代码后,我们可以在create-embedding.mjs文件中看到所有给出的数据全部都向量化:

前端开发AI新尝试,使用Embeddings模拟实现浏览器搜索推荐,简直不要太高级!!!Embeddings是机器学习和

实现搜索推荐功能

在多维空间中,判断两个数据的相似程度可以通过判断两个向量之间的夹角大小,如果两个数据之间的夹角越大那么它们之间的相似程度就越低,反之越大。那么在数学中就可以通过判断两个向量数据之间的cos大小来判断它们之间的夹角大小,也正是它们之间的相关程度的大小。下面我将通过代码来为大家展示这一过程。


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

const inputFilePath = './data/posts_with_embeddings.json'
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;
};

const searchText = '什么时候去旅游'
// 先向量化一下
const response = await client.embeddings.create({
    model: 'text-embedding-ada-002',
    input: searchText
})
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);

这段代码的思路可以总结为如下过程:

  1. 加载数据:

    • ./data/posts_with_embeddings.json文件中读取已经包含了嵌入向量的帖子数据。
  2. 定义相似度计算逻辑:

    • 实现cosineSimilarity函数,用于计算两个向量之间的余弦相似度,这是衡量两个向量方向相似性的标准方法。
  3. 向量化查询文本:

    • 使用OpenAI的text-embedding-ada-002模型将用户的查询文本转化为嵌入向量。
  4. 计算相似度并排序:

    • 遍历所有帖子,对每个帖子的嵌入向量与查询文本的嵌入向量进行余弦相似度计算。
    • 将计算结果与帖子信息一起存储,形成一个新的数组,其中包含每个帖子的标题、分类以及与查询文本的相似度。
  5. 筛选最相似的结果:

    • 根据相似度对所有帖子进行排序,选取相似度最高的几条帖子(本例中是前三条)。
  6. 输出结果:

    • 将筛选出的最相似帖子的信息格式化为易读的字符串,并打印到控制台上。

这一过程的核心在于利用嵌入向量来捕捉文本的语义信息,从而实现基于语义的搜索而非简单的关键词匹配,提高了搜索的准确性和相关性。

实现效果:

当输入:什么时候去旅行

前端开发AI新尝试,使用Embeddings模拟实现浏览器搜索推荐,简直不要太高级!!!Embeddings是机器学习和

当输入: 如何制作美食

前端开发AI新尝试,使用Embeddings模拟实现浏览器搜索推荐,简直不要太高级!!!Embeddings是机器学习和

以上便是本篇文章的主要内容,希望对大家有所帮助,谢谢大家,如果有用的话,还请大家多多点赞。

前端开发AI新尝试,使用Embeddings模拟实现浏览器搜索推荐,简直不要太高级!!!Embeddings是机器学习和

转载自:https://juejin.cn/post/7390319492142071847
评论
请登录