Вступление
У людей есть естественная способность понимать, что говорят другие люди и что им отвечать. Эта способность развивается благодаря постоянному взаимодействию с другими людьми и обществом на протяжении многих лет. Язык играет очень важную роль в том, как люди взаимодействуют. Языки, которые люди используют для взаимодействия, называются естественными языками.
Правила разных естественных языков различны. Однако естественные языки объединяет одно: гибкость и эволюция.
Естественные языки очень гибкие. Предположим, вы ведете машину, и ваш друг произносит одно из этих трех высказываний: «Остановить», «Остановить машину», «Остановиться». Сразу понимаешь, что он просит тебя остановить машину. Это потому, что естественные языки чрезвычайно гибки. Есть несколько способов сказать одно.
Еще один важный аспект естественных языков - это то, что они постоянно развиваются. Например, несколько лет назад не было такого термина, как «Google it», который относился бы к поиску чего-либо в поисковой системе Google. Естественные языки всегда эволюционируют.
Напротив, компьютерные языки следуют строгому синтаксису. Если вы хотите, чтобы компьютер напечатал что-то на экране, для этого есть специальная команда. Задача обработки естественного языка - заставить компьютеры понимать и генерировать человеческий язык аналогично человеческому.
Это огромная задача, в которой есть много препятствий. Эта видеолекция из Мичиганского университета содержит очень хорошее объяснение того, почему НЛП так сложно.
В этой статье мы реализуем технику встраивания слов Word2Vec, используемую для создания векторов слов с помощью библиотеки Python Gensim. Однако, прежде чем сразу перейти к разделу кодирования, мы сначала кратко рассмотрим некоторые из наиболее часто используемых техник встраивания слов, а также их плюсы и минусы.
Подходы к встраиванию слов
Одна из причин, по которой обработка естественного языка является сложной задачей, заключается в том, что, в отличие от людей, компьютеры могут понимать только числа. Мы должны представлять слова в числовом формате, понятном для компьютеров. Встраивание слов относится к числовым представлениям слов.
В настоящее время существует несколько подходов к встраиванию слов, и все они имеют свои плюсы и минусы. Мы обсудим здесь три из них:
- Мешок слов
- Схема TF-IDF
- Word2Vec
Мешок слов
Подход «мешок слов» - один из простейших подходов к встраиванию слов. Ниже приведены шаги для создания вложений слов с использованием подхода «мешок слов».
Мы увидим вложения слов, сгенерированные подходом «мешок слов», на примере. Предположим, у вас есть корпус из трех предложений.
- S1 = я люблю дождь
- S2 = дождь идет дождь
- S3 = Я далеко
Чтобы преобразовать приведенные выше предложения в соответствующие им представления встраивания слов с использованием подхода «мешок слов», нам необходимо выполнить следующие шаги:
- Создайте словарь уникальных слов из корпуса. В приведенном выше корпусе у нас есть следующие уникальные слова: [Я, люблю, дождь, иди, прочь, я]
- Разберите предложение. Для каждого слова в предложении добавьте 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
У подхода «мешок слов» есть как плюсы, так и минусы. Основным преимуществом подхода с использованием набора слов является то, что вам не нужен очень большой набор слов для получения хороших результатов. Как видите, мы строим очень простую модель набора слов из трех предложений. В вычислительном отношении модель набора слов не очень сложна.
Основным недостатком подхода «мешок слов» является тот факт, что нам нужно создавать огромные векторы с пустыми пробелами, чтобы представить число (разреженную матрицу), которое потребляет память и пространство. В предыдущем примере у нас было всего 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
Хотя 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 бывает двух видов: модель пропуска грамма и модель непрерывного мешка слов (CBOW).
В модели Skip Gram контекстные слова предсказываются с использованием базового слова. Например, учитывая предложение «Я люблю танцевать под дождем», модель пропуска грамма предсказывает «любовь» и «танец», учитывая слово «to» в качестве входных данных.
Напротив, модель CBOW будет предсказывать «до», если контекстные слова «любовь» и «танец» вводятся в модель в качестве входных данных. Модель изучает эти отношения с помощью глубоких нейронных сетей.
Плюсы и минусы Word2Vec
Word2Vec имеет несколько преимуществ перед пакетом слов и схемой IF-IDF. Word2Vec сохраняет семантическое значение различных слов в документе. Контекстная информация не теряется. Еще одним большим преимуществом подхода Word2Vec является то, что размер вектора внедрения очень мал. Каждое измерение в векторе внедрения содержит информацию об одном аспекте слова. Нам не нужны огромные разреженные векторы, в отличие от мешка слов и подходов TF-IDF.
Примечание . Математические детали того, как работает Word2Vec, включают объяснение нейронных сетей и вероятности softmax, что выходит за рамки данной статьи. Если вы хотите понять математические основы Word2Vec, прочтите этот документ: https://arxiv.org/abs/1301.3781
Word2Vec на Python с библиотекой Gensim
В этом разделе мы реализуем модель Word2Vec с помощью библиотеки Python Gensim. Следуй этим шагам:
Создание корпуса
Ранее мы обсуждали, что для создания модели Word2Vec нам нужен корпус. В реальных приложениях модели Word2Vec создаются с использованием миллиардов документов. Например , модель Google Word2Vec обучается с использованием 3 миллионов слов и фраз. Однако для простоты мы создадим модель Word2Vec, используя отдельную статью в Википедии. Наша модель будет не так хороша, как у Google. Хотя этого достаточно, чтобы объяснить, как модель Word2Vec может быть реализована с использованием библиотеки Gensim.
Прежде чем мы сможем обобщить статьи Википедии, нам нужно их получить. Для этого мы воспользуемся парочкой библиотек. Первая библиотека, которую нам нужно загрузить, - это библиотека Beautiful Soup , очень полезная утилита Python для парсинга веб-страниц. Выполните следующую команду в командной строке, чтобы загрузить служебную программу 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
метод request
класса urllib
библиотеки. Затем мы читаем
содержание статьи и анализируем его с помощью объекта класса
BeautifulSoup
Википедия хранит текстовое содержимое статьи внутри
тегов p
Мы используем функцию find_all
BeautifulSoup
для
извлечения всего содержимого из тегов абзацев статьи.
Наконец, мы объединяем все абзацы вместе и сохраняем article_text
статью в переменной 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.
Создание модели Word2Vec
С 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 создает стомерный вектор. Это намного меньший
вектор по сравнению с тем, что можно было бы создать из пакета слов.
Если для встраивания статьи мы воспользуемся подходом «мешок слов»,
длина вектора для каждого будет равна 1206, поскольку имеется 1206
уникальных слов с минимальной частотой 2. Если минимальная частота
появления установлена на 1, размер мешок слов вектор будет и дальше
увеличиваться. С другой стороны, векторы, созданные с помощью Word2Vec,
не зависят от размера словаря.
Поиск похожих слов
Ранее мы говорили, что контекстная информация слов не теряется при использовании подхода Word2Vec. В этом можно убедиться, найдя все слова, похожие на слово «интеллект».
Взгляните на следующий сценарий:
sim_words = word2vec.wv.most_similar('intelligence')
Если вы напечатаете в sim_words
переменную 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)
На выходе вы можете увидеть слова, похожие на «интеллект», а также их индекс сходства. Слово «ай» наиболее похоже на слово «интеллект» согласно модели, что действительно имеет смысл. Точно так же такие слова, как «человек» и «искусственный», часто сосуществуют со словом «интеллект». Наша модель успешно зафиксировала эти отношения, используя всего одну статью в Википедии.
Заключение
В этой статье мы реализовали модель встраивания слов Word2Vec с помощью библиотеки Python Gensim. Мы сделали это, скопировав статью из Википедии и построив нашу модель Word2Vec, используя статью в качестве корпуса. Мы также кратко рассмотрели наиболее часто используемые подходы к встраиванию слов, а также их плюсы и минусы в сравнении с Word2Vec.
Я бы посоветовал вам создать собственную модель Word2Vec с помощью любого текстового корпуса и посмотреть, сможете ли вы получить лучшие результаты по сравнению с подходом с набором слов.