ITPub博客

首页 > 数据库 > 数据库开发技术 > 向量数据库技术鉴赏(一)

向量数据库技术鉴赏(一)

原创 数据库开发技术 作者:HelloTech技术派 时间:2023-07-06 09:00:00 0 删除 编辑

内容通过 ChatGPT 技术将视频生成文字,然后人工校验,整理成文。如果喜欢看视频,文章最下面有视频链接。

区分狗的品种

熟悉犬类的朋友,应该能很快的区分出它们的品种,我们之所以能做到这一点,是因为我们会从不同的角度来观察它们的特征。

比如:体型的大小

如果我们用一个坐标轴来表示这个特征,这些狗将落在不同的坐标。

然而单纯依靠体型这一个特征还不够,比如金毛和拉布拉多的体型就十分的接近,所以需要继续观察其他的特征。

比如:毛发的长短

我们再建立一个坐标轴,这样就区分开了金毛和拉布拉多。现在每只狗对应一个二维坐标点。但这仍然不能够很好地区分。德国牧羊犬和挪威纳犬,因为无论是体型还是毛发的长短,他们都十分的接近。所以,我们需要继续从更多的角度来观察。

比如:鼻子的长短

再建立一个坐标轴,于是这两个犬种也被区分开来,现在每只狗对应一个三维的坐标点。我们还可以有更多的角度。

比如:眼睛的大小

虽然作为三维生物,我们不可能在四维空间作图。但在坐标点的数值上却很容易实现这一点,继续向后追加就好,现在每只狗对应一个四维的坐标点。

如果我们从更多的角度或者说维度,来观察一只狗的特征,比如:腿的粗细、毛发的卷曲;甚至是一些抽象的角度,比如:服从性、攻击性等等,我们使用的维度越多,对狗的区分能力就越强,同时坐标点所在的空间维度也就越高。不仅是狗,实际上几乎所有的事情都可以被这样表达。

适用于各种事物

可以是具象的山河日月鸟兽鱼虫,也可以是抽象的喜怒哀乐、悲欢离合。不同事物在不同的特征维度中有着不同的表现,或者说不同的数值,所以最终都会在在一个高维的特征空间中,对应着一个坐标点,只不过在这些更大的范围内我们可能需要更高的特征维度,才能很好的对事物进行区分,可能几百几千乃至上万。但由于我们无法做出超过三维的图,所以接下来我们都是用二维坐标来讲解。你会发现这种表达事物的方式,有着很多美妙的特性,那些概念上更为接近的点,在空间中更为聚集。而那些概念上非常不同的点则距离很远,更进一步,如果以坐标原点为起点,这些坐标点为终点,这就是我们熟悉的带有方向和大小的向量。

矢量化的优势

而从向量的角度,这种表达方式甚至有了一定的推理能力。比如,警察的向量去小偷的向量得到的结果向量和猫减去老鼠的结果向量十分的相似,这意味着猫和老鼠的关系类似于警察和小偷的关系。用向量化的数据来表达概念,不得不说是一个非常好的想法。

  • 如果我们对图片进行向量化,那么就可以通过搜索相似的向量,实现图搜图的功能;
  • 如果对视频进行向量的话,就可以通过搜索相似的向量,实现相关视频的推荐;
  • 如果对商品进行向量的话,就可以通过搜索相似的向量,针对用户当前浏览的商品进行相关推荐;
  • 如果对一个文本进行向量化,就能在一个智能问答系统,从根据用户当前的问题,找到一些已经解决过的相似的问题。
  • ......

矢量数据库及其应用

说到文本类的数据,近些年来对词汇进行向量化,在自然语言处理领域得到了巨大意义,也就是所谓的词向量。

实际上语言作为概念的符号,你会发现一个训练恰当的词向量集合将和其所指代的事物之间的向量结合十分的接近,这很利于发现自然语言中所蕴含的实际概念。

除了词向量以外,最近随着以 ChatGPT为代表的大语言模型的如火如荼,人们又发现了向量数据的一些妙用。如果我们把ChatGPT的对话内容进行向量化,便可以用当前的对话,搜索到历史中最为相似的一些对话,也就是找到和当前对话最相关的记忆,而把这些最相关的记忆提示给模型,将极大地提高其输出的效果。

最近几年,一种叫做向量数据库的产品,正趁着AI的热潮开始崭露头角,向量数据库的倡导者和创业者们正是基于这样的一种设想,开始了他们的视野,伴随着大AI时代的到来,向量将成为一种重要的数据形式,而传统的数据库并不适合用来存储和检索向量数据,因此我们大约需要一种专门设计的数据库,来处理这些问题。

