写点什么

使用矢量数据库打造全新的搜索引擎

作者:这我可不懂
  • 2023-08-01
    福建
  • 本文字数:4501 字

    阅读完需:约 15 分钟

使用矢量数据库打造全新的搜索引擎

在技术层面上,矢量数据库采用了一种名为“矢量索引”的技术,这是一种组织和搜索矢量数据的方法,可以快速找到相似矢量。其中关键的一环是“距离函数”的概念,它可以衡量两个矢量的相似程度。

1.矢量数据库简介


矢量数据库是专门设计用来高效处理矢量数据的数据库。什么是矢量数据呢?矢量数据代表多维空间中的数据点,是一种用数学方法来定义现实世界信息的方式。


比如说,您有一组图片,每张图片都可以在高维空间中表示为一个矢量,其中每个维度都与图片的某些特征(如颜色、形状或纹理)相关。通过比较这些矢量,我们可以找到相似的图片。


这种能力非常关键,因为它可用来进行相似性搜索——一种寻找相似物品而不是完全相同复制品的搜索方式。对于推荐系统和机器学习等许多领域来说,这都是一个重大的变革。

2.解析矢量数据库


在技术层面上,矢量数据库采用了一种名为“矢量索引”的技术,这是一种组织和搜索矢量数据的方法,可以快速找到相似矢量。其中关键的一环是“距离函数”的概念,它可以衡量两个矢量的相似程度。


当您寻找与给定矢量相似的矢量时,数据库并不会将给定矢量与数据库中的每个矢量进行比较。相反,它使用矢量索引快速定位到可能相似的一小部分矢量。这个特性使搜索变得更快、更高效。

3.矢量数据库的实际应用

矢量数据库在实际应用中的优势:

  • 推荐系统:许多受欢迎的网站和应用都使用矢量数据库向您推荐喜欢的节目和产品。他们将项目(如电影或产品)和用户表示为矢量,然后利用项目矢量和用户矢量之间的相似性来预测用户可能喜欢的项目。

  • 图像和视频搜索:矢量数据库非常适合图像类比这种应用,它们使图像或视频搜索系统能够根据视觉相似性而不仅仅是文本标签来查找相似的图像或视频。

  • 语义搜索:语义搜索是一种高级的方式,可以理解查询的含义,不仅仅是特定的单词。例如,如果您搜索“可爱猫咪的图片”,语义搜索系统可能还会向您展示可爱的小猫的图片,即使“小猫”这个词不在您的查询中。矢量数据库可以将文档、查询和概念表示为矢量,然后利用矢量相似性来查找相关结果。

4.将文本转换为矢量


当我们谈论将查询和文章转换为矢量时,实际上我们想要的是将人类可读的文本转换为机器可以理解和执行的格式,即矢量。在这种情况下,矢量实质上是个数字列表,捕捉了文本的本质或含义。这个过程通常被称为“文本嵌入”或“词嵌入”。

4.1 应用于我们的情况:


对于我们的应用程序,我们需要将文章和用户查询都转换为矢量。我们来看看如何完成此过程:

  • 选择嵌入算法:假设我们使用 Word2Vec,这是一种可以接收文本并输出矢量的算法。Word2Vec 通过分析单词在文本中出现的上下文,并以这样一种方式分配矢量,使共享相似上下文的单词被分配相似的矢量。

  • 预处理文本:在我们将文本输入 Word2Vec 之前,我们需要对其进行一些清理。这通常涉及将所有文本转换为小写,删除标点符号和特殊字符,有时甚至删除意义不大的的常用词(如 "和"、"的"、"是 "等)(称为“stop words”)。

  • 将清理后的文本输入到算法中:文本整理好后,就将其输入到 Word2Vec 中。输出将是矢量,我们可以将其用于我们的矢量数据库。

4.2 案例:


