У людей есть естественная способность понимать, что говорят другие люди и что им отвечать. Эта способность развивается благодаря постоянному взаимодействию с другими людьми и обществом на протяжении многих лет. Язык играет очень важную роль в том, как люди взаимодействуют. Языки, которые люди используют для взаимодействия, называются естественными языками.
Правила разных естественных языков различны. Однако у естественных языков есть одна общая черта: гибкость и эволюция.
Естественные языки очень гибкие. Предположим, вы ведете машину, и ваш друг произносит одно из этих трех высказываний: «Остановить», «Остановить машину», «Остановиться». Сразу понимаешь, что он просит тебя остановить машину. Это потому, что естественные языки чрезвычайно гибки.
Еще один важный аспект естественных языков – это то, что они постоянно развиваются. Например, несколько лет назад не было такого термина, как «Google it», который относился бы к поиску чего-либо в поисковой системе Google. Естественные языки всегда эволюционируют.
Напротив, компьютерные языки следуют строгому синтаксису. Если вы хотите, чтобы компьютер напечатал что-то на экране, для этого есть специальная команда. Задача обработки естественного языка – заставить компьютеры понимать и генерировать человеческий язык аналогично человеческому.
Это огромная задача, в которой есть много препятствий. Эта видеолекция из Мичиганского университета содержит очень хорошее объяснение того, почему НЛП так сложно.
В этой статье мы реализуем технику встраивания слов Word2Vec, используемую для создания векторов слов с помощью библиотеки Gensim. Однако, прежде чем сразу перейти к разделу кодирования, мы сначала кратко рассмотрим некоторые из наиболее часто используемых техник встраивания слов, а также их плюсы и минусы.
Подходы к встраиванию слов
Одна из причин, по которой обработка естественного языка является сложной задачей, заключается в том, что, в отличие от людей, компьютеры могут понимать только числа. Мы должны представлять слова в числовом формате, понятном для компьютеров. Встраивание слов относится к числовым представлениям слов.
В настоящее время существует несколько подходов к встраиванию слов, и все они имеют свои плюсы и минусы. Мы обсудим здесь три из них:
- Bag of Words;
- Схема TF-IDF;
- Word2Vec.
Bag of Words
Подход «Bag of Words» – один из простейших подходов к встраиванию слов. Ниже приведены шаги для создания вложений слов с использованием подхода «Bag of Words».
Мы увидим вложения слов, сгенерированные подходом «Bag of Words», на примере. Предположим, у вас есть корпус из трех предложений:
- S1 = я люблю дождь;
- S2 = идет дождь;
- S3 = я далеко.
Чтобы преобразовать приведенные выше предложения в соответствующие им представления встраивания слов с использованием подхода «Bag of Words», нам необходимо выполнить следующие шаги:
- Создайте словарь уникальных слов из корпуса. В приведенном выше корпусе у нас есть следующие уникальные слова.
- Разберите предложение. Для каждого слова в предложении добавьте 1 вместо слова в словаре и добавьте ноль для всех других слов, которых нет в словаре. Например, набор слов для предложения S1 (Я люблю дождь) выглядит так: [1, 1, 1, 0, 0, 0]. Аналогичным образом для S2 и S3 набором представлений слов являются [0, 0, 2, 1, 1, 0] и [1, 0, 0, 0, 1, 1] соответственно.
Обратите внимание, что для S2 мы добавили 2 вместо слова «дождь» в словаре, это потому, что S2 дважды содержит слово «дождь».
Плюсы и минусы
У подхода «Bag of Words» есть как плюсы, так и минусы. Основным преимуществом подхода с использованием набора слов является то, что вам не нужен очень большой набор слов для получения хороших результатов. Как видите, мы строим очень простую модель набора слов из трех предложений. В вычислительном отношении модель набора слов не очень сложна.
Основным недостатком подхода «Bag of Words» является тот факт, что нам нужно создавать огромные векторы с пустыми пробелами, чтобы представить число (разреженную матрицу), которое потребляет память и пространство. В предыдущем примере у нас было всего 3 предложения. Тем не менее, вы можете видеть по три нуля в каждом векторе.
Представьте себе корпус с тысячами статей. В таком случае количество уникальных слов в словаре может достигать тысячи. Если один документ содержит 10% уникальных слов, соответствующий вектор внедрения все равно будет содержать 90% нулей.
Еще одна серьезная проблема, связанная с подходом с использованием набора слов, заключается в том, что он не поддерживает никакой контекстной информации. Его не волнует порядок, в котором слова появляются в предложении. Например, он одинаково обрабатывает предложения «Бутылка в машине» и «Машина в бутылке», которые являются совершенно разными предложениями.
Метод набора слов, известный как n-граммы, может помочь поддерживать взаимосвязь между словами. N-грамма относится к непрерывной последовательности из n слов. Например, 2 грамма для предложения «Вы не счастливы», это «Вы», «не счастливы» и «несчастлив». Хотя подход n-граммов позволяет фиксировать отношения между словами, размер набора функций растет экспоненциально при слишком большом количестве n-граммов.
Схема TF-IDF
Схема TF-IDF – это тип подхода с использованием слов-пакетов, при котором вместо добавления нулей и единиц в вектор внедрения вы добавляете плавающие числа, которые содержат больше полезной информации по сравнению с нулями и единицами. Идея схемы TF-IDF заключается в том, что слова, часто встречающиеся в одном документе и реже встречающиеся во всех других документах, более важны для классификации.
TF-IDF – это продукт двух значений: Term Frequency (TF) и Inverse Document Frequency (IDF).
Частота термина – это количество раз, когда слово появляется в документе, и может быть рассчитана как:
Term frequence = (Number of Occurences of a word)/(Total words in the document)
Например, если мы посмотрим на предложение S1 из предыдущего раздела, то есть «Я люблю дождь», каждое слово в предложении встречается один раз и, следовательно, имеет частоту 1. Напротив, для S2, т.е. частота «дождя» равна двум, а для остальных слов – 1.
IDF относится к журналу общего количества документов, разделенному на количество документов, в которых существует это слово, и может быть рассчитано как:
IDF(word) = Log((Total number of documents)/(Number of documents containing the word))
Например, значение IDF для слова «дождь» составляет 0,1760, поскольку общее количество документов равно 3, а дождь присутствует в 2 из них, поэтому log (3/2) составляет 0,1760. С другой стороны, если вы посмотрите на слово «любовь» в первом предложении, оно появляется в одном из трех документов, и поэтому его значение IDF равно log (3), что составляет 0,4771.
Плюсы и минусы
Хотя TF-IDF является усовершенствованием по сравнению с простым набором слов и дает лучшие результаты для общих задач НЛП, общие плюсы и минусы остаются теми же. Нам все еще нужно создать огромную разреженную матрицу, которая также требует гораздо больше вычислений, чем подход простого набора слов.
Word2Vec
Метод встраивания <a target=»_blank rel=»nofollow»» href=»https://en.wikipedia.org/wiki/Word2vec»> Word2Vec, разработанный Томасом Миколовым, считается современным. Подход Word2Vec использует методы глубокого обучения и нейронных сетей для преобразования слов в соответствующие векторы таким образом, чтобы семантически похожие векторы были близки друг к другу в N-мерном пространстве, где N относится к размерам вектора.
Word2Vec возвращает удивительные результаты. Способность Word2Vec поддерживать семантическую связь отражена в классическом примере, где, если у вас есть вектор для слова «Король», и вы удалите вектор, представленный словом «Мужчина» из «Короля», и добавите к нему «Женщины», вы получить вектор, близкий к вектору «Королевы». Это отношение обычно представлено как:
King - Man + Women = Queen
Модель Word2Vec бывает двух видов: модель Skip Gram и модель Continuous Bag of Words (CBOW).
В модели Skip Gram контекстные слова предсказываются с использованием базового слова. Например, для предложения «Я люблю танцевать под дождем» модель предсказывает «любовь» и «танец».
Напротив, модель CBOW будет предсказывать «до», если контекстные слова «любовь» и «танец» вводятся в модель в качестве входных данных. Модель изучает эти отношения с помощью глубоких нейронных сетей.
Плюсы и минусы
Word2Vec имеет несколько преимуществ перед пакетом слов и схемой IF-IDF. Word2Vec сохраняет семантическое значение различных слов в документе. Контекстная информация не теряется. Еще одним большим преимуществом подхода Word2Vec является то, что размер вектора внедрения очень мал. Каждое измерение в векторе внедрения содержит информацию об одном аспекте слова. Нам не нужны огромные разреженные векторы, в отличие от мешка слов и подходов TF-IDF.
Примечание. Математические детали того, как работает Word2Vec, включают объяснение нейронных сетей и вероятности softmax, что выходит за рамки данной статьи.
Библиотека Gensim
В этом разделе мы реализуем модель Word2Vec с помощью библиотеки Gensim в Python. Следуй этим шагам.
Создание корпуса
Ранее мы обсуждали, что для создания модели Word2Vec нам нужен корпус. В реальных приложениях модели Word2Vec создаются с использованием миллиардов документов. Например, модель Google Word2Vec обучается с использованием 3 миллионов слов и фраз. Однако для простоты мы создадим модель Word2Vec, используя отдельную статью в Википедии. Наша модель будет хуже, чем у Google. Хотя этого достаточно, чтобы объяснить, как модель может быть реализована с использованием библиотеки Gensim.
Прежде чем мы сможем обобщить статьи Википедии, нам нужно получить их. Для этого мы воспользуемся парочкой библиотек. Первая библиотека, которую нам нужно загрузить, – это библиотека Beautiful Soup, очень полезная утилита для парсинга веб-страниц. Выполните следующую команду в командной строке, чтобы загрузить служебную программу.
$ pip install beautifulsoup4
Еще одна важная библиотека, которая нам нужна для синтаксического анализа XML и HTML, – это библиотека lxml. Выполните следующую команду в командной строке, чтобы загрузить lxml:
$ pip install lxml
Статья, которую мы собираемся очистить, – это статья в Википедии об искусственном интеллекте. Напишем скрипт Python для очистки статьи из Википедии:
import bs4 as bs
import urllib.request
import re
import nltk
scrapped_data = urllib.request.urlopen('https://en.wikipedia.org/wiki/Artificial_intelligence')
article = scrapped_data .read()
parsed_article = bs.BeautifulSoup(article,'lxml')
paragraphs = parsed_article.find_all('p')
article_text = ""
for p in paragraphs:
article_text += p.text
В приведенном выше скрипте мы сначала загружаем статью из Википедии, используя метод urlopen класса запроса библиотеки urllib. Затем мы читаем содержание статьи и анализируем его с помощью объекта класса BeautifulSoup. Википедия хранит текстовое содержимое статьи внутри тегов p. Мы используем функцию find_all объекта BeautifulSoup для извлечения всего содержимого из тегов абзацев статьи.
Наконец, мы объединяем все абзацы вместе и сохраняем извлеченную статью в переменной article_text для дальнейшего использования.
Предварительная обработка
На этом этапе мы импортировали статью. Следующим шагом является предварительная обработка содержимого для модели Word2Vec. Следующий скрипт предварительно обрабатывает текст:
# Cleaing the text
processed_article = article_text.lower()
processed_article = re.sub('[^a-zA-Z]', ' ', processed_article )
processed_article = re.sub(r'\s+', ' ', processed_article)
# Preparing the dataset
all_sentences = nltk.sent_tokenize(processed_article)
all_words = [nltk.word_tokenize(sent) for sent in all_sentences]
# Removing Stop Words
from nltk.corpus import stopwords
for i in range(len(all_words)):
all_words[i] = [w for w in all_words[i] if w not in stopwords.words('english')]
В приведенном выше скрипте мы преобразовываем весь текст в нижний регистр, а затем удаляем из текста все цифры, специальные символы и лишние пробелы. После предварительной обработки нам остались только слова.
Модель Word2Vec обучается на наборе слов. Во-первых, нам нужно преобразовать нашу статью в предложения. Мы используем утилиту nltk.sent_tokenize для преобразования нашей статьи в предложения. Для преобразования предложений в слова мы используем утилиту nltk.word_tokenize. На последнем этапе предварительной обработки мы удаляем из текста все стоп-слова.
После того, как скрипт завершит свое выполнение, объект all_words содержит список всех слов в статье. Мы будем использовать этот список для создания нашей модели Word2Vec с библиотекой Gensim.
Создание модели
С Gensim очень просто создать модель Word2Vec. Список слов передается в класс Word2Vec пакета gensim.models. Нам нужно указать значение параметра min_count. Значение 2 для min_count указывает на включение в модель Word2Vec только тех слов, которые встречаются в корпусе как минимум дважды. Следующий скрипт создает модель Word2Vec с использованием статьи в Википедии, которую мы скопировали.
from gensim.models import Word2Vec word2vec = Word2Vec(all_words, min_count=2)
Чтобы увидеть словарь уникальных слов, которые существуют как минимум дважды в корпусе, выполните следующий скрипт:
vocabulary = word2vec.wv.vocab print(vocabulary)
Когда приведенный выше скрипт будет выполнен, вы увидите список всех уникальных слов, встречающихся как минимум дважды.
Анализ модели
Мы успешно создали нашу модель Word2Vec в последнем разделе. Пришло время изучить то, что мы создали.
Поиск векторов для слова
Мы знаем, что модель Word2Vec преобразует слова в соответствующие им векторы. Давайте посмотрим, как мы можем просматривать векторное представление любого конкретного слова.
v1 = word2vec.wv['artificial']
Вектор v1 содержит векторное представление слова «искусственный». По умолчанию, Gensim Word2Vec создает стомерный вектор. Это намного меньший вектор по сравнению с тем, что можно было бы создать из пакета слов. Если для встраивания статьи мы воспользуемся подходом «Bag of Words», длина вектора для каждого будет равна 1206, поскольку имеется 1206 уникальных слов с минимальной частотой 2. Если минимальная частота появления установлена на 1, размер Bag of Words будет и дальше увеличиваться. С другой стороны, векторы, созданные с помощью Word2Vec, не зависят от размера словаря.
Поиск похожих слов
Ранее мы говорили, что контекстная информация слов не теряется при использовании подхода Word2Vec. В этом можно убедиться, найдя все слова, похожие на слово «интеллект».
Взгляните на следующий скрипт:
sim_words = word2vec.wv.most_similar('intelligence')
Если вы напечатаете в консоли переменную sim_words, вы увидите слова, наиболее похожие на «интеллект», как показано ниже:
('ai', 0.7124934196472168)
('human', 0.6869025826454163)
('artificial', 0.6208730936050415)
('would', 0.583903431892395)
('many', 0.5610555410385132)
('also', 0.5557990670204163)
('learning', 0.554862380027771)
('search', 0.5522681474685669)
('language', 0.5408136248588562)
('include', 0.5248900055885315)
На выходе вы можете увидеть слова, похожие на «интеллект», а также их индекс сходства. Слово «ai» наиболее похоже на слово «интеллект» согласно модели, что действительно имеет смысл. Точно так же такие слова, как «человек» и «искусственный», часто сосуществуют со словом «интеллект». Наша модель успешно зафиксировала эти отношения, используя всего одну статью в Википедии.
Заключение
В этой статье мы реализовали модель встраивания слов Word2Vec с помощью библиотеки Gensim в Python. Мы сделали это, скопировав статью из Википедии, и построили нашу модель, используя статью в качестве корпуса. Мы также кратко рассмотрели наиболее часто используемые подходы к встраиванию слов, а также их плюсы и минусы.