clearwind

clearwind

首页
分类
登录 →
clearwind

clearwind

首页 分类
登录
  1. 首页
  2. 🚀AI
  3. 基于Embedding高级搜索

基于Embedding高级搜索

0
  • 🚀AI
  • 发布于 2024-07-12
  • 78 次阅读
clearwind
clearwind

什么是向量

在数学中,向量(也称为欧几里得向量、几何向量),指具有大小(magnitude)和方向的量。二维平面中,一个向量表示xy坐标轴的坐标点 `A(1,2)`,在编程领域,一个二维向量对应的就是一个大小为二的float类型的数组。

文本向量化

文本向量化是指,利用大模型可以把一个字、一个词或一段话映射为一个多维向量。

在LangChain4j中向量模型OpenAiEmbeddingModel对话展示文本向量:

public static void main(String[] args) {
    OpenAiEmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder()
            .baseUrl("http://langchain4j.dev/demo/openai/v1")
            .apiKey("demo")
            .build();

    Response<Embedding> embed = embeddingModel.embed("你好,我叫风");
    System.out.println(embed.content().toString());
    System.out.println(embed.content().vector().length);
}

// 输出结果

Embedding { vector = [-0.010026788, -0.009126372, -0.0085925525, ......, -0.045200944] }
1536

从结果可以知道"你好,我叫风"这句话经过OpenAiEmbeddingModel向量化之后得到的一个长度为1536的float数组。

基于向量来判断两句话之间的相似度。

1536是固定的,不会随着句子长度而变化

向量相似度

向量模型也是经过大量机器学习训练之后产生,向量模型效果与其对自然语言理解的程度成正相关。如果两句话对应的向量相似,那么就表示大模型对这两句话语义理解比较相似,在假设大模型的理解比较理性的情况下,就表示这两句话的意思越相近。

比如可以通过计算两个坐标的余弦相似度(代码是ChatGPT生成的):

public class CosineSimilarity {
    // 计算两个向量的点积
    public static double dotProduct(double[] vectorA, double[] vectorB) {
        double dotProduct = 0;
        for (int i = 0; i < vectorA.length; i++) {
            dotProduct += vectorA[i] * vectorB[i];
        }
        return dotProduct;
    }
    // 计算向量的模
    public static double vectorMagnitude(double[] vector) {
        double magnitude = 0;
        for (double component : vector) {
            magnitude += Math.pow(component, 2);
        }
        return Math.sqrt(magnitude);
    }
    // 计算余弦相似度
    public static double cosineSimilarity(double[] vectorA, double[] vectorB) {
        double dotProduct = dotProduct(vectorA, vectorB);
        double magnitudeA = vectorMagnitude(vectorA);
        double magnitudeB = vectorMagnitude(vectorB);
        
        if (magnitudeA == 0 || magnitudeB == 0) {
            return 0; // 避免除以零
        } else {
            return dotProduct / (magnitudeA * magnitudeB);
        }
    }
    // 通过向量的相近度近似计算语义的相似度
    public static void main(String[] args) {
        // 示例向量
        double[] vectorA = {1, 2, 3};
        double[] vectorB = {3, 2, 1};
        
        // 计算余弦相似度
        double similarity = cosineSimilarity(vectorA, vectorB);
        System.out.println("Cosine Similarity: " + similarity);
    }
}

向量数据库

向量数据库可以存储向量模型生成的向量,就可以利用向量数据库来计算两个向量之间的相似度,或者根据一个向量查找与之相似的向量。

在LangChain4j中,EmbeddingStore表示向量数据库,它有20个实现类:

  1. AstraDbEmbeddingStore

  2. AzureAiSearchEmbeddingStore

  3. CassandraEmbeddingStore

  4. ChromaEmbeddingStore

  5. ElasticsearchEmbeddingStore

  6. InMemoryEmbeddingStore

  7. InfinispanEmbeddingStore

  8. MemoryIdEmbeddingStore

  9. MilvusEmbeddingStore

  10. MinimalEmbeddingStore

  11. MongoDbEmbeddingStore

  12. Neo4jEmbeddingStore

  13. OpenSearchEmbeddingStore

  14. PgVectorEmbeddingStore

  15. PineconeEmbeddingStore

  16. QdrantEmbeddingStore

  17. RedisEmbeddingStore

  18. VearchEmbeddingStore

  19. VespaEmbeddingStore

  20. WeaviateEmbeddingStore

使用Redis操作向量

首先添加依赖:

<dependency>
	<groupId>dev.langchain4j</groupId>
	<artifactId>langchain4j-redis</artifactId>
	<version>${langchain4j.version}</version>
</dependency>

注意普通的Redis是不支持向量存储和查询的,需要额外的redisearch模块,

使用docker来运行一个带有redisearch模块的redis容器`docker run -p 6379:6379 redis/redis-stack-server:latest`

存储向量到redis

RedisEmbeddingStore embeddingStore = RedisEmbeddingStore.builder()
    .host("127.0.0.1")
    .port(6379)
    .dimension(1536)
    .build();

// 生成向量
Response<Embedding> embed = embeddingModel.embed("我是风");

// 存储向量
embeddingStore.add(embed.content());

// 清空向量
redis-cli FT.DROPINDEX embedding-index DD