假设我们有一篇标题为“The Best Chocolate Chip Cookie Recipe”的博客文章。清理后,它可能看起来像“best chocolate chip cookie recipe”。然后,使用 Word2Vec,我们将每个单词转换为矢量。为简单起见,假设我们的矢量只有两个维度。 “best”的矢量可能看起来像[0.25,-0.1],“chocolate”可能是[0.75,0.8],“chip”可能是[-0.6,0.5],“cookie”可能是[0.4,-0.2],“recipe”可能是[-0.1,0.65]。


在这种情况下,我们将这些矢量的平均值表示整个文章,然后将其用于我们的矢量数据库。用户查询也会经过相同的过程,它们的矢量将用于搜索矢量数据库。


这是一个简化的解释,实际过程涉及更复杂的数学和更大的矢量,但这提供了如何将查询和文章转换为矢量的基本理解。一旦您了解了基本概念,就有很多库可以为您完成繁重的工作!


在我们的 Java Spring Boot 应用程序中,可以使用像 DL4J(Deeplearning4j)这样的库来帮助我们进行文本到矢量的转换。虽然使用 DL4J 进行文本到矢量的转换需要一些时间和精力去掌握,但一旦掌握,DL4J 就是数据管理工具包中非常强大的一个工具。


现在,我们将这一步添加到我们的 Spring Boot 应用程序中,使用 Deeplearning4j 库将文本转换为矢量。以下是如何使用它创建一个 Word2Vec 模型的示例:


首先,请将 DL4J 库添加到您的 pom.xml 中:

<dependency>    <groupId>org.deeplearning4j</groupId>    <artifactId>deeplearning4j-core</artifactId>    <version>1.0.0-beta7</version></dependency>
复制代码


以下代码显示了如何构建 Word2Vec 模型:

import org.deeplearning4j.text.sentenceiterator.BasicLineIterator;import org.deeplearning4j.text.sentenceiterator.SentenceIterator;import org.deeplearning4j.text.tokenization.tokenizer.preprocessor.CommonPreprocessor;import org.deeplearning4j.text.tokenization.tokenizerfactory.DefaultTokenizerFactory;import org.deeplearning4j.text.tokenization.tokenizerfactory.TokenizerFactory;import org.deeplearning4j.models.word2vec.Word2Vec;
public Word2Vec createWord2VecModel(String filePath) { SentenceIterator iter = new BasicLineIterator(filePath); TokenizerFactory t = new DefaultTokenizerFactory(); t.setTokenPreProcessor(new CommonPreprocessor()); Word2Vec vec = new Word2Vec.Builder() .minWordFrequency(5) .iterations(1) .layerSize(100) .seed(42) .windowSize(5) .iterate(iter) .tokenizerFactory(t) .build(); vec.fit(); return vec;}
复制代码


以上是构建 Word2Vec 模型的示例代码,下面是如何将文本转换为矢量的示例代码:

import org.nd4j.linalg.api.ndarray.INDArray;public INDArray textToVector(Word2Vec word2VecModel, String text) {    TokenizerFactory t = new DefaultTokenizerFactory();    t.setTokenPreProcessor(new CommonPreprocessor());    List<String> tokens = t.create(text).getTokens();    INDArray vector = word2VecModel.getWordVectorMatrixNormalized(tokens.get(0));    for (int i = 1; i < tokens.size(); i++) {        vector.addi(word2VecModel.getWordVectorMatrixNormalized(tokens.get(i)));    }    vector.divi(tokens.size());    return vector;}
复制代码


将 INDArray 对象转换为双精度列表的代码如下:

public List<Double> toDoubleVector(INDArray vector) {    return Arrays.stream(vector.toDoubleVector())            .boxed()            .collect(Collectors.toList());}
复制代码

5.在 Spring Boot 应用程序中实现矢量数据库


让我们从理论转向实践,看看如何将矢量数据库集成到 Spring Boot 应用程序中。在本示例中,我们将使用 Vespa,这是一个开源的矢量数据库,它在语义搜索方面表现非常出色,因此备受关注和推崇。


首先,您需要在 pom.xml 中的 Maven 依赖项中添加 Vespa 客户端:

<dependency>    <groupId>com.yahoo.vespa</groupId>    <artifactId>vespa-feed-client</artifactId>    <version>8.91.4</version></dependency>
复制代码


然后,您将创建一个与 Vespa 数据库交互的 VespaClient 类。

public class VespaClient {    private FeedClient feedClient;    public VespaClient(String endpoint) {        this.feedClient = FeedClientFactory.create(new FeedParams.Builder().build(), endpoint);    }    public CompletableFuture<Result> indexDocument(String documentId, Map<String, Object> fields) {        DocumentId docId = new DocumentId("namespace", "documentType", documentId);        Document document = new Document(docId, fields);        return feedClient.send(document);    }    // 其他Vespa客户端方法在此处...}
复制代码


您还将拥有一个 BlogPost 类,该类将表示您的数据。

public class BlogPost {    private String id;    private String title;    private String content;    // Getters、setters和其他方法在此处...}
复制代码


要索引文章,我们将把 BlogPost 转换为 Vespa 友好格式,该格式是一个 Map<String, Object>,其中键是字段名称,值是字段值。您可能会使用一个方法来执行此转换。

public CompletableFuture<Result> indexBlogPost(BlogPost post) {    Map<String, Object> fields = new HashMap<>();    fields.put("id", post.getId());    fields.put("title", post.getTitle());    fields.put("content", post.getContent());    // 根据需要包含其他字段...    return indexDocument(post.getId(), fields);}
复制代码


使用 Vespa,您可以进行最近邻搜索,以查找与给定查询类似的文章。我们假设您有一种方法可以将查询和文章转换为矢量。

public CompletableFuture<SearchResult> searchSimilarBlogPosts(String query) {    List<Double> queryVector = convertQueryToVector(query);    Query request = new Query.Builder("namespace", "documentType")        .setYql("select * from sources * where ([{" +                "\"targetNumHits\": 10," +                "\"algorithm\": \"euclidean\"," +                "\"pivot\": " + queryVector.toString() +            "}])" +            " output distance")        .build();    return feedClient.search(request);}
复制代码


现在您已经将矢量数据库集成到 Spring Boot 应用程序中,并准备使用矢量数据库的强大功能来改善搜索功能!

6.基于 SpringBoot+Vue3 的全栈开发平台


低代码开发是近年来在网络开发领域备受关注的一个趋势。低代码开发是指使用最少的编程代码来开发应用程序或业务逻辑,这使得即使是没有 IT 或编程经验的初学者也能快速创建所需的功能。


这几年隐约碰过低代码,目前比较热门,很多大厂都相继加入。如果你从未了解过低代码,那你一定不能错过。


JNPF 是一款基于 SpringBoot+Vue3 的全栈开发平台采用微服务、前后端分离架构,基于可视化流程建模、表单建模、报表建模工具,快速构建业务应用;平台可以本地化部署,也支持 K8S 部署。


除了上述功能,还配置了图表引擎、接口引擎、门户引擎、组织用户引擎等可视化功能引擎,基本实现页面 UI 的可视化搭建。内置有百种功能控件及使用模板,使得在拖拉拽的简单操作下,也能大限度满足用户个性化需求。由于 JNPF 平台的功能比较完善,本文选择这项工具进行展开,使你更加直观看到低代码的优势。


如果那你未曾体验过这个领域,你或许可以免费试试看!

应用地址:https://www.jnpfsoft.com/?infoq

7.总结


矢量数据库已经成为一种处理搜索功能的新方式,提供了独特的优势,特别是在处理“相似性”概念至关重要的数据时。通过了解这项技术的基本原理并学习如何在实际场景中应用它,您可以发掘其潜力,从而彻底改变处理数据的方式。

发布于: 2023-08-01阅读数: 22
用户头像

低代码技术追随者,为全民开发而努力 2023-02-15 加入

大家好,我是老王,专注于分享低代码图文知识,感兴趣的伙伴就请关注我吧!

评论

发布
暂无评论
使用矢量数据库打造全新的搜索引擎_数据库_这我可不懂_InfoQ写作社区