【Milvus&向量搜索】在长文本搜索场景下的探索

发布于:2024-05-09 ⋅ 阅读:(24) ⋅ 点赞:(0)

本文为稀土掘金技术社区首发签约文章,30天内禁止转载,30天后未获授权禁止转载,侵权必究!

halo大家好,我是广州小井。书接上回,本文将从语句、文段搜索的方向,继续跟大家探索Milvus和向量搜索在文档搜索业务领域的功力。毕竟在文档搜索的业务场景中,我们面对的不只有词语,更多情况下的可能是语句、段落。事不宜迟,马上进入主题。

前文回顾

前文我通过将“开心”、“快乐”、“不开心”等词语做了词嵌入处理后,放到了 Mivlus 中去实际体验了一把搜索的效果。当我通过“开心”的词嵌入结果拿去搜索时,结果如下图所示:

image.png

上图中我们发现,中文语义中跟“开心”更接近的“高兴”、“快乐”排名靠前(distance距离较短),而跟“开心”成反义之势的词语如“不开心”、“生气”等,则排名靠后,距离“开心”的位置较远。通过这种搜索情况的表现,我们不难发现,向量搜索通过对词嵌入结果(向量)做距离计算的搜索方式,确实可以缓解 ES 在语义模糊情况下的搜索不准确的问题

反过来说,如果要用 ES 做到如 Mivlus 这样场景下的搜索结果:"用“开心”作为关键词可以搜索出“快乐”的搜索结果",是不是就有点费劲了呢?如果说要做自定义词典去增强 ES 在语义模糊场景下的搜索质量,我们所付出的成本和得到的收益,是否真的值得呢?

那既然大家都粗略感受到了向量搜索的优势所在,不知道现在的你是否有一个疑问:既然是要落地到文档搜索的业务领域,那我们应该怎么处理原始的文档数据呢? 问题可能有点抽象,那我不妨这么说,文档的数据肯定时由词、语句、段落、超链接、代码块等等组成的,就好比平时我们在掘金写的文章一样,文档的元数据肯定不是简单的几个词语就完事了,所以这里,我们需要注意的就是应该如何处理文档原数据...

上述也就是本文将要跟大家一起探讨的问题了,关于语句、文段等数据在 Mivlus & 向量搜索 中的实战体验如何?我们应该如何对文档原数据进行拆分处理,以及 向量搜索 在处理语句的时候,是否还和词语一样有他的优势?我们一起往下看吧~

ES的语句搜索

在文档搜索的业务领域中,我们要面对的文档数据绝不仅仅是词语,而更多的是句子、段落,还有其他的一些文本内容。所以,这里我们会遇到的第一个问题就是:怎么把握文本的拆分尺度? 至于这个问题,我们可以先思考,我会把其放到下一节内容中再讲。

不过此时的你可能会有疑问,为什么我们在用 ES 搜索的时候,好像并不需要考虑文段切割的事情,为什么在向量搜索中却要考虑呢?我认为最大的区别就在于向量搜索之前需要对文本数据做词嵌入的处理

整个词嵌入的过程,大家可以理解为是一个总结、提炼的过程。好比你丢了一句话、一段话、甚至一整篇文章给 GPT,让他帮你做总结、写读后感啥的,我相信每一次的结果都是不同的。这其实很好理解,比如有一本讲人性的书,其中一篇文章里面讲的是贪婪,而其中一句话是一个具体的例子...同理,把不同体量的数据给到 NLP 模型做词嵌入也会得到不同的结果。

大概了解向量搜索在语句方面的一些理论后,我们不妨先来看看 ES 在语句搜索 中是怎么做的?为什么它不需要对文段、语句等文本做切割拆分,却可以往里面丢一整个语句、文段后就能直接搜呢?

在本文归属专栏的第一篇文章中,我就有介绍过 ES 中 match 关键词的得分总和的由来,如果你还有印象,你应该就不难理解为什么直接给 ES 丢一整个文段、语句后就能直接搜索了,而且搜索的结果依然是以关键词命中数来计算得分的~

不过,讲这么多理论不如来点实际的,这里我就找 gpt 生成三句对互联网介绍的句子,一会用来做搜索实验:

  1. 互联网行业是一个以互联网技术为核心,以提供在线服务和内容为主要业务方向的行业。
  2. 互联网行业具有高速发展和创新性强的特点,涵盖了电子商务、社交网络、在线娱乐等多个领域。
  3. 互联网行业的发展带动了数字经济的兴起,对社会、经济和生活方式产生了深远影响。

我们简单看看这三个句子大概讲了啥:

  • 第一句:互联网是什么;
  • 第二句:互联网的特点;
  • 第三句:互联网的优势、好处。

好好好,笔者的概括能力大概就这样了,有不对的大家多多包涵,接着我们来看看用 ES 拿一些关键词搜索之后的结果吧!

首先我把这三句话录入 ES 中,还是之前的那个索引,插入后如下图所示:

es插入句子.png

现在我们通过:“互联网的特点”作为搜索词,来对 ES 中的 content 字段进行检索看看结果如何(这里还是仅以 match 关键字做演示)。

es-搜索1.png

如图所示,三个句子都能被搜中(这个并不意外,之前我有分析过 match 的机制),但是评分差距有点大(拆词后的关键词命中次数不一样)。从结果上来讲,这个搜索的结果还算符合我个人的感觉,因为从语义上面来看,排名第一的更符合我想要搜索到的内容。好,那么接下来我换一个搜索词:“互联网的好处”,看看 ES 的表现如何?

