基于Es和智普AI实现的语义检索

news2024/11/15 23:37:17

1、什么是语义检索

语义检索是一种利用自然语言处理(NLP)和人工智能(AI)技术来理解搜索查询的语义,以提供更准确和相关搜索结果的搜索技术,语义检索是一项突破性的技术,旨在通过深入理解单词和短语的含义及上下文来提供更为准确的搜索结果。与传统的基于关键词的搜索不同,语义检索侧重于查询的意图和语境,而不仅仅是关键词的直接匹配。这种搜索方式可以显著提高搜索结果的准确性和相关性,尤其适用于复杂查询和模糊不清的搜索需求

上面是比较"官方"的解释,举个例子来简单说明一下吧:

比如现在有一条数据,叫诸葛亮,输入关键字孔明,传统的查询(关系型数据)和搜索引擎(Elasticsearch)是查不出来诸葛亮这条数据的,因为这二者都是通过关键字来匹配的,但是语义检索能够查出来,这就是语义检索最大的亮点

2、语义检索能做什么

除了上面提到的文字检索,还可以实现基于文档内容(本质还是文字检索)、图片、和视频内容的检索

3、语义检索的实现思路

Elasticsearch在7.X版本开始支持knn查询,也就是近似查询(也叫向量查询),关于knn的深入理解就不在这里过多的赘述了,其底层原理我也不是很懂,整体的思路如下图:

其中图片和视频的转换为向量的时候有两种方式,一种是直接将图片和视频转换为向量,这种相对较复杂,第二种是通过把图片和视频交给大模型,让其理解其中的内容,并将内容提取出来转换为文字,然后将文字再转换为向量存入es

4、操作实践

准备工作:

Elasticsearch 8.12.0

智普AI向量转换:智谱AI开放平台(embedding-3)

1、建立Es索引mapping,其中几个关键的属性字段:

dims:向量的纬度数,本质就是一个float类型的数组,我自己测试的结果是1024效果比较好,一般这个值有738,1024,2048,具体要看模型支持多少唯独

type:int8_hnsw,这个是es8.8才提供的特性

{
  "my_embedding": {
    "mappings": {
      "dynamic": "strict",
      "properties": {
        "department": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword"
            }
          },
          "analyzer": "my_analyzer"
        },
        "embedding": {
          "type": "dense_vector",
          "dims": 1024,
          "index": true,
          "similarity": "l2_norm",
          "index_options": {
            "type": "int8_hnsw",
            "m": 16,
            "ef_construction": 100
          }
        }
      }
    }
  }
}

2、通过智普AI生成向量数据写入Elasticsearch:Authorization填写自己申请的智普的授权码

    @Test
    public void vectorWriteV1() throws Exception {
//        List<String> text = Stream.of("刘玄德", "桃园三结义", "刘备", "毛岸英", "毛泽东思想", "新中国", "江青", "杨开慧", "毛润之", "三国", "武当山", "二万五千里长征", "太极拳").collect(Collectors.toList());
        List<String> text = Stream.of(
//                "武当山不仅是中国道教文化的圣地,也是自然与人文景观的完美融合之地。游客在这里可以体验丰富的历史文化和壮丽的自然风光",
//                "庐山集自然美景与深厚文化底蕴于一体,无论是自然景观的雄奇险秀,还是人文景观的丰富多彩,基本都使其成为不可多得的旅游胜地。对于想要探访庐山的游客来说,春夏秋三季是最佳游览时节。"
//                "西安事变是**由张学良和杨虎城于1936年12月12日为劝谏蒋介石改变“攘外必先安内”的国策、停止内战一致抗日而发动的兵谏,又称双十二事变**。这次事变对我国近现代史产生了深远的影响,不仅因为其直接参与者的身份特殊,更因为它标志着国内战争向抗日战争转折的重大历史节点"
//                "大势智慧科技有限公司凭借其在实景三维数字化重建及三维数据服务的深厚技术积累和丰富的实践经验,已经成为该领域的领导者。面对未来的机遇与挑战,大势智慧有望继续发挥其在技术创新和行业应用方面的优势,为不同行业提供更多高质量的三维数字化解决方案,推动相关领域的技术进步和产业升级"
                "关羽", "张飞"
        ).collect(Collectors.toList());
        String url = "https://open.bigmodel.cn/api/paas/v4/embeddings";
        Map<String, String> header = new HashMap<>();
        header.put("Content-Type", "application/json");
        header.put("Authorization", "");

        for (String s : text) {
            List<Float> embeddings = new LinkedList<>();
            EmbeddingParams embeddingParams = CommonBuilder.of(EmbeddingParams.class)
                    .with(EmbeddingParams::setInput, ListBuilder.<String>ofList().add(s).build())
                    .build();
            String result = HttpRequestUtil.doPost(url, header, JSON.toJSONString(embeddingParams));
            JSONObject jsonObject = JSON.parseObject(result);
            JSONArray jsonArray = jsonObject.getJSONArray("data");
            JSONObject embeddingObj = (JSONObject) jsonArray.get(0);
            JSONArray embedding = embeddingObj.getJSONArray("embedding");
            for (Object o : embedding) {
                embeddings.add(((BigDecimal) o).floatValue());
            }
            MyVector myVector = CommonBuilder.of(MyVector.class)
                    .with(MyVector::setDepartment, s)
                    .with(MyVector::setEmbedding, embeddings)
                    .build();
            esClientUtil.writeData(myVector, IdUtil.getSnowflakeNextId() + "", "my_embedding");
        }
    }

