Цю картину створив автор цього блогу.
Вступ
У попередній статті ми досліджували, як вкладати документи за допомогою моделей глибокого навчання та зберігати ці вектори в Elasticsearch.
Тепер ми зробимо ще крок далі, реалізувавши пошук за допомогою алгоритму k-найближчих сусідів (kNN), щоб отримувати документи на основі їх щільних векторних уявлень.
Для детальнішого пояснення перегляньте відео-урок:
Відео-урок: Алгоритм пошуку kNN.
Всі пов’язані з цим ноутбуки та слайди можна знайти в моєму репозиторії на GitHub:
[
GitHub - ImadSaddik/ElasticSearchPythonTutorial: Цей репозиторій містить ноутбуки, що демонструють…
Цей репозиторій містить ноутбуки, що демонструють використання ElasticSearch у Python, супроводжувані відповідними відео на YouTube…
github.com
](https://github.com/ImadSaddik/ElasticSearchPythonTutorial?source=post_page-----17f3b9b82017--------------------------------)
Що таке пошук kNN?
Пошук kNN — це метод, що використовується для знаходження k найближчих сусідів до запитуваного вектору в наборі даних.
В Elasticsearch це працює з полями щільних векторів і використовує параметр knn
для пошуку.
Примітка: Стандартний
query
параметр тут не застосовується.
Як це працює?
Спочатку вам потрібно використовувати модель вбудовування (embedding), щоб перетворити ваші документи в щільні векторні уявлення. Ознайомтесь з попередньою статтею, щоб дізнатися, як це зробити.
Ось приклад з трьома документами:
document_1 = {
"id": 1,
"title": "Сонячна система",
"content": "Сонячна система складається з Сонця та об'єктів, що обертаються навколо нього, включаючи вісім планет, їхні супутники, карликові планети та безліч малих тіл, таких як астероїди і комети."
}
document_2 = {
"id": 2,
"title": "Чорні діри",
"content": "Чорна діра — це область простору, де гравітаційне тяжіння таке сильне, що нічого, навіть світло, не може покинути її."
}
Вони утворюються, коли масивні зірки колапсують під дією власної гравітації."
}
document_3 = {
"id": 3,
"title": "Галактики",
"content": "Галактики — це величезні системи, які складаються з зірок, залишків зірок, міжзоряного газу, пилу та темної матерії."
}
Молочний Шлях — це галактика, що містить нашу Сонячну систему."
}
Використовуйте модель all-MiniLM-L6-v2
для кодування поля content
кожного документа:
import torch
from sentence_transformers import SentenceTransformer
# Завантаження моделі
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = SentenceTransformer('all-MiniLM-L6-v2')
model = model.to(device)
# Кодування поля content для кожного документа
document_1["embedding"] = model.encode(document_1["content"])
document_2["embedding"] = model.encode(document_2["content"])
document_3["embedding"] = model.encode(document_3["content"])
Створіть новий індекс, де поле embedding
буде встановлено як dense_vector
, і вставте документи:
from elasticsearch import Elasticsearch
# Підключення до Elasticsearch
es = Elasticsearch('http://localhost:9200')
# Створення індексу
response = es.indices.create(
index="my_index",
mappings={
"properties": {
"embedding": {
"type": "dense_vector",
}
}
},
)
# Індексація документів
response = es.index(index="my_index", body=document_1)
response = es.index(index="my_index", body=document_2)
response = es.index(index="my_index", body=document_3)
Коли ви ставите запитання, наприклад, Що таке чорні діри?, ми не можемо безпосередньо використовувати цей текст для пошуку відповідних документів.
Натомість, запит має бути закодований за допомогою тієї ж моделі.
Тут алгоритм kNN демонструє свою ефективність, оскільки працює з вбудованими (embedded) представленнями. Використовуючи різні метрики відстані, kNN визначає документи, найближчі до вбудованої версії запиту.
Різні метрики відстані, джерело: Jonte Dancker.
Після того як відстані між запитом та документами обчислені, вони сортуються у порядку зростання.
Алгоритм kNN дозволяє вказати кілька параметрів для тонкої налаштування процесу пошуку:
field
: Поле повинно бути відображено якdense_vector
.query_vector
: Представляє вбудоване (embedding) представлення тексту запиту.num_candidates
: Максимальна кількість документів, які будуть отримані перед застосуванням алгоритмуkNN
.k
: Кількість найближчих документів, які слід повернути.
Підсумовуючи, це основна функціональність алгоритму kNN.
Виконання пошуку kNN
Давайте реалізуємо пошук kNN, щоб знайти документи, пов'язані з запитом.
Приклад запиту 1
query = "Що таке чорна діра?"
embedded_query = model.encode(query)
result = es.search(
index='my_index',
knn={
"field": "embedding",
"query_vector": embedded_query.tolist(),
"num_candidates": 5,
"k": 3,
}
)
for hit in result.body["hits"]["hits"]:
print(f"Назва : {hit['_source'].get('title', 'Без назви')}")
print(f"Зміст: {hit['_source']['content']}")
print(f"Оцінка : {hit['_score']}")
print("*"*100)
Оскільки питання стосувалося чорних дір, перший документ отримує найвищу оцінку, оскільки він спеціально обговорює чорні діри.
Назва : Чорні діри
Зміст: Чорна діра — це область простору, де гравітаційне притягання настільки сильне, що нічого, навіть світло, не може вирватися з неї.
Вони утворюються, коли масивні зірки колапсують під власною гравітацією.
Оцінка : 0.8863337
****************************************************************************************************
Назва : Темна матерія
Зміст: Темна матерія — це тип матерії, яка не випромінює світло чи енергію. Її неможливо спостерігати безпосередньо, але вважається, що вона складає близько 27% загальної маси та енергії Всесвіту.
Оцінка : 0.6618407
****************************************************************************************************
Назва : Галактики
Зміст: Галактики — це величезні системи, що складаються зі зірок, залишків зірок, міжзоряного газу, пилу та темної матерії. Чумацький Шлях — це галактика, яка містить нашу Сонячну систему.
Оцінка : 0.64313364
****************************************************************************************************
Приклад запиту 2
query = "Як ми знаходимо екзопланети?"
embedded_query = get_embedding(query)
result = es.search(
index='my_index',
knn={
"field": "embedding",
"query_vector": embedded_query.tolist(),
"num_candidates": 5,
"k": 1,
}
)
for hit in result.body["hits"]["hits"]:
print(f"Назва : {hit['_source'].get('title', 'Без назви')}")
print(f"Зміст: {hit['_source']['content']}")
print(f"Оцінка : {hit['_score']}")
print("*"*100)
Встановивши параметр k
на 1, ми отримали лише один документ.
Назва : Екзопланети
Зміст: Екзопланети, або екзосонячні планети, — це планети, які існують поза межами нашої Сонячної системи. Вони сильно відрізняються за розмірами та складом і часто знаходяться за допомогою таких методів, як метод транзитів та радіальна швидкість.
Оцінка : 0.85655975
****************************************************************************************************
Результати показують, що знайдені документи є дуже релевантними до запиту. Щоб ще більше уточнити пошук, можна встановити поріг оцінки, щоб виключити нерелевантні документи.
Документація
Для більш детальної інформації про пошук kNN
в Elasticsearch, зверніться до офіційної документації.
Наступні кроки
Тепер, коли ви розумієте, як працює пошук kNN
, ви можете створювати чудові пошукові системи з семантичним пошуком. У наступному відео ми розглянемо глибоку пагінацію.
Для більш детальних порад, перегляньте відеоурок:
Відеоурок: Глибока пагінація: Пошук після VS From/Size.
Альтернативно, продовжуйте читати наступну статтю в цій серії на Medium.
Перекладено з: #15 — Implementing kNN search in Elasticsearch for embedded documents