匹配向量

使用“我的名字叫风”来查找到“我是风”

public static void main(String[] args) {

    OpenAiEmbeddingModel embeddingModel = OpenAiEmbeddingModel.builder()
            .baseUrl("http://langchain4j.dev/demo/openai/v1")
            .apiKey("demo")
            .build();

    RedisEmbeddingStore embeddingStore = RedisEmbeddingStore.builder()
            .host("127.0.0.1")
            .port(6379)
            .dimension(1536)
            .build();

    // 生成向量
    Response<Embedding> embed = embeddingModel.embed("我的名字叫周瑜");

    List<EmbeddingMatch<TextSegment>> result = embeddingStore.findRelevant(embed.content(), 4);
    for (EmbeddingMatch<TextSegment> embeddingMatch : result) {
        System.out.println(embeddingMatch.score());
    }

}

// 执行结果
0.9765566289425

// 提示词换成:今天天气很好,执行结果
0.8937962949275

看上去似乎分数差别不大,应该是小数位很多,分数精度比较高,两个分数还是有一定距离。

向量搜索

基于向量快速的得到和文本相似的文本

// 生成向量
TextSegment textSegment1 = TextSegment.textSegment("客服电话是400-8888888");
TextSegment textSegment2 = TextSegment.textSegment("客服工作时间是周一到周五");
TextSegment textSegment3 = TextSegment.textSegment("客服投诉电话是400-9999999");
Response<Embedding> embed1 = embeddingModel.embed(textSegment1);
Response<Embedding> embed2 = embeddingModel.embed(textSegment2);
Response<Embedding> embed3 = embeddingModel.embed(textSegment3);

// 存储向量
embeddingStore.add(embed1.content(), textSegment1);
embeddingStore.add(embed2.content(), textSegment2);
embeddingStore.add(embed3.content(), textSegment3);

向量数据库中添加三条客户相关的知识,并且通过TextSegment把原始文本也存入了Redis,相当于Redis中现在存储了三条原始文本以及对应的向量,然后查询:

// 生成向量
Response<Embedding> embed = embeddingModel.embed("客服电话多少");

// 查询
List<EmbeddingMatch<TextSegment>> result = embeddingStore.findRelevant(embed.content(), 5);
for (EmbeddingMatch<TextSegment> embeddingMatch : result) {
    System.out.println(embeddingMatch.embedded().text() + ",分数为:" + embeddingMatch.score());
}

客服电话是400-8558558,分数为:0.9529553055763
客服投诉电话是400-8668668,分数为:0.9520588517189
客服工作时间是周一到周五,分数为:0.9305278658864999

标签: #Java 6 #AI 7 #LangChain4j 5
相关文章
简述 Transformer 训练计算过程(刷新渲染)

简述 Transformer 训练计算过程(刷新渲染) 2025-01-11 23:54

Step1-定义数据集 用于创建 ChatGPT 的数据集为 570 GB。假设数据集为一下内容: 白日依山尽,黄河入海流。 马无夜草不肥,人无横财不富。 天行健,君子以自强不息,地势坤,君子以厚德载物。 Step2-计算词汇量

基于Deepseek的AI试题问答

基于Deepseek的AI试题问答 2025-02-28 09:46

需求 项目目标‌ 构建一个基于大模型微调的AI试题问答系统,支持数学、历史、英语等多学科试题的智能解析、答案生成及知识点关联,适配考试场景的自动评分与错题分析功能‌。 核心功能需求‌ ‌试题交互与解析‌:支持选择、填空、判断、问答等题型交互,自动生成试题解析(含解题步骤与知识点标注)‌。 ‌智能查询

基于 internlm2 和 LangChain 搭建你的知识库

基于 internlm2 和 LangChain 搭建你的知识库 2025-02-27 14:25

环境配置 internlm2 模型部署 创建虚拟环境 conda create -n deepseek_rag python=3.10 -y conda activate deepseek_rag 并在环境中安装运行 demo 所需要的依赖 # 升级pip python -m pip install

xtuner微调大模型

xtuner微调大模型 2025-02-26 09:31

构建环境 # 创建虚拟环境 conda create --name xtuner-env python=3.10 -y conda activate xtuner-env # 安装xtuner git clone https://github.com/InternLM/xtuner.git cd

Llama-Factory 微调全过程

Llama-Factory 微调全过程 2025-01-13 22:28

数据集 数据集下载:通过ModelScope获取原始数据集https://modelscope.cn/datasets/w10442005/ruozhiba_qa/summary git clone https://www.modelscope.cn/datasets/w10442005/ruozh

矩阵分解 2025-01-11 15:48

矩阵分解是一种通过将较大的矩阵分解为多个小矩阵已降低计算复杂度的技术,在模型训练微调上,通常用于简化模型、提高训练效率。矩阵分解有多种形式,一下是几种常见的模型微调权重分解方法: 奇异值分解 将矩阵分解为三个矩阵乘积的方法: W=U \Sigma V^{T} 其中: W是原始权重矩阵。 U和V是正交

目录
  • clearwind
  • 微信小程序

导航菜单

  • 首页
  • 分类
Copyright © 2024 your company All Rights Reserved. Powered by clearwind.
皖ICP备19023482号