3、测试验证knn检索:

 @Test
    public void vectorSearchV1() throws Exception {
//        List<String> text = Stream.of("刘备", "关羽", "毛泽东思想", "毛泽东", "林彪", "周恩来", "张三丰", "十堰").collect(Collectors.toList());
//        List<String> text = Stream.of("西安", "十堰", "江西", "张学良", "蒋介石", "杨虎城", "黄先锋").collect(Collectors.toList());
        List<String> text = Stream.of("桃园三结义", "十堰", "江西", "张学良", "蒋介石", "大势智慧", "黄先锋").collect(Collectors.toList());
        String url = "https://open.bigmodel.cn/api/paas/v4/embeddings";
        Map<String, String> header = new HashMap<>();
        header.put("Content-Type", "application/json");
        header.put("Authorization", "");

        for (String s : text) {
            List<Float> embeddings = new LinkedList<>();
            EmbeddingParams embeddingParams = CommonBuilder.of(EmbeddingParams.class)
                    .with(EmbeddingParams::setInput, ListBuilder.<String>ofList().add(s).build())
                    .build();
            String result = HttpRequestUtil.doPost(url, header, JSON.toJSONString(embeddingParams));
            JSONObject jsonObject = JSON.parseObject(result);
            JSONArray jsonArray = jsonObject.getJSONArray("data");
            JSONObject embeddingObj = (JSONObject) jsonArray.get(0);
            JSONArray embedding = embeddingObj.getJSONArray("embedding");
            for (Object o : embedding) {
                embeddings.add(((BigDecimal) o).floatValue());
            }
            // 设置查询向量
            KnnQuery.Builder builder = new KnnQuery.Builder();
            builder.field("embedding")
                    .numCandidates(100)
                    .k(10)
//                .similarity(0.3f)
                    .queryVector(embeddings);
            // 创建搜索请求
            SearchRequest searchRequest = new SearchRequest.Builder()
                    .index("my_embedding")
                    .knn(builder.build())
                    .size(10)
                    .build();

            // 执行搜索请求
            SearchResponse<Product> searchResponse = es8ClientUtil.searchData(searchRequest, "my_embedding", Product.class);
            StringJoiner stringJoiner = new StringJoiner("\t");
            StringJoiner score = new StringJoiner("\t");
            for (Hit<Product> hit : searchResponse.hits().hits()) {
                stringJoiner.add(hit.source().getDepartment());
                score.add(hit.score() + "");
            }
            System.err.println(s + "===检索结果===:");
            System.err.println(stringJoiner);
            System.err.println(score);
            System.err.println();
        }
    }

其中用到的HttpRequestUtil是我自己基于apachehttpclient封装的工具类:基于ApacheHttpclient封装的请求工具类(记笔记)_java apache请求工具类-CSDN博客

