Логотип Зефирнет

Семантический поиск: теория и реализация

Дата:

Мне потребовалось много времени, чтобы понять, что поиск является самой большой проблемой в НЛП. Просто посмотрите на Google, Amazon и Bing. Это многомиллиардный бизнес, который возможен только благодаря мощным поисковым системам.

Мои первые мысли о поиске были сосредоточены вокруг неконтролируемой ОД, но я участвовал в Microsoft Хакатон 2018 для Бинга и узнал, как можно сделать поисковую систему с глубоким изучением.

В этой статье будут рассмотрены следующие темы:

Считаете ли вы, что это глубокое техническое образование о приложениях НЛП будет полезным? Подпишитесь ниже, чтобы быть в курсе, когда мы выпустим новый соответствующий контент.  

Классические поисковые системы

Процесс поиска можно разбить на 4 этапа:

  1. Автозаполнение запроса - Предложить запрос на основе первых введенных символов
  2. Фильтрация запросов - удаление токенов, ограничение и опускание
  3. Увеличение запросов - добавление синонимов и сокращение / расширение аббревиатуры
  4. Оценка документа - Оценка (документ | запрос) в соответствии с механизмом оценки, который в основном BM25

Теперь, не тратя времени на объяснение этих шагов, я начну обсуждать недостатки классической поисковой системы, такой как Lucene, которая является самой популярной поисковой системой.

Проблема 1: сопоставление токенов

Представьте, что я заинтересован в поиске лучшей книги о обратное распространение, Согласно отзывам пользователей, Deep Learning от Ian Goodfellow et al. считается лучшим по теме и окружающим. Но есть полное несоответствие слов между Запрос: обратное распространение и Название документа: Глубокое обучение, Это результаты amazon.com. Книга глубокого обучения не существует!

семантический поиск

Результат для запроса "Обратное распространение"

Хотя, если я ищу глубокое изучение, я получаю книгу наверху.

семантический поиск

Результат для запроса «глубокое обучение»

Это проблема жесткого соответствия токенов.

Проблема 2: Контекстуализация

Приведенный выше пример работает с глубоким изучением запросов. Что делать, если мне нравится читать книги с практическими примерами, а не просто читать теорию. Это подводит нас к теме контекстный поиск, В таком случае эти книги были идеальными для меня. Не так ли?

семантический поиск

Практическая книга для изучения «нейронной сети»

семантический поиск

Еще одна практическая книга для изучения «нейронной сети»

И какого черта я вижу книги по НЛП (Нейро-лингвистическое программирование), когда я ищу НЛП! Контекстный поиск может решить эту проблему - если бы поисковая система знала, что я покупаю книги по информатике, она бы показала мне книги по обработке естественного языка.

семантический поиск

And I get these when I search GAN. Again an issue of non-personalisation.

semantic search

Проблема 3: недопонимание запроса

Запрос: влияние х на тебя Результат первой научной статьи: влияние а на х

Т.е. вместо того, чтобы обнаружить влияние Бернхарда на академическое, первая статья о влиянии Гербарта на Бернхарда.

семантический поиск

Обыскан 14 ноября 2019 г.

Поскольку механизм сопоставления токенов не учитывает последовательность слов, он может давать неверные результаты. 😞

Хотя подобное предложение от Google лучше!

семантический поиск

Обыскан 14 ноября 2019 г.

Проблема 4: Поиск изображения

И последнее, но не менее важное: единственный способ поиска изображений по тексту - генерировать метаданные всех изображений с описаниями или тегами, что практически невозможно.

Как влияет наш показатель?

Из-за этого на нашу метрику негативно влияют.

Жесткий токен матча → LESS RECALL

Отсутствие контекста → МЕНЬШАЯ ТОЧНОСТЬ

Глубокое обучение для поиска 🔥

Теперь, когда вы поняли проблемы, связанные с простым сопоставлением токенов, мы можем обсудить, как выполнять поиск с использованием глубокого обучения. Мои мысли основаны на книге Глубокое обучение для поиска Томмазо Теофили.

Решение 1: генерация синонимов

