Распределённые представления: слово — это его контекст
Главный сдвиг этого раздела: вместо того чтобы давать слову номер, мы даём ему плотный вектор, который улавливает его смысл из контекста.
Дистрибутивная гипотеза: слова, которые встречаются в похожих контекстах, имеют похожий смысл. «Слово — это компания, которую оно водит».
Откуда брать смысл слова
Как объяснить машине, что «кот» и «кошка» близки? Подсмотреть значение в словаре она не может. Но есть гениально простая идея: посмотреть, в каком окружении слово встречается. «Кот» и «кошка» окружены одними и теми же словами: «мяукает», «пушистая», «молоко», «лапы». «Молоток» — совсем другими: «забить», «гвоздь», «ручка». Значит, смысл можно вывести из контекста.
Представьте предложения с пропуском: «___ мяукает и пьёт молоко». Сюда подходят «кот», «кошка», «котёнок» — и не подходит «молоток». Слова, заполняющие одни и те же пропуски, близки по смыслу. Это и есть дистрибутивная гипотеза.
От счётчиков контекста к векторам
Простейшая реализация идеи: для каждого слова посчитать, какие слова стоят рядом с ним в текстах. Получится вектор «соседей». У «кота» и «кошки» эти векторы будут похожи. Посчитаем на игрушечном корпусе.
from collections import defaultdict, Counter
corpus = [
"кот пьёт молоко",
"кошка пьёт молоко",
"кот мяукает громко",
"кошка мяукает громко",
"молоток забивает гвоздь",
]
# для каждого слова считаем соседей (окно = всё предложение)
context = defaultdict(Counter)
for sent in corpus:
words = sent.split()
for i, w in enumerate(words):
for j, other in enumerate(words):
if i != j:
context[w][other] += 1
for w in ["кот", "кошка", "молоток"]:
print(w, "->", dict(context[w]))
Вывод:
кот -> {'пьёт': 1, 'молоко': 1, 'мяукает': 1, 'громко': 1}
кошка -> {'пьёт': 1, 'молоко': 1, 'мяукает': 1, 'громко': 1}
молоток -> {'забивает': 1, 'гвоздь': 1}
«Кот» и «кошка» имеют идентичные векторы контекста, а «молоток» — совершенно другой. Мы вывели смысловую близость, ни разу не заглянув в словарь, — только из того, кто с кем соседствует. Это зерно, из которого вырастет word2vec.
Что такое эмбеддинг
Эмбеддинг (embedding) — плотный вектор фиксированной небольшой длины (обычно 100-300 чисел), который представляет слово так, что близкие по смыслу слова имеют близкие векторы. «Плотный» — значит почти все числа ненулевые и осмысленные, в отличие от разрежённого one-hot.
| One-hot (классика) | Эмбеддинг | |
| Длина | = размер словаря | ~300 |
| Заполнение | один 1, остальное нули | плотный, дробные числа |
| Смысл слова | нет | зашит в геометрию |
| Близость «кот»/«кошка» | 0 | высокая |
Откуда берутся настоящие эмбеддинги
Наш счётчик соседей — наивная версия. Настоящие эмбеддинги обучают нейросетью на огромных корпусах: модель учится предсказывать слово по контексту (или наоборот), и в процессе подбирает векторы так, чтобы это получалось лучше всего. Самый известный метод — word2vec — разберём в следующем уроке.
Итог
- Дистрибутивная гипотеза: смысл слова — в его контексте.
- Слова с похожим окружением получают похожие векторы.
- Эмбеддинг — плотный вектор ~300 чисел, кодирующий смысл слова.
- В отличие от one-hot, у эмбеддингов «кот» и «кошка» близки.