• 如何在 Elasticsearch 中使用 Openai Embedding 进行语义搜索


    随着强大的 GPT 模型的出现,文本的语义提取得到了改进。 在本文中,我们将使用嵌入向量在文档中进行搜索,而不是使用关键字进行老式搜索。

    什么是嵌入 - embedding?

    在深度学习术语中,嵌入是文本或图像等内容的数字表示。 由于每个深度学习模型的输入都应该是数字,因此要使用文本来训练模型,我们应该将其转换为一种数字格式。

    有多种算法可以将文本转换为 n 维数字数组。 最简单的算法称为“Bag Of Word”,该算法中 n 是语料库中唯一单词的数量。 该算法只是简单地统计文本中出现的单词数量,并形成一个数组来表示它。

    1. >>> from sklearn.feature_extraction.text import CountVectorizer
    2. >>> corpus = [
    3. ... 'This is the first document.',
    4. ... 'This document is the second document.',
    5. ... 'And this is the third one.',
    6. ... 'Is this the first document?',
    7. ... ]
    8. >>> vectorizer = CountVectorizer()
    9. >>> X = vectorizer.fit_transform(corpus)
    10. >>> vectorizer.get_feature_names_out()
    11. array(['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third',
    12. 'this'], ...)
    13. >>> print(X.toarray())
    14. [[0 1 1 1 0 0 1 0 1]
    15. [0 2 0 1 0 1 1 0 1]
    16. [1 0 0 1 1 0 1 1 1]
    17. [0 1 1 1 0 0 1 0 1]]

    这种表示形式不够丰富,无法从文本中提取语义和含义。 由于变换器的强大功能,模型可以学习嵌入。 Openai 提供了嵌入 API 来计算文本的嵌入数组。 该表示可以存储在矢量数据库中以供搜索。

    Openai 嵌入 API

    要使用 openai,我们需要在 openai 网站上生成一个 API 密钥。 为此,我们需要在 “View API Keys” 页面中注册并生成一个新密钥。

    Openai API key 页面

    请记住:该密钥只会显示一次,因此请保存以供以后使用。

    要检索文本嵌入,我们应该使用模型和文本调用 openai 嵌入 API。

    1. {
    2. "input": "The food was delicious and the waiter...",
    3. "model": "text-embedding-ada-002"
    4. }

    输入是我们要计算嵌入数组的文本,模型是嵌入模型的名称。 Openai 对于此链接中提供的嵌入模型有多种选择。 在本文中,我们将使用默认的 “text-embedding-ada-002”。 为了调用 API,我们在 python 中使用以下脚本。

    1. import os
    2. import requests
    3. headers = {
    4. 'Authorization': 'Bearer ' + os.getenv('OPENAI_API_KEY', ''),
    5. 'Content-Type': 'application/json',
    6. }
    7. json_data = {
    8. 'input': 'This is the test text',
    9. 'model': 'text-embedding-ada-002',
    10. }
    11. response = requests.post('https://api.openai.com/v1/embeddings',
    12. headers=headers,
    13. json=json_data)
    14. result = response.json()

    嵌入的响应将类似于:

    1. {
    2. "object": "list",
    3. "data": [
    4. {
    5. "object": "embedding",
    6. "embedding": [
    7. 0.0023064255,
    8. -0.009327292,
    9. .... (1536 floats total for ada-002)
    10. -0.0028842222,
    11. ],
    12. "index": 0
    13. }
    14. ],
    15. "model": "text-embedding-ada-002",
    16. "usage": {
    17. "prompt_tokens": 8,
    18. "total_tokens": 8
    19. }
    20. }

    result['data']['embedding'] 是给定文本的嵌入向量。 ada-002 模型的向量大小为 1536 个浮点数,输入的最大标记为 8191 个标记。

    存储和搜索

    有多种数据库选择来存储嵌入向量。 在本文中,我们将探索 Elasticsearch 来存储和搜索向量。

    Elasticsearch 有一个预定义的向量数据类型,称为 “密集向量”。 为了存储嵌入向量,我们需要创建一个索引,其中包括一个文本字段和一个嵌入向量字段。

    1. PUT my_vector_index
    2. {
    3. "mappings": {
    4. "properties": {
    5. "embedding": {
    6. "type": "dense_vector",
    7. "dims": 1536
    8. },
    9. "text": {
    10. "type": "keyword"
    11. }
    12. }
    13. }
    14. }

    对于 ada-002 模型,向量的维数应为 1536。 现在要查询该索引,我们需要熟悉不同类型的向量相似度得分。 余弦相似度是我们可以在 Elasticsearch 中使用的分数之一。 首先,我们需要计算搜索短语的嵌入向量,然后通过索引对其进行查询并获取 top-k 结果。

    1. POST my_vector_index/_search
    2. {
    3. "query": {
    4. "script_score": {
    5. "query": {
    6. "match_all": {}
    7. },
    8. "script": {
    9. "source": "cosineSimilarity(params.query_vector, 'embedding') + 1.0",
    10. "params": {
    11. "query_vector": [0.230, -0.120, 0.389, ...]
    12. }
    13. }
    14. }
    15. }
    16. }

    当然,对于大规模部署,我们需要使用 aNN 搜索。请详细阅读 “Elasticsearch:在 Elastic Stack 8.0 中引入近似最近邻搜索”。

    这将返回语义上与文本查询相似的文本。

    结论

    在本文中,我们探讨了新嵌入模型在文档中查找语义的强大功能。 你可以使用任何类型的文档,例如 PDF、图像、音频,并使用 Elasticsearch 作为语义相似性的搜索引擎。 该功能可用于语义搜索、推荐系统。

  • 相关阅读:
    统计学研硕大数据统计练手11
    element表格跨页全选实现(二)之后端分页
    混沌系统在图像加密中的应用(基于哈密顿能量函数的混沌系统构造1.1)
    hyperscan技术
    C++语言写的CT图像三维重建算法
    xxl-job 数据库由mysql替换为postgre
    图像的梯度
    什么牌子的蓝牙耳机耐用?平价蓝牙耳机里面性价比高的推荐
    深入了解代理服务器:Socks5、IP代理与网络安全
    GitHub SSH 快速配置
  • 原文地址:https://blog.csdn.net/UbuntuTouch/article/details/133430372