Проблему соответствия токенов можно решить, дополнив слова синонимами с помощью специального словаря в Elasticsearch. Для этого я должен вручную определить слова, которые требуют синонимов, а затем найти их синонимы тоже. Это легко начать, но трудно поддерживать. Вместо этого мы можем использовать глубокое обучение здесь! Сначала мы находим POS (часть речи), используя такую ​​библиотеку, как Spacy, и получаем синонимы для слов, которые имеют POS (часть речи) как существительное, глагол или прилагательное. Мы должны сохранить ограничение по косинусному подобию для выбора похожих слов, чтобы избежать добавления слишком большого количества или не относящихся к делу синонимов.

Наличие синонимов может помочь нам улучшить отзыв, но также может снизить точность 😅

Осторожно ❌

Здесь мы должны быть осторожны, чтобы не дополнить некоторые слова. Удивительно, но самые близкие слова для слова «хорошо» согласно word2vec - «плохо» и «плохо». Это может изменить результаты в определенных случаях. 😅

Вы можете примерить https://projector.tensorflow.org

Самым близким словом для «удивительного» в соответствии с word2vec является «паук», который может быть из фильма «Удивительный человек-паук». Это может привести к неожиданным результатам.

Решение 2: Автозаполнение запроса

Почему бы не помочь пользователю выполнить запрос правильно, когда он печатает так, что завершенный запрос не выдаст пустой результат! Elasticsearch также имеет функцию автозаполнения запросов, но это конечный автомат. Если вы введете последовательность символов, которая не была видна в индексе, она не будет показывать результаты. В то время как в случае языковой модели (LM) генерация не является конечной. (Хотя генерация LM может быть неудачной для более длинных запросов, если модель обучена для более коротких последовательностей.)

Возможность автозаполнения запросов таким образом, что результат не является пустым, может значительно изменить пользовательский опыт и избежать оттока пользователей.

Уловка: удалите те запросы из обучения, которые возвращают пустые результаты, так как нет смысла предлагать запросы, которые не приведут ни к какому результату.

Решение 3: Генерация альтернативного запроса

Если у нас есть журнал запросов от пользовательских сессий, мы можем обучить генеративную модель для генерации (следующий запрос | текущий запрос). Гипотеза заключается в том, что все запросы в сеансе похожи друг на друга. Логи могут быть такими.

  1. искусственный интеллект
  2. Tensorflow
  3. Нейронные сети
  4. ...

Обучающие данные (x, y) (Искусственный интеллект, Tensorflow) (Tensorflow, Нейронные сети)

Генерация запросов может помочь нам предложить соответствующие запросы, понимая покупательский замысел пользователя.

Решение 4. Использование вложений в слова и документы

Как только у нас есть запрос, введенный пользователем, вместо того, чтобы представлять его в однократной или нормализованной форме TF-IDF, мы можем векторизовать слова, предложения и документы, используя некоторые подходы.

  • Простое среднее вложение
  • Взвешенное среднее вложение путем умножения на значения IDF
  • Вложение предложения с использованием такой модели, как infersent, USE (Универсальный кодировщик предложений), предложение предложений
  • автоэнкодер seq2seq

Это может помочь нам представить все токены в семантический и сжатый форма вектора фиксированного размера независимо от размера словаря. Это требует однократных значительных накладных расходов на векторизацию с использованием модели, но все последующие поиски будут векторным поиском в n-мерном пространстве. Современное состояние векторного поиска&nb
СП;Milvus. Для примерный ближайший сосед Вы можете использовать фланн и раздражать.

Решение 5: Контекстуализация

Факторы, которые должны учитываться поисковой системой для контекстуализации / персонализации

  • История пользователя - Интересы от его прошлого поиска, и если он искал то же самое в прошлом, что он нажал
  • География пользователя - Поиск слова «президент» дает мне «Рам Нат Ковинд» → нынешний президент Индии
  • Временные изменения в информации - Результат запроса «президент» будет меняться со временем

Историю пользователя можно использовать, кодируя каждый клик как фиксированный вектор и генерируя счет (документ | история + запрос)

семантический поиск