这或许会成为未来数据层面的基础设施。和存储数据表然后用查询语句进行精准搜索的传统数据库不同。

向量数据库存储的是向量数据,而查询过程则是从库中搜索出和查询向量最为相似的一些向量,具有一定的模糊性。

最近邻搜索

通过以上这些例子,不难看出向量数据的一个主要应用场景,就是给定一个查询向量,然后从众多的向量中找到最为相似的一些,这就是所谓的最近邻问题。而能实现这一点的则称之为最近邻搜索算法,一种最容易想到的方法可能就是暴力搜索,也叫平坦搜索。就是一路直接平推过去,依次比较所有向量和查询向量的相似度,挑选出相似度最高的几个。

比较两个向量的相似度的具体方法有许多,两个向量的夹角越小越相似。所以,可以通过计算向量夹角的余弦值来判断。再比如直接计算两个向量的欧式距离,距离越近越相似。

显然如果库中的向量过多,这种毫无技术含量的暴力方法,将导致极高的搜索时间。

但这种方法也有着其他方法永远无法到达的一个好处,它的搜索质量是完美的,因为它真的比较了每一个向量。

使用聚类优化搜索

所以如果库中数据规模较小,消耗的时间可以接受,这也不失为一种好的方法。然而实际应用中的数据规模往往都不会太小,所以我们必须找出一些方法进行优化。有一种朴素的想法,指出了优化的大致思路,我们可以用一个「寻人」的例子来说明。

假如已经知道照片上的这个人在a城市,现在请你想一个办法把他找出来爆搜,就相当于去找a城市的每一个人逐一比较,这样一定能够找到。

但要花费海量的时间,但我们通过他胸前的红领巾,就知道他是一名小学生,所以就可以把寻找的范围缩小到a城市的所有小学。如此就有可能将千万级别的查找次数,降到只有几10万的级别,所以对于向量的搜索问题,假如能够为查询向量先划定一个大致的范围,在搜索岂不美哉。

有一种称之为聚类的算法可以实现这一点,我们以最为流行的k means聚类算法为例。

很简单,我们先选定一个想要分类的数量,比如四类,然后随机生成四个点称之为聚类的中心点,然后这些向量和哪一个中心点最近就被分为哪一类,再然后用当前被分为一类的向量计算出一个平均的向量点,把对应的中心点的位置更新为这个平均点,在判断每个向量点和哪一个中心点最近重新分类,然后继续用同一类的向量点计算出一个平均点,把中心点更新过去,再次重新分类。

如此反复,这个不断迭代的过程就称之为训练,最后这些中心点将趋于稳定或者说收敛,最终将这些向量分成了四类。

在搜索的时候,只需要找出和查询向量最近的那个聚类中心,搜索这个分类中的向量即可,也就实现了缩小搜索范围的目的。

当然聚类的方法并不能保证不会出现遗漏的问题,比如查询向量在这里,他和这个分类的中心最近,但和它最近的向量其实是在这个分类中。有一些缓解这个问题的办法,比如我们增加聚类的数量,同时指定搜索多个最近的区域,减少遗漏。但只要是试图提高搜索的质量,基本上都会增加搜索的时间,实际上速度和质量往往是一对难以调和的矛盾。

而几乎所有的算法都是在这两个指标上,结合实际情况衡量的结果。所以现实就是,除了爆搜一定能够找到最近邻的一些向量以外其他任何方法都不能保证这一点。而只能得到一些近似的结果,所以其实这些算法一般也被称之为近似最近邻算法。

用于搜索优化的哈希

除了聚类以外,减少搜索范围的方式还有很多,这里再介绍一种比较流行的基于哈希的方法,简单来说就是任何数据经过哈希函数计算之后都会输出一个固定长度的哈希值,比如128位。而且由于输入是任意的数据,而输出是固定长度的数,以有穷对无。根据鸽巢原理,必然会出现数据不同。但哈希值相同的情况,这也被称之为碰撞,通常情况下,哈希函数的设计一般力求减少这种碰撞的发生。

但这里所构建的哈希函数却反其道而行,它力求增大发生碰撞的可能,因为哈希碰撞正是分组的依据,哈希值一样的向量被分到同一组。这些分组也被称之为桶。除了容易发生碰撞以外,这个哈希函数还要具备这样的一个特性,位置越近或者说越相似的向量发生碰撞的概率越高,被分到同一个桶中的可能性越大,如此在查询的时候,只需要计算一下查询向量的哈希值,找到其所在的桶,再在这个桶中搜索就好。因为和查询向量最相似的一些向量,大概率都在这个桶。

