当前位置:   article > 正文

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

如何在 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 作为语义相似性的搜索引擎。 该功能可用于语义搜索、推荐系统。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/305671
推荐阅读
相关标签
  

闽ICP备14008679号