PS:经过几轮测试下来,得出以下结论:

1、knn检索确实可以实现语义检索,弥补传统的关键字检索的不足,二者结合可以实现更加智能的检索

2、knn检索的"准确性"问题,比如我在测试的时候输入林彪,也能查询到诸葛亮这条数据,在我们的认知里面,这两个人是八竿子打不着的, 但是在经过模型转换之后,他们之间可能确实存在一些相似性,比如都是历史名人,这个"偏差"很依赖于模型的理解和转换能力

3、我测试过智普、阿里云、百度千帆和百川智能四个模型,总体上智普的效果比较好

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

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

相关文章

QT菜单栏设计(二级菜单栏)

目的&#xff1a;创建一级菜单栏&#xff0c;添加对应选项&#xff0c;并向一级菜单栏中添加二级菜单栏选项。 #include "mainwindow.h" #include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindo…

【天怡AI-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

Netty笔记07-粘包与半包(上)

文章目录 前言1. 粘包造成粘包的原因解决粘包的方法 2. 半包造成半包的原因解决半包的方法 粘包现象服务端代码示例客户端代码示例 半包现象现象分析粘包半包滑动窗口MSS 限制Nagle 算法 前言 粘包和半包问题是网络编程中常见的问题&#xff0c;特别是在TCP协议中。通过合理的设…

C++编程语言:基础设施:源文件和程序(Bjarne Stroustrup)

第15章 源文件和程序 (Source Files and Programs) 目录 15.1 单独编译(Separate Compilation) 15.2 链接(Linkage) 15.2.1 文件局部名(File-Local Names) 15.2.2 头文件(Header Files) 15.2.3 一次定义原则(The One-Definition Rule) 15.2.4 标准库头文件 1…

Python办公自动化教程(001):PDF内容提取

1、Pdfplumber介绍 pdfplumber的github地址&#xff1a; https://github.com/jsvine/pdfplumber/【介绍】&#xff1a;pdfplumber 是一个用于处理 PDF 文件的 Python 第三方库&#xff0c;它提供了一种方便的方式来提取 PDF 文件中的文本、表格和其他信息。【功能】&#xff…

JEDEC DDR3 SRAM standard

DDRDouble Data Rate双倍速率,DDR SDRAM双倍速率同步动态随机存储器&#xff0c;人们习惯称为DDR&#xff0c;其中&#xff0c;SDRAM 是Synchronous Dynamic Random Access Memory的缩写&#xff0c;即同步动态随机存取存储器。而DDR SDRAM是Double Data Rate SDRAM的缩写&…

交叉熵损失函数的使用

交叉熵损失函数 交叉熵损失函数&#xff08;Cross-Entropy Loss&#xff09;&#xff0c;也称为对数损失&#xff08;Log Loss&#xff09;&#xff0c;是机器学习和深度学习中常用的损失函数之一&#xff0c;尤其在分类问题中。它衡量的是模型预测的概率分布与真实标签的概率…

写作文的AI,不妨试试这些工具

写作文的AI&#xff0c;随着人工智能技术的迅猛发展&#xff0c;AI写作软件已经成为许多作家、学生和内容创作者的得力助手。这些软件不仅能帮助用户生成高质量的文章&#xff0c;还能提供创意灵感、语法校正和内容优化等多重功能。下面&#xff0c;本文将介绍五款各具特色的AI…

s3c2440——UART串口通信

一、通信方式 1、并行通信&#xff1a;一次可收发2bit/2bit以上。通信效率高&#xff1b;但对SOC硬件资源占用率太高。 串行通信&#xff1a;一次通信传递1bit。降低对硬件占用率&#xff1b;但通信速率低。 2、单工通信&#xff1a;只能A发送&#xff0c;B接收。 半双工通信…

D. Minimize the Difference (Codeforces Round 973 Div. 2)

D. Minimize the Difference 思路&#xff1a; 发现操作是单向的从左往右取高补低&#xff0c;最终目标是尽可能趋于平均&#xff0c;使最大值最小和使最小值最大。可以用二分答案法分别找到两个最值&#xff0c;然后做差即可。 关于这种算法的正确性没有做严格的证明&#x…

国庆节适合买什么东西?精选五款实用又优惠的多功能好物!

