Эмбеддинг — это сжатое представление о контексте слова.
Почему важно знать контекст слова? Потому что мы верим в дистрибутивную гипотезу — что похожие по смыслу слова употребляются в сходных контекстах.

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

Каноничный пример эмбеддинга – это эмбеддинг слова (словоформенный эмбеддинг).

Что обычно выступает в роли дискретного вектора признаков? Булев вектор, соответствующий всевозможным значениям какой-то категории (например, все возможные части речи или все возможные слова из какого-то ограниченного словаря).

Для словоформенных эмбеддингов такой категорией обычно выступает индекс слова в словаре. Допустим, есть словарь размерностью 100 тысяч. Соответственно, каждое слово имеет дискретный вектор признаков – булев вектор размерности 100 тысяч, где на одном месте (индексе данного слова в нашем словаре) стоит единичка, а на остальных – нули.

Почему мы хотим отображать наши дискретные вектора признаков в непрерывные заданной размерности? Потому что вектора размерностью 100 тысяч не очень удобно использовать для вычислений, а вот вектора целых чисел размерности 100, 200 или, например, 300, — намного удобнее.

В принципе, мы можем не пытаться накладывать никаких дополнительных ограничений на такое отображение. Но раз уж мы строим такое отображение, давайте попытаемся добиться, чтобы вектора похожих по смыслу слов также были в каком-то смысле близки. Это делается с помощью простой feed-forward нейросетки.

Обучение эмбеддингов

Как эмбеддинги обучаются? Мы пытаемся решить задачу восстановления слова по контексту (или наоборот, восстановления контекста по слову). В простейшем случае мы получаем на вход индекс в словаре предыдущего слова (булев вектор размерности словаря) и пытаемся определить индекс в словаре нашего слова. Делается это с помощью сетки с предельно простой архитектурой: два полносвязных слоя. Сначала идет полносвязный слой из булева вектора размерности словаря в скрытый слой размерности эмбеддинга (т.е. просто умножение булева вектора на матрицу нужной размерности). А потом наоборот, полносвязный слой с softmax из скрытого слоя размерности эмбеддинга в вектор размерности словаря. Благодаря функции активации softmax, мы получаем распределение вероятностей нашего слова и можем выбрать самый вероятный вариант.


Эмбеддингом i-го слова будет просто i-я строка в матрице перехода W.

В используемых на практике моделях архитектура сложнее, но ненамного. Главное отличие в том, что мы используем не один вектор из контекста для определения нашего слова, а несколько (например, все в окне размера 3). Несколько более популярным вариантом является ситуация, когда мы пытаемся предсказать не слово по контексту, а наоборот контекст по слову. Такой подход называется Skip-gram.

Давайте приведем пример применения задачи, которая решается во время обучения эмбеддингов (в варианте CBOW — предсказания слова по контексту). Например, пусть контекст токена состоит из 2 предыдущих слов. Если мы обучались на корпусе текстов про современную русскую литературу и контекст состоит из слов “поэт Марина”, то, скорее всего, самым вероятным следующим словом будет слово “Цветаева”.

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

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

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

Похожие соображения используются и при предобучении для современных архитектур, упомянутых выше — ELMo, ULMFit, BERT. Они тоже используют при обучении неразмеченные данные, и поэтому обучаются на максимально большом доступном корпусе (хотя сами архитектуры, конечно, сложнее, чем у классических эмбеддингов).

Зачем нужны эмбеддинги?

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

Во-первых, мы уменьшаем размерность пространства признаков, потому что с непрерывными векторами размерностью несколько сотен работать намного удобнее, чем с признаками-булевыми векторами размерностью 100 тысяч. Уменьшение размерности признакового пространства – это очень важно: оно сказывается на быстродействии, это удобнее для обучения, и поэтому алгоритмы обучаются лучше.
Во-вторых, учет близости элементов в исходном пространстве. Слова похожи друг на друга по-разному. И разные координаты эмбеддингов способны ловить эту схожесть. Приведу простой грубый и набивший всем оскомину пример. Эмбеддинг вполне способен уловить, что король отличается от королевы примерно так же, как мужчина от женщины. Или наоборот, король отличается от мужчины, как королева от женщины. Точно так же схожи связи разных стран со своими столицами. Хорошо обученная модель на достаточно большом корпусе способна понять, что Москва отличается от России тем же, чем Вашингтон от США.

Но не нужно думать, что такая векторная арифметика работает надежно. В статье, где были введены эмбеддинги, были примеры, что Ангела относится к Меркель примерно так же, как Барак к Обаме, Николя к Саркози и Путин к Медведеву. Поэтому полагаться на эту арифметику не стоит, хотя это все равно важно, и компьютеру намного проще, когда он знает эту информацию, пусть она и содержит неточности.