Как искать синонимы с помощью Word2Vec
Зачем нужны библиотеки для векторизации.
Компьютеры понимают только числа. Чтобы обучить машину естественному (человеческому) языку, мы должны перевести все слова в числовой формат. Для этого можно использовать встраивание слов — Word2Veс.
Вместе с Марией Обедковой, NLP Engineer в TrustYou, разбираемся, как работает Word2Vec (на примере Python-библиотеки Gensim).
Как превратить текст в числа
Обработка естественного языка (NLP) начинается с преобразования текста в числа — векторизации. Текст разбивают на части (токены) — символы, слова или предложения, — а затем присваивают числовое значение каждой части (в зависимости от частоты, с которой токен встречается в тексте). Токену можно назначить не одно число, а вектор, состоящий из нескольких чисел.
Word2Vec — одна из реализаций предварительно обученного векторного представления слов от Google.
Создавать векторы можно с помощью подходов One-Hot Encoding и Embedding. В One-Hot Encoding каждый вектор состоит из количества чисел, совпадающего с числом слов в тексте. Все элементы вектора равны 0, кроме того, который соответствует токену.
Сначала количество слов для анализа ограничивается с помощью словарей. Для английского языка, например, используют словари Oxford 3000 и Merriam-Webster. Затем создается вектор нужной длины из множества нулей и одной единицы. В итоге получаются векторы большого размера, которые занимают много места в памяти.
Embedding считается более эффективным и менее ресурсоемким. В таком случае вектор может состоять не только из 0 и 1, но и из других чисел. Понадобится меньше «ячеек», чтобы преобразовать слово.
Векторы показывают разницу и закономерности между частями текста (словами, предложениями). Классический пример: вектор между словами «мужчина» и «женщина» будет таким же, как и вектор между словами «дядя» и «тетя».
Расстояния между векторами соответствуют смыслу слов. Выражение «дядя» - «мужчина» + «женщина» будет близким к «тетя», но при этом может не соответствовать ему на 100%.
Мария: «Word2Vec используют как основу для больших проектов и как способ решения исследовательских подзадач. При этом у идеи дистрибутивной семантики (того, что слово можно идентифицировать по контексту) есть недостатки. Например, схожесть слов не всегда указывает на то, что они одинаковы по смыслу».
Поиск синонимов: пишем скрипт
Для работы с Word2Vec можно использовать библиотеку Gensim. Она помогает обрабатывать естественные языки и извлекать семантические темы из документов. Gensim «перегоняет» текст в вектор и считает расстояние между векторами. Преимущество библиотеки в том, что она не требует полной загрузки корпуса в память, а позволяет читать данные с диска.
Рассказываем на примере, как векторные представления помогают находить синонимы для улучшения работы поисковых запросов.
- 1. Загрузим библиотеки для парсинга и анализа страниц.
pip install beautifulsoup4 pip install lxml
- 2. Приступим к написанию скрипта и подтянем необходимые зависимости (для парсинга, работы с регулярными изображениями, NLP и Gensim).
import bs4 as bs import urllib.request import re import nltk from nltk.corpus import stopwords from gensim.models import Word2Vec
- 3. Будем парсить страницу «Википедии» о романе Филипа Дика Do Androids Dream of Electric Sheep.
scrapped_data = urllib.request.urlopen('https://en.wikipedia.org/wiki/Do_Androids_Dream_of_Electric_Sheep') article = scrapped_data.read()
- 4. С помощью объекта BeautifulSoup извлекаем из абзацев текст.
parsed_article = bs.BeautifulSoup(article, 'lxml') paragraphs = parsed_article.find_all('p')
- 5. Объединяем весь текст в переменной article_text.
article_text = "" for p in paragraphs: article_text += p.text
- 6. Дальнейшая работа любого скрипта зависит от того, насколько хорошо вы провели очистку исходного текста. Поэтому мы переводим все символы в нижний регистр.
cleaned_article = article_text.lower()
- 7. Оставляем только буквы и убираем пробелы, используя регулярные выражения.
cleaned_article = re.sub('[^a-z]', ' ', cleaned_article) cleaned_article = re.sub(r'\s+', ' ', cleaned_article)
- 8. Готовим датасет для обучения.
all_sentences = nltk.sent_tokenize(cleaned_article) all_words = [nltk.word_tokenize(sent) for sent in all_sentences]
- 9. Проходимся по датасету и удаляем стоп-слова (те, которые не добавляют смысла, например, is).
for i in range(len(all_words)): all_words[i] = [w for w in all_words[i] if w not in stopwords.words('english')]
- 10. Создаем модель Word2Vec со словами, чаще всего встречающимися в тексте. Например, теми, которые встречаются минимум 3 раза (min_count=3).
word2vec = Word2Vec(all_words, min_count=3)
- 11. В рамках модели находим и выводим самое близкое по смыслу (topn=1) слово для book.
print(word2vec.wv.most_similar('book', topn=1))
Готово — ближайший синоним слова book по нашему словарю — novel.
[('novel', 0.26558035612106323)]
Таким же образом можно искать близкие значения к отдельным словам и целым запросам.