Перейти к содержанию

Ответы 2.5

Теория

  1. Maximum Marginal Relevance (MMR): Балансирует релевантность и разнообразие, выбирая документы, близкие к запросу, но при этом непохожие друг на друга.
  2. Self-query Retrieval: Разбивает запрос на семантические компоненты и метаданные для более точного поиска по содержанию и атрибутам.
  3. Контекстная компрессия: Извлекает только наиболее релевантные сегменты из документов, уменьшая объем лишней информации и улучшая качество ответа.
  4. Настройка окружения: Включает установку библиотек, доступ к API (для эмбеддингов) и инициализацию векторной базы данных — все это является основой для реализации продвинутого ретривала.
  5. Векторная база данных: Хранит эмбеддинги и обеспечивает быстрый поиск по семантической близости к запросу.
  6. Наполнение БД: Предполагает добавление текстов и использование поиска по сходству; MMR помогает исключить избыточные повторы.
  7. Повышение разнообразия с MMR: MMR увеличивает разнообразие результатов, предотвращая кластеризацию похожих документов.
  8. Метаданные для специфичности: Метаданные (например, дата, тип) повышают специфичность и точность поиска.
  9. Self-query Retriever: Автоматически извлекает как семантическую часть запроса, так и метаданные из пользовательского ввода.
  10. Эффективность контекстной компрессии: Позволяет экономить вычислительные ресурсы и выделять основную суть информации.
  11. Лучшие практики: Включают балансировку MMR, грамотное использование метаданных, тонкую настройку компрессии и тщательную подготовку документов.
  12. Сочетание методов: Векторные методы эффективны для поиска по смыслу, но иногда TF-IDF или SVM могут быть полезны для поиска по ключевым словам или классификации.
  13. Преимущества продвинутых техник: Улучшают точность, разнообразие, контекстность и общий пользовательский опыт (UX).
  14. Будущее NLP: Прогресс в обработке естественного языка обещает еще более интеллектуальные способы понимания и реагирования на сложные запросы.

Практические задания

  1. 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)
    
  2. 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)
    
  3. 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)
    
  4. 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()