География и временные характеристики могут быть учтены либо путем фильтрации, либо путем добавления их в качестве функций при обучении модели.

Персонализация позволяет нам предлагать пользователю рекомендации на уровне человека, которые могут помочь нам улучшить конверсию.

Решение 6: Обучение рангу

Из-за недостатков сопоставления токенов в схеме TF-IDF нам на самом деле нужен слой, который может пересортировать результаты. Схема имеет большой уклон для редких слов, а также не учитывает возможность конвертации статьи. Если у нас есть журнал запросов пользователей и того, что они нажимали в результатах поиска, мы можем обучить модель ранжированию документов. Данные будут выглядеть так. (x, y) (Искусственный интеллект, заголовок книги 2) (Tensorflow, заголовок книги 1) (Нейронные сети, заголовок книги 4) В следующий раз, когда мы хотим показать результаты, мы сначала получаем лучшие результаты x из дешевого процесса сопоставления токенов через TF-IDF / BM25, в основном через Elasticsearch, а затем генерируют баллы для всех пар (х, у)

  1. (запрос, заголовок 1) → оценка 1
  2. (запрос, заголовок 2) → оценка 2
  3. ...

Затем мы сортируем названия по счету и показываем лучшие результаты. Вы можете найти реализацию этого с помощью BERT в моем GitHub.

семантический поиск

БЕРТ с головкой НСП

Мы можем определить проблему обучения для ранжирования как проблему BERT NextSentencePrediction - иначе говоря, проблему привязанности.

Решение 7: Ансамбль

В большинстве случаев выгодно использовать оба подхода. В книге упоминается, что лучше всего использовать комбинированные оценки wordvector и BM25.

семантический поиск

Из «Глубокого обучения для поиска»

Ensemble позволяет нам использовать лучшие из обоих подходов - жесткое соответствие токенов + семантика.

Решение 8: Многоязычный поиск

Подход 1

семантический поиск

В некоторых случаях, когда приложение находится в разных регионах, язык пользователя может отличаться от документа. Такой поиск невозможен при классическом поисковом подходе, поскольку токены разных языков не могут совпадать. Это требует помощи машинного перевода с глубоким обучением.

  1. Определить язык пользовательского запроса (например, французский)
  2. Перевести запрос на все языки, на которые у нас есть документы (с французского на английский, немецкий и испанский)
  3. Поиск документов
  4. Перевести все лучшие документы на язык пользователя (английский, немецкий и испанский на французский)

Подход 2

Вместо этого мы можем использовать многоязычный кодировщик предложений для представления текста с любого языка в похожих векторах. Давайте подробно рассмотрим этот подход.

Многоязычный универсальный кодировщик предложений

Я принимаю эти компоненты для выполнения POC:

  • Модель - Многоязычный универсальный кодировщик предложений
  • Поиск векторов - FAISS
  • Данные - Quora вопрос пара от kaggle

Вы можете прочитать больше об использовании в эта бумага, Поддерживает 16 языков.

ШАГ 1. НАГРУЗКА ДАННЫХ

Давайте сначала прочитаем данные. Поскольку набор данных quora огромен и занимает много времени, мы возьмем только 1% данных. Это займет около 3 минут для кодирования и индексации. У него будет 4000 вопросов.

 df = pd.read_csv('quora-question-pairs/train.csv')
df = df.sample(frac=0.01, random_state=1)
df.dropna(inplace=True)
questions = df.question1.values

ШАГ 2. СОЗДАТЬ ЭНКОДЕР

Давайте создадим классы кодировщика, которые загружают модель и имеют метод кодирования. Я создал классы для разных моделей, которые вы можете использовать. Все модели работают с английским и только ИСПОЛЬЗУЮТ многоязычные работы с другими языками.

USE кодирует текст в фиксированный вектор размером 512.

Я использую TFHub для использования и Flair для BERT для загрузки моделей.