我们把具有这种特性的哈希函数,称之为位置敏感的哈希函数。这样的哈希函数怎么实现呢?我们来看一种常用的手法,我们以a b c 3 个向量为例。首先随机生成一条直线 而且这条线区分正反两侧,比如这边是正的一侧,这边是反的一侧。如果一个向量在这条线的正的一侧,那么他就是1 ,如果再反的一侧,那么就是0 。然后再随机生成一条直线,同样政策的向量是1,反侧的向量是0 。

如此这般,我们随机的生成若干个这样的直线,每次都根据向量所在的正反侧得到1或者0 。如果一共使用四条随机的直线,如此就为每个向量算出了四个0或者1各自得到一个四位的二进制编码。现在我们来观察一下,这三个二进制编码的相似程度很明显 ac这两个更近的向量的编码更为相似,只有第三位不同,相似度高达3/4 ,而这个较远的b和ac的相似度都很低。

一个是1/4, 一个是0,所以为什么向量越接近,得到的二进制编码就越相似呢?

我们直观的来定性分析一下,在计算这四个二进制编码的某一位的时候,如果要让b和c的结果一样,那么这条线应该是这样的。当然也可以是这样,还可以是这样或者这样,但不论如何,一定要从ac和ab之间穿过去。

同样,如果要让a和c的结果一样,这条线应该从bc和ab之间穿过,我们忽略共同穿越的直观上来看 b和c之间的宽度。

要远远大于a和c之间的宽度,而我们的直线是随机生成的,所以从概率上来说,生成的直线从b c穿过的可能性要比从ac穿过的要更大。所以在生成二进制编码的过程中 c更有可能和a一样,而不是b。同样如果要让a和b的编码值一样,直线要穿过ac和bc ,而如果要让a和c的结果一样,这条线应该从b c和a b之间穿过,忽略共同穿越的bc、ac间的宽度也远小a b 所以a也是更可能和c一样,而不是b。所以这串二进制编码便可以作为向量的哈希值。而这个生成的过程,就是一种我们所找寻的哈希函数,因为它满足我们刚才说的两个要求,容易碰撞而且越相似的向量越容易碰撞。以至于被分到同一个桶中。当然这三个向量的哈希值并不完全相同,但如果我们再观察一个距离a更近的d,你就会发现d最后的二进制编码或者说哈希值和a一样发生的碰撞,我们用四个向量展示了这个方法的基本工作原。

速度和质量之间的权衡

而对于真实情况中的许多向量而言,每个向量通过这个哈希函数后,都会得到一串二进制编码的哈希值。而那些非常接近的,像那样的哈希值大概率是一样的,也就被分到了同一个桶中。

对于更高维度的向量,道理也是一样的。比如三维,便可以使用三维空间中的一个随机平面,来做哈希函数的计算,这个面也有正反正面的向量得到1,反面的向量得到0 。若干个随机平面,自然也就得到了一串二进制编码的哈希值。

如果是更高的维度,虽然我们做不出图形,但却可以理解。在这些更高维度中也存在着包围的超平面,同样也可以完成这样的哈希值生成,所以我们把这种方法称之为随机超平面或者随机投影。

当然正如我们所言。除了直接爆搜,任何试图减少搜索量的方法。都会在一定程度上降低搜索的质量,比如还是这四个向量,现在我们用九条随机直线,每个向量生成长度为九的二进制哈希编码。可能是这样的过程 ad两个比较近的点的哈希值一致,被分到了同一个桶中,这是比较理想的结果。但因为直线是随机的,我们把握不住,所以这个过程也有可能是这样的。在生成第六个编码的时候,这个直线真的就随机到了,从ad之间穿过导致a和d的哈希编码的第六位不同。虽然我们说概率比较小,但毕竟是有可能发生的,最后a和d无法进入同一个痛。

所以一般会采用一种分段的措施,来改善这种情况,比如现在我们把这些二进制哈希值分成三段,然后独立的对这些片段进行分头,如此,虽然d的第二个片段被分到了不同的桶中,但第1、3两个片段却被分到了同一个桶,我们可以采用只要匹配一个片段,就将其作为候选项的策略,合理的扩充更多的搜索范围,你会发现在这种分段的措施下 a和c的第二段也被分到了同一个桶中。两者由此成为了相似向量的候选项,因为他们比较接近。这是一种合理的扩充,而b则没有任何一个段和其他向量对应的段被分到同一个桶中,因为它们距离很远,这很合理。

小结

总之,向量数据库技术提供了一种有效的表示和搜索相似向量的强大方法。在图片搜索、视频推荐、个性化产品推荐、智能问答系统等方面有多种应用。使用聚类和哈希技术有助于优化搜索过程,尽管搜索速度和质量之间始终存在权衡。

原文作者:HelloTech技术派;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2017-12-05

  • 博文量
    181
  • 访问量
    73728