临近国庆&#xff0c;我猜很多朋友已经开始为假期做好准备&#xff0c;计划开启出游和购物的节奏了&#xff01;大家都希望在国庆期间&#xff0c;买到一些平时因为价格太贵而舍不得下单的好物&#xff01;作为一名家居兼数码博主&#xff0c;每年国庆的时候我都会疯狂采购各种…

那年我双手插兜,使用IPv6+DDNS动态域名解析访问NAS

估计有很多科技宅和我一样&#xff0c;会买一个NAS存储或者自己折腾刷一下黑群晖玩玩&#xff0c;由于运营商不给分配固定的公网IP&#xff0c;就导致我在外出的时候无法访问家里的NAS&#xff0c;于是远程访问常常受到IP地址频繁变动的困扰。为了解决这一问题&#xff0c;结合…

对FPGA加载过程中不同寄存器初始化方式现象的分析

对FPGA加载过程中不同寄存器初始化方式现象的分析 概述目的术语和缩略语参考资料 相关原理分析MMCM时钟锁定分析声明信号时进行初始化RTL测试代码示波器现象 同步复位/置位初始化RTL测试代码示波器现象 异步复位/置位初始化RTL测试代码示波器现象 不进行任何初始化操作&#xf…

JSP 指令标识和脚本标识的使用

文章目录 前言一、JSP 页面是什么&#xff1f;二、JSP 基本语法 1.指令标识 &#xff08;1&#xff09;page 指令&#xff08;2&#xff09;include 指令&#xff08;3&#xff09;taglib 指令2.脚本标识总结 前言 在进行Java Web 应用开发的过程中&#xff0c;JSP 是必不可少的…

9.19工作笔记

怎么做多空对冲 脚本2 read_coin选币单币涨跌幅计算单币资金曲线单币资金曲线均值得到周期总体资金曲线周期总体资金曲线得到周期总体涨跌幅周期总体涨跌幅计算得到总体资金曲线 脚本2怎么实现多空对冲的 首先读取factors和periods中的文件&#xff0c;然后read_coin得到结…

Proteus-7.8sp2安装

一、D盘新建空文件夹&#xff0c;名为Proteus。 二、安装软件 1.双击P7.8sp2.exe 2.next 三、破解 1.双击 Proteus Pro 7.8 SP2破解 1.0.exe 2. 升级 打开软件 四、汉化 1.将如下两个文件复制到 D:\Proteus\BIN 路径中 重新打开软件&#xff0c;汉化成功

【在.net6和WPF框架下进行海康SDK开发】(一)如何引用Dll

最近有个上位机项目&#xff0c;需要将海康VisionMaster的部分功能嵌入到统一的界面。项目使用WPFdotNet6开发&#xff0c;UI库使用HandyControl。 先说下需求&#xff0c;在某个TabItem内嵌入一个UserControl&#xff0c;UserContr内嵌入VisionMaster运行界面。 本以为按照海康…

10年计算机考研408-计算机网络

【题33】下列选项中&#xff0c;不属于网络体系结构所描述的内容是&#xff08;&#xff09; A.网络的层次 B.每一层使用的协议 C.协议的内部实现细节 D.每一层必须完成的功能 解析&#xff1a; 本题考查的是网络体系结构相关的概念。 图1描述了网络的7层架构以及每一层所要完成…

智能新突破:AIOT 边缘计算网关让老旧水电表图像识别

数字化高速发展的时代&#xff0c;AIOT&#xff08;人工智能物联网&#xff09;技术正以惊人的速度改变着我们的生活和工作方式。而其中&#xff0c;AIOT 边缘计算网关凭借其强大的功能&#xff0c;成为了推动物联网发展的关键力量。 这款边缘计算网关拥有令人瞩目的 1T POS 算…

某文书网爬虫逆向

一、抓包分析 请求参数和响应数据都有加密 二、逆向分析 老方法、下xhr断点 加密实现逻辑都在这个方法里 执行到这的时候&#xff0c;在向下跟栈数据就已经渲染出来了&#xff0c;说明是在这个方法里进行的解密 解密方法&#xff0c;data.result为加密数据&#xff0c;data.s…