既然是要讨论相似文章的检索,那我们就得知道,一篇文章是怎么用计算机能理解的形式表示出来的,以及怎么计算两篇文章的相似性。最常见的方式就是使用 向量空间模型(Vector Space Model)。所谓向量空间模型,就是将所有文档中出现过的所有关键词都提取出来。如果一共有 n 个关键词,那每个关键词就是一个维度,这就组成了一个 n 维的向量空间。
那一篇文档具体该如何表示呢?我们可以假设,一篇文章中有 k(0。这样一来,每一个文档就都是 n 维向量空间中的一个点。
那接下来,计算两个文章相似度就变成了计算两个向量的相似度。计算向量相似度实际上就是计算两个向量的距离,距离越小,它们就越相似。具体在计算的时候,我们可以使用很多种距离度量方式。比如说,我们可以采用余弦距离,或者采用欧式距离等。一般来说,我们会采用余弦距离来计算向量相似度。
拓展到搜索引擎和推荐引擎中,因为每个文档都是 n 维向量中的一个点,所以查询相似文章的问题,就变成了在 n 维空间中,查询离一个点距离最近的 k 个点的问题。如果把这些「点」想象成「人」,这不就和我们在二维空间中查询附近的人的问题非常类似了吗?这就给了我们一个启发,我们是不是也能用类似的检索技术来解决它呢?下面,我们一起来看一下。
首先,在十几维量级的低维空间中,我们可以使用 k-d 树进行 k 维空间的近邻检索,它的性能还是不错的。但随着维度的增加, 如果我们还要精准找到最邻近的 k 个点,k-d 需要不停递归来探索邻接区域,检索效率就会急剧下降,甚至接近于遍历代价。当关键词是几万乃至百万级别时,文档的向量空间可能是一个上万维甚至是百万维的超高维空间,使用 k-d 树就更难以完成检索工作了。因此,我们需要寻找更简单、高效的方案。
这个时候,使用非精准 Top K 检索代替精准 Top K 检索的方案就又可以派上用场了。这是为什么呢?因为高维空间本身就很抽象,在用向量空间中的一个点表示一个对象的过程中,如果我们选择了不同的权重计算方式,那得到的向量就会不同,所以这种表示方法本身就已经损失了一定的精确性。
因此,对于高维空间的近邻检索问题,我们可以使用 近似最近邻检索(Approximate Nearest Neighbor)来实现。你可以先想一想查询附近的人是怎么实现的,然后再和我一起来看高维空间的近似最近邻检索是怎么做的。