Ответы 2.5
Теория
- Maximum Marginal Relevance (MMR): Балансирует релевантность и разнообразие, выбирая документы, близкие к запросу, но при этом непохожие друг на друга.
- Self-query Retrieval: Разбивает запрос на семантические компоненты и метаданные для более точного поиска по содержанию и атрибутам.
- Контекстная компрессия: Извлекает только наиболее релевантные сегменты из документов, уменьшая объем лишней информации и улучшая качество ответа.
- Настройка окружения: Включает установку библиотек, доступ к API (для эмбеддингов) и инициализацию векторной базы данных — все это является основой для реализации продвинутого ретривала.
- Векторная база данных: Хранит эмбеддинги и обеспечивает быстрый поиск по семантической близости к запросу.
- Наполнение БД: Предполагает добавление текстов и использование поиска по сходству; MMR помогает исключить избыточные повторы.
- Повышение разнообразия с MMR: MMR увеличивает разнообразие результатов, предотвращая кластеризацию похожих документов.
- Метаданные для специфичности: Метаданные (например, дата, тип) повышают специфичность и точность поиска.
- Self-query Retriever: Автоматически извлекает как семантическую часть запроса, так и метаданные из пользовательского ввода.
- Эффективность контекстной компрессии: Позволяет экономить вычислительные ресурсы и выделять основную суть информации.
- Лучшие практики: Включают балансировку MMR, грамотное использование метаданных, тонкую настройку компрессии и тщательную подготовку документов.
- Сочетание методов: Векторные методы эффективны для поиска по смыслу, но иногда TF-IDF или SVM могут быть полезны для поиска по ключевым словам или классификации.
- Преимущества продвинутых техник: Улучшают точность, разнообразие, контекстность и общий пользовательский опыт (UX).
- Будущее NLP: Прогресс в обработке естественного языка обещает еще более интеллектуальные способы понимания и реагирования на сложные запросы.
Практические задания
-
from typing import List, Tuple import numpy as np # Заглушка для функции эмбеддинга OpenAI def openai_embedding(text: str) -> List[float]: # Эта функция должна вызывать API OpenAI для получения эмбеддингов для заданного текста. # Для демонстрационных целей возвращается случайный вектор. return np.random.rand(768).tolist() # Заглушка функции, которая вычисляет косинусное сходство между двумя векторами def cosine_similarity(vec1: List[float], vec2: List[float]) -> float: # Преобразуем входные списки в массивы numpy для удобства вычислений vec1 = np.array(vec1) vec2 = np.array(vec2) # Вычисляем косинусное сходство между векторами return np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2)) class VectorDatabase: def __init__(self, persist_directory: str): self.persist_directory = persist_directory self.database = [] # Список для хранения кортежей (текст, эмбеддинг) def add_text(self, text: str): # Генерируем эмбеддинг для входного текста embedding = openai_embedding(text) # Сохраняем исходный текст и его эмбеддинг в базу данных self.database.append((text, embedding)) def similarity_search(self, query: str, k: int) -> List[str]: # Генерируем эмбеддинг для запроса query_embedding = openai_embedding(query) # Вычисляем оценки сходства запроса со всеми документами в базе данных similarities = [(text, cosine_similarity(query_embedding, embedding)) for text, embedding in self.database] # Сортируем документы на основе оценок сходства в убывающем порядке sorted_similarities = sorted(similarities, key=lambda x: x[1], reverse=True) # Возвращаем k наиболее похожих текстов return [text for text, _ in sorted_similarities[:k]] # Пример использования класса VectorDatabase if __name__ == "__main__": # Инициализируем векторную базу данных с фиктивным путем к директории для персистентности vector_db = VectorDatabase("path/to/persist/directory") # Добавляем несколько примеров текстов в базу данных vector_db.add_text("The quick brown fox jumps over the lazy dog.") vector_db.add_text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.") vector_db.add_text("Python is a popular programming language for data science.") # Выполняем поиск по сходству для заданного запроса query = "Programming in Python" similar_texts = vector_db.similarity_search(query, 2) print("Результаты поиска по сходству:", similar_texts)
-
def compress_segment(segment: str, query: str) -> str: # Эта функция является заглушкой для внешней утилитарной функции, которая сжимает сегмент # текста на основе заданного запроса. Она должна возвращать более короткую версию сегмента, # которая релевантна запросу. Здесь реализована мок-версия, возвращающая половину сегмента. return segment[:len(segment) // 2] # Мок-реализация: возвращаем половину сегмента def compress_document(document: List[str], query: str) -> List[str]: # Применяем функцию сжатия к каждому сегменту документа compressed_document = [compress_segment(segment, query) for segment in document] return compressed_document # Пример использования функции compress_document document = [ "The first chapter introduces the concepts of machine learning.", "Machine learning techniques are varied and serve different purposes.", "In the context of data analysis, regression models can predict continuous outcomes." ] query = "machine learning" compressed_doc = compress_document(document, query) print("Сжатые сегменты документа:", compressed_doc)
-
def similarity(doc_id: str, query: str) -> float: # Заглушка функции для вычисления косинусного сходства между документом и запросом. # В реальной реализации здесь будет использоваться модель эмбеддингов. return 0.5 # Мок-реализация: возвращаем фиксированное значение def diversity(doc_id1: str, doc_id2: str) -> float: # Заглушка функции для вычисления разнообразия или несходства между двумя документами. # В реальной реализации это может быть 1 - cosine_similarity. return 0.5 # Мок-реализация: возвращаем фиксированное значение def max_marginal_relevance(doc_ids: List[str], query: str, lambda_param: float, k: int) -> List[str]: selected = [] # Список для хранения выбранных документов remaining = doc_ids.copy() # Список оставшихся документов для выбора while len(selected) < k and remaining: mmr_scores = {doc_id: lambda_param * similarity(doc_id, query) - (1 - lambda_param) * max([diversity(doc_id, sel) for sel in selected] or [0]) for doc_id in remaining} next_selected = max(mmr_scores, key=mmr_scores.get) # Выбираем документ с максимальным MMR selected.append(next_selected) remaining.remove(next_selected) return selected # Пример использования функции max_marginal_relevance doc_ids = ["doc1", "doc2", "doc3"] query = "data analysis" selected_docs = max_marginal_relevance(doc_ids, query, 0.5, 2) print("Выбранные документы:", selected_docs)
-
def initialize_vector_db(): # Инициализируем векторную базу данных, используя ранее определенный класс `VectorDatabase`. vector_db = VectorDatabase("path/to/persist/directory") # Определяем несколько примеров текстов для добавления в базу данных. texts = [ "The quick brown fox jumps over the lazy dog.", "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", "Python is a popular programming language for data science." ] # Заполняем базу данных подготовленными текстами. for text in texts: vector_db.add_text(text) # Выполняем поиск по сходству с заданным запросом. query = "data science" similar_texts = vector_db.similarity_search(query, 2) print("Результаты поиска по сходству:", similar_texts) # Для демонстрации разнообразного поиска (симулированного), # здесь можно было бы применить MMR или другие методы для улучшения разнообразия. # Данный вывод просто иллюстрирует возможность такого вызова после реализации функции. print("Результаты разнообразного поиска (симулированные):", similar_texts) # Запускаем демонстрацию работы с векторной базой данных. initialize_vector_db()