class TFEncoder(metaclass=ABCMeta): """Base encoder to be used for all encoders.""" def __init__(self, model_path:str): self.model = hub.load(model_path) @abstractmethod def encode(self, text:list): """Encodes text. Text: should be a list of strings to encode """ class USE(TFEncoder): """Universal sentence encoder""" def __init__(self, model_path): super().__init__(model_path) def encode(self, text): return self.model(text).numpy() class USEQA(TFEncoder): """Universal sentence encoder trained on Question Answer pairs""" def __init__(self, model_path): super().__init__(model_path) def encode(self, text): return self.model.signatures['question_encoder'](tf.constant(s))['outputs'].numpy() class BERT(): """BERT models""" def __init__(self, model_name, layers="-2", pooling_operation="mean"): self.embeddings = BertEmbeddings(model_name, layers=layers, pooling_operation=pooling_operation) self.document_embeddings = DocumentPoolEmbeddings([self.embeddings], fine_tune_mode='nonlinear') def encode(self, text): sentence = Sentence(text) self.document_embeddings.embed(sentence) return sentence.embedding.detach().numpy().reshape(1, -1) model_path = "https://tfhub.dev/google/universal-sentence-encoder-multilingual-large/3" encoder = USE(model_path) 

ШАГ 3. СОЗДАТЬ ИНДЕКСЕР

Теперь мы создадим класс индексатора FAISS, который будет эффективно хранить все вложения для быстрого поиска векторов.

 class FAISS: def __init__(self, dimensions:int): self.dimensions = dimensions self.index = faiss.IndexFlatL2(dimensions) self.vectors = {} self.counter = 0 def add(self, text:str, v:list): self.index.add(v) self.vectors[self.counter] = (text, v) self.counter += 1 def search(self, v:list, k:int=10): distance, item_index = self.index.search(v, k) for dist, i in zip(distance[0], item_index[0]): if i==-1: break else: print(f'{self.vectors[i][0]}, %.2f'%dist) 

ШАГ 4. КОДИРОВАНИЕ И ИНДЕКС

Давайте создадим вложения для всех вопросов и сохраним их в FAISS. Мы определяем метод поиска, который показывает нам топ k похожих результатов по заданному запросу.

 d = encoder.encode(['hello']).shape[-1] # get dimension of emb
index = FAISS(d) #index all questions
for q in tqdm(questions): emb = encoder.encode([q]) index.add(q, emb) # embed and search a question
def search(s, k=10): emb = encoder.encode([s]) index.search(emb, k) 

ШАГ 5. ПОИСК

Ниже мы можем увидеть результаты модели. Сначала мы пишем вопрос на английском языке, и он дает ожидаемые результаты. Затем мы конвертируем запрос в другие языки, используя Google Translate, и результаты снова отличные. Несмотря на то, что я допустил орфографическую ошибку, написав «потерять» вместо «потерять», модель понимает это, так как работает на уровне подслов и является контекстуальной.

семантический поиск

Как видите, результаты настолько впечатляющие, что модель стоит запустить в производство.

Вы можете найти полный код в моя тетрадь с колабом, Вы можете скачать данные с здесь.

Чтобы создавать более совершенные модели, вам нужно настроить языковую модель для ваших данных с помощью трансферного обучения. Вы можете прочитать больше об этом в моем Последняя статья.

И, здесь Вы можете прочитать больше о различных моделях кодирования текста для семантического поиска.

Заключение

Возможно, вы уже знаете, что недавно Google подтолкнул внедрение BERT в производство для улучшения своих результатов поиска. Кажется, что семантический поиск находится на подъеме и станет обычным явлением в отрасли, поскольку мы лучше понимаем использование глубокого обучения для поиска.

Эта статья была первоначально опубликована на Medium (часть 1 и часть 2) и переиздан в TOPBOTS с разрешения автора.

Наслаждайтесь этой статьей? Подпишитесь на дополнительные обновления AI и NLP.

Мы сообщим вам, когда выпустим более глубокое техническое образование.

Источник: https://www.topbots.com/semantic-search-theory-and-implementation/?utm_source=rss&utm_medium=rss&utm_campaign=semantic-search-theory-and-implementation

Spot_img

Последняя разведка

Spot_img

Чат с нами

Всем привет! Могу я чем-нибудь помочь?