es-搜索2.png

如上图所示,虽然搜索结果都能搜出三句话,但其实从排名上来看并不是特别符合我个人的预期,我想知道互联网带来的好处,优势,那肯定是后两句的语义更符合我想搜到的内容,毕竟第一句更多偏向于下定义,告诉我们互联网是什么。

简单总结:ES 对于语句的搜索,跟之前的词语搜索机制一样,通过将搜索词拆词、匹配后,计算命中数等得分,并且按照得分的高低来返回结果。也就是说,只要能命中关键词,不管我用 ES 来搜索词语、句子、段落、甚至是一整篇文章都是没有问题的。一旦有关键词的命中,就能搜到内容,最后的给到用户的搜索结果就是看得分高低后进行排序而已。

向量的语句搜索

从上文 ES 的搜索表现来看,依旧缺乏语义相关性的匹配能力,也就是说语义模糊场景下的搜索依然不是很好。就拿最后一个搜索结果来说,我用“互联网的好处”进行搜索,更符合我预期的是对互联网优势、特点说明的语句,而不是下定义的语句。

同样,我先把三句话分别做词嵌入处理之后,插入到 milvus 中。这是其中一句的词嵌入截图:

image.png

插入完毕后,在 attu 中看到数据如图所示:

image.png

我首先用“互联网的好处”去搜索,看看向量搜索这边有没有不一样的结果。当然,先对搜索关键词做 emb 后,得到向量数据再丢进去 milvus 中进行i向量搜索,结果如下图所示:

image.png

如上图可以看到,当我使用“互联网的好处”去搜索时,原本 ES 排名第一的搜索结果在这里排到了靠后,排名靠前的两句话均对”好处“的介绍沾边更多,也就是说这个结果其实是更符合我的预期的。(不知道是不是也更符合你的预期呢)

这里可能有同学发现,啊怎么把前一篇文章讲的内容都给搜索出来了呢?而这不更说明了向量搜索它的距离计算的搜索方式吗?所有的文本数据,做了词嵌入处理后都变成了 1024 维的向量,都可以被计算出位置和被搜索信息的距离。当然啦,0.4几的distance已经是差距很大了,只是这里的数据量不多(9条)的情况下被顶上来了而已...

那既然已经印证了向量搜索在语义模糊情况下的搜索能力,我们顺便也把”互联网的特点“这个搜索词的搜索结果印证一下吧:

image.png

上述的搜索结果,跟 ES 的简直一毛一样。所以这里我们大概可以得出这么一个结论:向量搜索在语句搜索场景中,依然有缓解语义模糊的搜索优势。它相较于 ES,更能在语义层面找出跟我们输入的搜索词语义更为接近的结果。

简单总结:向量搜索不仅仅对词语的搜索场景有缓解语义模糊的优势,也在对句子搜索中语义层面的匹配度也同样具备优势。它相比于 ES,在某种场景下更能搜出语义与搜索内容更加接近的词语、句子。

段落搜索

相信经过前文的介绍,向量搜索在句子搜索层面的表现,你对于向量搜索在段落场景的表现也应该信心十足了。但是磨刀不误砍柴功,在正式将向量搜索落地到文档搜索业务的时候,我们还是要看一看其对于文段的搜素能力。

老样子,我找 gpt 帮我以”介绍互联网“为核心写一个250字以内的小文段:

image.png

再通过”互联网优势“为核心写一个小文段如下:

image.png

话不多说,我同样将这两个文段做词嵌入后插入到 milvus 中。其中一个文段如下图所示:

image.png

此时,我用”互联网简介“作为搜索词去搜索,看看效果如何:

image.png

如图所示,两个对”互联网“下定义的数据排名靠前,而讲互联网优势的句子、段落排名靠后。从这一点上来说,比较符合我们的预期。再接着我用”互联网的优势“去搜索试试效果,看看是不是排名会有所改变?

image.png

显然,对于更侧重于讲优势的文段排名更靠前,而更多介绍互联网是什么的文段则排名第二。从这一点来说,也是比较符合我的预期的。既然这次看过了向量搜索的表现,我们依然把目光转向 ES,看看 ES 对于这种长文本的搜索结果是否跟向量搜索的结果类似?或者说有所不同?

首先我们看看“互联网简介”的搜索情况:

es-搜索3.png

结果如上图所示,这个结果对于大家来说可能也没啥意外,毕竟都能搜索出来。不过这里我发现了一个点,那就是他们的得分都不高...不过结果还算符合预期,我们再来看看“互联网的优势”的搜索情况:

es-搜索4.png

我用来做测试的 ES 并没有安装任何拆词器插件,如ik那些...

如图所示,对互联网优势介绍的文段的得分很高,排名第一(盲猜是因为都匹配上了),总体也是搜出了5条数据。

总结:经过对句子、段落的搜索结果测试,并且横向对比了搜索领域的老大哥 ES 的搜索结果,我们可以肯定向量搜索在长文本搜索场景下有着它的优势,值得一试。

写在最后

当然,在真正将向量搜索落地到文档搜索业务的时候,我们还有一步骤比较关键的步骤,那就是文档的源数据处理。我们到底是都把文档拆分成词语、句子、段落再去做词嵌入、落库,还是说不做拆分,一整段丢进去?或者说对于不同类别的数据我们需不需要处理?比如说 markdown 中的一些其他格式,如 table、代码块、链接 等等内容数据要怎么处理?

关注我,我们下一篇文章再见~