В современном мире информации, богатый информацией, быстрое поиск соответствующих документов имеет решающее значение. Традиционные системы поиска на основе ключевых слов часто терпят неудачу при работе с семантическим значением. Этот учебник демонстрирует, как создать мощную поисковую систему документов, используя:
- Модели встраивания обнимающего лица для преобразования текста в богатые векторные представления
- Chroma DB в качестве нашей векторной базы данных для эффективного поиска сходства
- Трансформеры предложений для высококачественных текстовых внедрений
Эта реализация обеспечивает возможности семантического поиска – поиск документов, основанных на значении, а не только на сопоставлении ключевых слов. К концу этого урока у вас будет рабочая поисковая система документа, которая может:
- Обрабатывать и встраивать текстовые документы
- Храните эти встроения эффективно
- Получить наиболее семантически похожие документы на любой запрос
- Обрабатывать различные типы документов и потребности в поиске
Пожалуйста, выполните подробные шаги, упомянутые ниже в последовательности, чтобы реализовать DocSearchagent.
Во -первых, нам нужно установить необходимые библиотеки.
!pip install chromadb sentence-transformers langchain datasets
Начнем с импорта библиотек, которые мы будем использовать:
import os
import numpy as np
import pandas as pd
from datasets import load_dataset
import chromadb
from chromadb.utils import embedding_functions
from sentence_transformers import SentenceTransformer
from langchain.text_splitter import RecursiveCharacterTextSplitter
import time
Для этого урока мы будем использовать подмножество статей Википедии из библиотеки наборов данных об объятиях. Это дает нам разнообразный набор документов для работы.
dataset = load_dataset("wikipedia", "20220301.en", split="train(:1000)")
print(f"Loaded {len(dataset)} Wikipedia articles")
documents = ()
for i, article in enumerate(dataset):
doc = {
"id": f"doc_{i}",
"title": article("title"),
"text": article("text"),
"url": article("url")
}
documents.append(doc)
df = pd.DataFrame(documents)
df.head(3)
Теперь давайте разделим наши документы на более мелкие куски для более детального поиска:
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
length_function=len,
)
chunks = ()
chunk_ids = ()
chunk_sources = ()
for i, doc in enumerate(documents):
doc_chunks = text_splitter.split_text(doc("text"))
chunks.extend(doc_chunks)
chunk_ids.extend((f"chunk_{i}_{j}" for j in range(len(doc_chunks))))
chunk_sources.extend((doc("title")) * len(doc_chunks))
print(f"Created {len(chunks)} chunks from {len(documents)} documents")
Мы будем использовать предварительно обученную модель трансформатора предложений от обнимающегося лица для создания наших встраиваний:
model_name = "sentence-transformers/all-MiniLM-L6-v2"
embedding_model = SentenceTransformer(model_name)
sample_text = "This is a sample text to test our embedding model."
sample_embedding = embedding_model.encode(sample_text)
print(f"Embedding dimension: {len(sample_embedding)}")
Теперь давайте настроем Chroma DB, легкую векторную базу данных, идеально подходящую для нашей поисковой системы:
chroma_client = chromadb.Client()
embedding_function = embedding_functions.SentenceTransformerEmbeddingFunction(model_name=model_name)
collection = chroma_client.create_collection(
name="document_search",
embedding_function=embedding_function
)
batch_size = 100
for i in range(0, len(chunks), batch_size):
end_idx = min(i + batch_size, len(chunks))
batch_ids = chunk_ids(i:end_idx)
batch_chunks = chunks(i:end_idx)
batch_sources = chunk_sources(i:end_idx)
collection.add(
ids=batch_ids,
documents=batch_chunks,
metadatas=({"source": source} for source in batch_sources)
)
print(f"Added batch {i//batch_size + 1}/{(len(chunks)-1)//batch_size + 1} to the collection")
print(f"Total documents in collection: {collection.count()}")
Теперь наступает захватывающая часть – поиск наших документов:
def search_documents(query, n_results=5):
"""
Search for documents similar to the query.
Args:
query (str): The search query
n_results (int): Number of results to return
Returns:
dict: Search results
"""
start_time = time.time()
results = collection.query(
query_texts=(query),
n_results=n_results
)
end_time = time.time()
search_time = end_time - start_time
print(f"Search completed in {search_time:.4f} seconds")
return results
queries = (
"What are the effects of climate change?",
"History of artificial intelligence",
"Space exploration missions"
)
for query in queries:
print(f"\nQuery: {query}")
results = search_documents(query)
for i, (doc, metadata) in enumerate(zip(results('documents')(0), results('metadatas')(0))):
print(f"\nResult {i+1} from {metadata('source')}:")
print(f"{doc(:200)}...")
Давайте создадим простую функцию, чтобы обеспечить лучший пользовательский опыт:
def interactive_search():
"""
Interactive search interface for the document search engine.
"""
while True:
query = input("\nEnter your search query (or 'quit' to exit): ")
if query.lower() == 'quit':
print("Exiting search interface...")
break
n_results = int(input("How many results would you like? "))
results = search_documents(query, n_results)
print(f"\nFound {len(results('documents')(0))} results for '{query}':")
for i, (doc, metadata, distance) in enumerate(zip(
results('documents')(0),
results('metadatas')(0),
results('distances')(0)
)):
relevance = 1 - distance
print(f"\n--- Result {i+1} ---")
print(f"Source: {metadata('source')}")
print(f"Relevance: {relevance:.2f}")
print(f"Excerpt: {doc(:300)}...")
print("-" * 50)
interactive_search()
Давайте добавим возможность фильтровать результаты нашего поиска по метаданным:
def filtered_search(query, filter_source=None, n_results=5):
"""
Search with optional filtering by source.
Args:
query (str): The search query
filter_source (str): Optional source to filter by
n_results (int): Number of results to return
Returns:
dict: Search results
"""
where_clause = {"source": filter_source} if filter_source else None
results = collection.query(
query_texts=(query),
n_results=n_results,
where=where_clause
)
return results
unique_sources = list(set(chunk_sources))
print(f"Available sources for filtering: {len(unique_sources)}")
print(unique_sources(:5))
if len(unique_sources) > 0:
filter_source = unique_sources(0)
query = "main concepts and principles"
print(f"\nFiltered search for '{query}' in source '{filter_source}':")
results = filtered_search(query, filter_source=filter_source)
for i, doc in enumerate(results('documents')(0)):
print(f"\nResult {i+1}:")
print(f"{doc(:200)}...")
В заключение мы демонстрируем, как создать поисковую систему семантического документа, используя модели обнимающего лица и ChromAdB. Система получает документы на основе значения, а не только на ключевых словах, преобразуя текст в векторные представления. Процессы реализации статей Википедии представляют их для гранулярности, внедряют их с использованием трансформаторов предложений и хранит их в векторной базе данных для эффективного поиска. Конечный продукт функционирует интерактивный поиск, фильтрация метаданных и рейтинг актуальности.
Вот Колаб ноутбукПолем Кроме того, не забудьте следовать за нами Twitter и присоединиться к нашему Телеграмма канал и LinkedIn GrукПолем Не забудьте присоединиться к нашему 80K+ ML SubredditПолем
ASIF Razzaq является генеральным директором Marktechpost Media Inc. как дальновидного предпринимателя и инженера, ASIF стремится использовать потенциал искусственного интеллекта для социального блага. Его последнее усилие-запуск медиа-платформы искусственного интеллекта, Marktechpost, которая выделяется благодаря глубокому освещению машинного обучения и новостей о глубоком обучении, которое является технически обоснованным и легко понятным для широкой аудитории. Платформа может похвастаться более чем 2 миллионами ежемесячных просмотров, иллюстрируя свою популярность среди зрителей.