Словесные вложения (Word Embeddings)

Словесные вложения – это векторное представление синтаксической единицы (слова или словосочетания), позволяющее уловить контекст. Такие векторы активно используются для широкого спектра задач, к примеру, для определения общей эмоциональной окраски текста.
Пример. Рассмотрим два похожих предложения: "Хорошего Вам дня" и "Отличного Вам дня". Компьютеру понять разницу в их значении довольно сложно, пока мы не создадим исчерпывающий словарь V = {Вам, дня, отличного, хорошего}.
Давайте создадим вектор быстрого кодирования (One-Hot Encoding) для каждого элемента словаря V. Мы получим векторы из нулей и единиц, где единицы представляют место слова в V:
- Вам = [1, 0, 0, 0]
- дня = [0, 1, 0, 0]
- отличного = [0, 0, 1, 0]
- хорошего = [0, 0, 0, 1]
Если мы попытаемся визуализировать эти кодирования, мы сможем представить себе четырехмерное пространство, где каждое слово занимает одно из измерений и не имеет ничего общего с остальными (без проекции по другим измерениям). Это означает, что «Вам» и «дня» так же близки по значению, как «отличного» и «хорошего», а это неверно.
Наша цель состоит в том, чтобы слова с похожим контекстом занимали близкие пространственные позиции. С точки зрения математики, косинус угла между такими векторами должен стремиться к единице, то есть угол стремиться к нулю.
Здесь возникает идея распределенных представлений. Мы интуитивно вводим некоторую зависимость одного слова от другого, чтобы устранить словарную независимость быстрого кодирования. С этим прекрасно справляется метод Word2Vec и его разновидности – скип-грам (Skip-Gram) и СBOW (Continuous Bag of Words – "Обычный мешок слов").
Посмотрим, как работает этот метод на Python. Импортируем библиотеку Gensim:
>>> from gensim.models import Word2Vec
Определим тренировочные данные:
>>> sentences = [
['это', 'первое', 'предложение', 'для', 'word2vec'],
['это', 'второе', 'предложение'],
['еще', 'одно', 'предложение'],
['и', 'еще', 'одно'],
['и', 'последнее', 'предложение']
]
Обучим модель:
>>> model = Word2Vec(sentences, min_count = 1)
>>> print(model)
Word2Vec(vocab=10, size=100, alpha=0.025)
Выведем словарь:
>>> words = list(model.wv.vocab)print(words)
['это', 'первое', 'предложение', 'для', 'word2vec', 'второе',
'еще', 'одно', 'и', 'последнее']
Отобразим вектор для слова "предложение"
>>> print(model['предложение'])
[ 2.7951182e-04 -3.6876823e-03 -3.4739964e-03 -4.6593761e-03
-6.8065652e-04 4.6762540e-03 -4.9465592e-03 -1.5376145e-03
-3.8114607e-03 1.9782037e-03 4.8228186e-03 -4.4843061e-03
-1.3968484e-03 3.9083948e-03 -3.8989992e-03 -3.7398134e-04
-4.4471960e-04 -3.5032684e-03 -3.0881944e-03 -3.6933757e-03
-3.1514678e-03 -7.4106758e-04 -3.2368137e-03 7.4947416e-04
-3.8781634e-03 -4.5922254e-03 -1.8124420e-03 -4.7787088e-03
-9.7891991e-04 -1.4414476e-03 -1.3748884e-03 -1.8673521e-03
2.7702458e-03 2.6762027e-03 -3.4182698e-03 -3.2053180e-03
-3.4514379e-03 9.6735061e-04 -2.2312114e-03 1.9647963e-03
5.5354909e-04 8.5186592e-04 -3.7264288e-03 2.9388207e-03
-2.3999424e-03 -1.4355985e-03 2.6428787e-04 3.1569401e-05
-2.1141735e-03 -2.2317225e-03 5.8705662e-04 -2.2599476e-03
-4.6893093e-03 -1.8836980e-03 1.2283499e-03 1.9487643e-03
2.5195950e-03 3.3758313e-03 2.0288548e-03 -1.4213409e-03
3.8691245e-03 -4.8152455e-03 -4.3285973e-03 -1.7564168e-03
-3.2937850e-03 9.5582556e-04 -4.7819293e-03 4.0930249e-03
3.9580315e-03 -4.0846365e-03 -2.4885340e-03 4.3221661e-03
4.4720429e-03 -1.2656129e-03 -1.5065590e-03 2.2809014e-03
2.2248828e-03 3.2351266e-03 -2.7615167e-03 -8.9465710e-04
2.5687986e-03 1.3637041e-04 2.6037137e-03 -3.8954872e-03
-1.4932255e-03 -1.1712565e-03 4.9797511e-03 1.6469969e-03
2.5363572e-04 -1.6010831e-03 -2.7519872e-03 3.0719070e-03
7.8561262e-04 8.4289414e-04 -2.1506855e-03 -2.5069705e-04
3.7172137e-04 2.2009613e-03 -8.7891234e-04 4.8939087e-03]