Линейные операции над векторами 🎯
Представь: ты работаешь с ChatGPT API, и каждый раз когда отправляешь текст, он превращается в набор из 1536 чисел — это embedding вектор. Почему именно вектор? Потому что эти числа упорядочены и с ними можно делать математические операции, которые имеют смысл!
Когда ты ищешь похожие документы в векторной базе данных (Pinecone, Weaviate, Qdrant), система вычисляет косинусное расстояние между векторами. Когда модель обучается, она масштабирует градиенты. Когда нормализуешь embeddings для поиска — используешь деление вектора на его длину.
Все эти операции — линейные операции над векторами. И хорошая новость: их всего 5 основных, и они удивительно просты!
В этом уроке ты узнаешь: 🎯 Что такое вектор на самом деле (не абстрактная стрелочка, а конкретный инструмент) 🎯 Как складывать и вычитать векторы (и зачем это в ML) 🎯 Что такое скалярное произведение (основа cosine similarity!) 🎯 Как нормализовать векторы (критично для поиска по embeddings) 🎯 Как всё это работает в реальном коде (примеры на Python)
Готов? Тогда поехали — обещаю, что через 45 минут ты поймёшь математику, которая лежит в основе 90% современного ML! 🚀
Что такое вектор простыми словами
Интуиция через embeddings
Давай начнём с того, с чем ты уже работал (или слышал): text embeddings.
Когда ты отправляешь слово “кот” в OpenAI Embeddings API, получаешь обратно что-то вроде:
[0.023, -0.145, 0.891, ..., 0.234] # 1536 чисел
А для слова “собака”:
[0.019, -0.132, 0.856, ..., 0.198]
Что это? Это векторы — упорядоченные списки чисел. Каждое число — это координата в многомерном пространстве.
Аналогия из жизни: Представь, что каждое слово — это точка в 1536-мерном пространстве. Координаты говорят, “где” это слово находится. Похожие по смыслу слова (кот/собака) будут находиться близко, а разные (кот/математика) — далеко.
Но как измерить “близко” или “далеко”? Вот тут и нужны векторные операции!
Строгое определение
Определение: Вектор — это упорядоченный набор чисел (координат), которые описывают точку или направление в многомерном пространстве.
Обозначения: - $\vec{v}$ или v — вектор (жирный шрифт или стрелка сверху) - $v_1, v_2, …, v_n$ — координаты вектора (компоненты) - $n$ — размерность вектора (количество координат) - $\mathbb{R}^n$ — пространство всех векторов размерности $n$
Запись вектора:
Столбец: Строка:
⎡ v₁ ⎤ [v₁, v₂, v₃, ..., vₙ]
⎢ v₂ ⎥
⎢ v₃ ⎥
⎢ .. ⎥
⎣ vₙ ⎦
В ML-контексте: - Embedding вектор слова “кот”: $\vec{e}_{\text{кот}} \in \mathbb{R}^{1536}$ - Feature вектор изображения: $\vec{x} \in \mathbb{R}^{2048}$ - Вектор весов нейронной сети: $\vec{w} \in \mathbb{R}^{784}$
Примеры векторов в реальной жизни
Пример 1 (простой): 2D вектор — координаты на карте
Представь GPS-координаты кафе:
Кафе "Старбакс": (55.7558, 37.6173) # широта, долгота
Это вектор $\vec{v} = [55.7558, 37.6173] \in \mathbb{R}^2$
Почему это вектор? - Две координаты (2D пространство) - Описывает точку на плоскости - Можно вычислять расстояния между точками
Пример 2 (средний): Feature вектор пользователя в рекомендательной системе
Netflix хранит информацию о твоих предпочтениях:
user_vector = [
0.85, # любит комедии (0-1)
0.12, # любит ужасы
0.67, # любит драмы
0.94, # предпочитает новинки
0.23 # смотрит документалки
]
Это вектор $\vec{u} \in \mathbb{R}^5$ — пять характеристик пользователя.
Применение: Чтобы найти похожих пользователей, Netflix сравнивает векторы (вычисляет расстояние между ними).
Пример 3 (сложный): Word2Vec embedding
Классический пример из NLP. Слово “king” (король):
king = [0.50451, 0.68607, -0.59517, ..., 0.23425] # 300 чисел
Эти 300 чисел закодировали смысл слова! Каждая координата — это “насколько слово связано” с определённым скрытым концептом (который модель выучила сама).
Магия векторов:
king - man + woman ≈ queen
Буквально: если взять вектор “король”, вычесть “мужчина” и добавить “женщина”, получится вектор близкий к “королева”!
Как такое возможно? Благодаря линейным операциям, которые мы сейчас изучим!
Почему это важно
Векторы — это язык машинного обучения: - Все данные представляются как векторы (тексты, изображения, звук) - Нейронные сети работают с векторами и матрицами - Сравнение объектов = вычисление расстояний между векторами - Обучение модели = изменение весовых векторов
Без понимания векторов невозможно понять, как работает ML. Хорошая новость: базовые операции очень просты!
Операция 1: Сложение векторов ➕
Что это такое простыми словами
Представь, что у тебя два embedding вектора:
embedding_1 = [0.2, 0.5, 0.8] # embedding слова "нейронная"
embedding_2 = [0.3, 0.1, 0.4] # embedding слова "сеть"
Если сложить их, получится вектор, который комбинирует информацию из обоих:
combined = [0.2+0.3, 0.5+0.1, 0.8+0.4] = [0.5, 0.6, 1.2]
Это грубая, но рабочая идея: сложение векторов объединяет их “смыслы”. Именно так работают некоторые методы композиции в NLP!
Геометрическая интерпретация
В 2D пространстве сложение векторов — это правило параллелограмма:
B (конец v₂)
↗
/│
/ │ v₂
/ │
A──→C (конец v₁)
v₁
v₁ + v₂ = вектор из A в B
Но в ML мы редко думаем геометрически (трудно представить 1536 измерений!). Вместо этого думаем покомпонентно.
Строгое определение
Определение: Сложение векторов $\vec{v}$ и $\vec{w}$ размерности $n$ — это вектор $\vec{v} + \vec{w}$, чьи координаты равны сумме соответствующих координат:
$$ \vec{v} + \vec{w} = \begin{bmatrix} v_1 \ v_2 \ \vdots \ v_n \end{bmatrix} + \begin{bmatrix} w_1 \ w_2 \ \vdots \ w_n \end{bmatrix} = \begin{bmatrix} v_1 + w_1 \ v_2 + w_2 \ \vdots \ v_n + w_n \end{bmatrix} $$
Важно: Складывать можно только векторы одинаковой размерности!
Свойства: - Коммутативность: $\vec{v} + \vec{w} = \vec{w} + \vec{v}$ - Ассоциативность: $(\vec{u} + \vec{v}) + \vec{w} = \vec{u} + (\vec{v} + \vec{w})$ - Нейтральный элемент: $\vec{v} + \vec{0} = \vec{v}$ (нулевой вектор)
Примеры с подробным разбором
Пример 1 (простой): Сложение 2D векторов
Даны координаты двух точек на карте:
cafe_1 = [3, 4] # кафе 1: 3 км на восток, 4 км на север от центра
cafe_2 = [1, 2] # кафе 2: 1 км на восток, 2 км на север от центра
Найти: сумму векторов (не имеет прямого физического смысла, но покажем механику).
Решение:
Шаг 1: Записываем векторы в столбец для наглядности:
v₁ = [3] v₂ = [1]
[4] [2]
Шаг 2: Складываем покомпонентно:
v₁ + v₂ = [3 + 1] = [4]
[4 + 2] [6]
Шаг 3: Интерпретация: Получили вектор $[4, 6]$ — точка на 4 км восточнее и 6 км севернее центра.
Ответ: $\vec{v}_1 + \vec{v}_2 = [4, 6]$
В Python:
import numpy as np
v1 = np.array([3, 4])
v2 = np.array([1, 2])
result = v1 + v2 # [4, 6]
print(result) # [4 6]
Пример 2 (средний): Усреднение embeddings
Задача из реальной практики: у нас есть embeddings двух предложений:
emb1 = [0.2, 0.8, -0.3] # "Машинное обучение"
emb2 = [0.4, 0.6, -0.1] # "Искусственный интеллект"
Хотим получить средний embedding (простой способ объединить семантику).
Решение:
Шаг 1: Складываем векторы покомпонентно:
emb1 + emb2 = [0.2 + 0.4, 0.8 + 0.6, -0.3 + (-0.1)]
= [0.6, 1.4, -0.4]
Шаг 2: Делим каждую координату на 2 (усреднение):
(emb1 + emb2) / 2 = [0.6/2, 1.4/2, -0.4/2]
= [0.3, 0.7, -0.2]
Шаг 3: Интерпретация: Получили вектор, который “между” двумя исходными. Это грубое, но быстрое представление обоих концептов вместе!
Ответ: Средний embedding = $[0.3, 0.7, -0.2]$
В Python:
import numpy as np
emb1 = np.array([0.2, 0.8, -0.3])
emb2 = np.array([0.4, 0.6, -0.1])
# Среднее
mean_emb = (emb1 + emb2) / 2
print(mean_emb) # [0.3 0.7 -0.2]
Где применяется: - Sentence BERT усредняет embeddings слов для получения embedding предложения - В RAG системах иногда комбинируют embeddings запроса и контекста
Пример 3 (сложный): Композиция векторов в Word2Vec
Классический пример аналогий:
king = [0.5, 0.8, -0.3, 0.6]
man = [0.2, 0.3, -0.1, 0.2]
woman = [0.3, 0.1, 0.2, 0.3]
Хотим найти: $\text{king} - \text{man} + \text{woman} \approx \text{queen}$
Решение:
Шаг 1: Вычитаем вектор “man” из “king” (вычитание разберём позже, но это тоже покомпонентно):
king - man = [0.5-0.2, 0.8-0.3, -0.3-(-0.1), 0.6-0.2]
= [0.3, 0.5, -0.2, 0.4]
Шаг 2: Прибавляем вектор “woman”:
[0.3, 0.5, -0.2, 0.4] + [0.3, 0.1, 0.2, 0.3]
= [0.3+0.3, 0.5+0.1, -0.2+0.2, 0.4+0.3]
= [0.6, 0.6, 0.0, 0.7]
Шаг 3: Интерпретация: Этот вектор $[0.6, 0.6, 0.0, 0.7]$ должен быть близок к embedding слова “queen”! Проверяем (условно):
queen = [0.58, 0.62, 0.02, 0.68] # очень близко!
Почему это работает? Вектор “man” содержит информацию о “мужественности”. Когда мы вычитаем его из “king”, остаётся “королевскость”. Добавляя “woman”, получаем “королевскость + женственность” = “queen”!
Ответ: $\vec{king} - \vec{man} + \vec{woman} = [0.6, 0.6, 0.0, 0.7] \approx \vec{queen}$
В Python (настоящий Word2Vec):
from gensim.models import KeyedVectors
# Загрузка модели
model = KeyedVectors.load_word2vec_format('GoogleNews-vectors-negative300.bin', binary=True)
# Аналогия
result = model.most_similar(positive=['king', 'woman'], negative=['man'], topn=1)
print(result) # [('queen', 0.712)] — работает!
Применение в ML: Mean Pooling
Задача: Есть предложение “I love cats”. Каждое слово имеет embedding:
I = [0.1, 0.5, 0.2]
love = [0.8, 0.3, 0.9]
cats = [0.4, 0.7, 0.1]
Как получить один вектор для всего предложения?
Решение — Mean Pooling:
Шаг 1: Складываем все векторы:
sum = [0.1, 0.5, 0.2] + [0.8, 0.3, 0.9] + [0.4, 0.7, 0.1]
= [0.1+0.8+0.4, 0.5+0.3+0.7, 0.2+0.9+0.1]
= [1.3, 1.5, 1.2]
Шаг 2: Делим на количество слов (3):
mean = [1.3/3, 1.5/3, 1.2/3]
= [0.433, 0.5, 0.4]
Ответ: Embedding предложения = $[0.433, 0.5, 0.4]$
Python (реальный код):
import torch
# Embeddings слов
word_embeddings = torch.tensor([
[0.1, 0.5, 0.2], # I
[0.8, 0.3, 0.9], # love
[0.4, 0.7, 0.1] # cats
])
# Mean pooling
sentence_embedding = torch.mean(word_embeddings, dim=0)
print(sentence_embedding) # tensor([0.4333, 0.5000, 0.4000])
Где применяется: - Sentence Transformers (SBERT) - Классические Seq2Seq модели - Любые задачи, где нужно “сжать” последовательность в один вектор
Операция 2: Вычитание векторов ➖
Что это такое простыми словами
Вычитание векторов — это разность координат. В ML это часто интерпретируется как расстояние или изменение.
Пример:
query_embedding = [0.5, 0.8, 0.3]
doc_embedding = [0.4, 0.9, 0.2]
difference = [0.5-0.4, 0.8-0.9, 0.3-0.2] = [0.1, -0.1, 0.1]
Этот вектор “разности” показывает, “насколько” запрос отличается от документа в каждом измерении.
Строгое определение
Определение: Вычитание вектора $\vec{w}$ из вектора $\vec{v}$ — это вектор $\vec{v} - \vec{w}$, где каждая координата равна разности соответствующих координат:
$$ \vec{v} - \vec{w} = \begin{bmatrix} v_1 \ v_2 \ \vdots \ v_n \end{bmatrix} - \begin{bmatrix} w_1 \ w_2 \ \vdots \ w_n \end{bmatrix} = \begin{bmatrix} v_1 - w_1 \ v_2 - w_2 \ \vdots \ v_n - w_n \end{bmatrix} $$
Связь со сложением: $$\vec{v} - \vec{w} = \vec{v} + (-\vec{w})$$
где $-\vec{w} = [-w_1, -w_2, …, -w_n]$ — вектор с противоположными знаками.
Примеры с подробным разбором
Пример 1 (простой): Вычитание 2D координат
GPS координаты:
home = [55.7558, 37.6173] # твой дом
office = [55.7512, 37.6250] # офис
Найти: вектор от офиса до дома.
Решение:
Шаг 1: Вычитаем координаты:
home - office = [55.7558 - 55.7512, 37.6173 - 37.6250]
= [0.0046, -0.0077]
Шаг 2: Интерпретация: - Широта: +0.0046° (на север) - Долгота: -0.0077° (на запад)
Это направление от офиса к дому!
Ответ: Вектор от офиса к дому = $[0.0046, -0.0077]$
Пример 2 (средний): Вычисление градиента в нейронке
В процессе обучения нейронной сети мы обновляем веса:
old_weights = [0.5, 0.3, 0.8]
new_weights = [0.48, 0.32, 0.79]
Найти: на сколько изменились веса (это упрощённый “градиент”).
Решение:
Шаг 1: Вычитаем старые веса из новых:
change = new - old
= [0.48 - 0.5, 0.32 - 0.3, 0.79 - 0.8]
= [-0.02, 0.02, -0.01]
Шаг 2: Интерпретация: - Первый вес уменьшился на 0.02 - Второй вес увеличился на 0.02 - Третий вес уменьшился на 0.01
Ответ: Изменение весов = $[-0.02, 0.02, -0.01]$
В коде обучения:
# Упрощённый шаг градиентного спуска
learning_rate = 0.01
gradient = torch.tensor([2.0, -2.0, 1.0]) # вычислен backward()
weights = torch.tensor([0.5, 0.3, 0.8])
# Обновление
new_weights = weights - learning_rate * gradient
# = [0.5, 0.3, 0.8] - 0.01 * [2.0, -2.0, 1.0]
# = [0.5, 0.3, 0.8] - [0.02, -0.02, 0.01]
# = [0.48, 0.32, 0.79]
Пример 3 (сложный): Вычисление Error Vector в RAG
В RAG системе сравниваем query embedding с найденными документами:
query = [0.5, 0.8, 0.2, 0.9]
doc1 = [0.52, 0.78, 0.25, 0.88] # очень похожий
doc2 = [0.1, 0.3, 0.7, 0.2] # не похожий
Найти: векторы “ошибки” (насколько далеки документы от запроса).
Решение для doc1:
Шаг 1: Вычитаем query из doc1:
error1 = doc1 - query
= [0.52-0.5, 0.78-0.8, 0.25-0.2, 0.88-0.9]
= [0.02, -0.02, 0.05, -0.02]
Шаг 2: Интерпретация: Все компоненты близки к нулю → документ очень похож на запрос!
Решение для doc2:
Шаг 1: Вычитаем query из doc2:
error2 = doc2 - query
= [0.1-0.5, 0.3-0.8, 0.7-0.2, 0.2-0.9]
= [-0.4, -0.5, 0.5, -0.7]
Шаг 2: Интерпретация: Компоненты большие → документ далёк от запроса!
Ответ: - $error_1 = [0.02, -0.02, 0.05, -0.02]$ (похож) - $error_2 = [-0.4, -0.5, 0.5, -0.7]$ (не похож)
В реальном коде:
import numpy as np
query = np.array([0.5, 0.8, 0.2, 0.9])
doc1 = np.array([0.52, 0.78, 0.25, 0.88])
doc2 = np.array([0.1, 0.3, 0.7, 0.2])
error1 = doc1 - query
error2 = doc2 - query
print("Error 1:", error1) # [ 0.02 -0.02 0.05 -0.02]
print("Error 2:", error2) # [-0.4 -0.5 0.5 -0.7 ]
# Можем вычислить "величину ошибки" (норму вектора, изучим позже)
print("Distance 1:", np.linalg.norm(error1)) # 0.059
print("Distance 2:", np.linalg.norm(error2)) # 1.077
Применение: В векторных БД (Pinecone, Qdrant) именно так вычисляют расстояния между векторами!
Операция 3: Умножение вектора на число (скаляр) ✖️
Что это такое простыми словами
Умножение вектора на число (скаляр) — это масштабирование. Все координаты увеличиваются или уменьшаются в одинаковое количество раз.
Пример:
embedding = [0.2, 0.5, 0.8]
scaled = 2 * embedding = [0.4, 1.0, 1.6] # увеличили в 2 раза
В ML это используется: - Для изменения learning rate (насколько сильно обновлять веса) - Для нормализации (деление на норму — частный случай!) - Для взвешивания векторов (attention механизм!)
Строгое определение
Определение: Умножение вектора $\vec{v}$ на число (скаляр) $\alpha$ — это вектор $\alpha \vec{v}$, где каждая координата умножена на $\alpha$:
$$ \alpha \vec{v} = \alpha \begin{bmatrix} v_1 \ v_2 \ \vdots \ v_n \end{bmatrix} = \begin{bmatrix} \alpha v_1 \ \alpha v_2 \ \vdots \ \alpha v_n \end{bmatrix} $$
Свойства: - Ассоциативность: $(\alpha \beta) \vec{v} = \alpha (\beta \vec{v})$ - Дистрибутивность 1: $(\alpha + \beta) \vec{v} = \alpha \vec{v} + \beta \vec{v}$ - Дистрибутивность 2: $\alpha (\vec{v} + \vec{w}) = \alpha \vec{v} + \alpha \vec{w}$ - Нейтральный элемент: $1 \cdot \vec{v} = \vec{v}$
Геометрическая интерпретация
- $\alpha > 1$: вектор увеличивается (растягивается)
- $0 < \alpha < 1$: вектор уменьшается (сжимается)
- $\alpha = 0$: вектор становится нулевым
- $\alpha < 0$: вектор переворачивается (меняет направление) и масштабируется
Примеры с подробным разбором
Пример 1 (простой): Увеличение координат
Дан вектор координат:
v = [3, 4]
Найти: удвоенный вектор (умножение на 2).
Решение:
Шаг 1: Умножаем каждую координату на 2:
2v = 2 * [3, 4] = [2*3, 2*4] = [6, 8]
Шаг 2: Интерпретация: Если исходный вектор имел длину 5 (по теореме Пифагора: $\sqrt{3^2+4^2} = 5$), то новый имеет длину 10.
Ответ: $2\vec{v} = [6, 8]$
Пример 2 (средний): Градиентный спуск с learning rate
Имеем градиент функции потерь:
gradient = [2.0, -3.0, 1.5] # направление наискорейшего роста
learning_rate = 0.01
Найти: шаг обновления весов (градиент, умноженный на learning rate).
Решение:
Шаг 1: Умножаем градиент на learning rate:
step = 0.01 * [2.0, -3.0, 1.5]
= [0.01*2.0, 0.01*(-3.0), 0.01*1.5]
= [0.02, -0.03, 0.015]
Шаг 2: Интерпретация: Это маленький шаг в направлении градиента. Если бы learning_rate = 1, шаг был бы слишком большим! 0.01 масштабирует градиент до безопасного размера.
Шаг 3: Обновление весов (вычитаем шаг):
weights = [0.5, 0.8, 0.3]
new_weights = weights - step
= [0.5-0.02, 0.8-(-0.03), 0.3-0.015]
= [0.48, 0.83, 0.285]
Ответ: Шаг = $[0.02, -0.03, 0.015]$
В PyTorch:
import torch
weights = torch.tensor([0.5, 0.8, 0.3], requires_grad=True)
gradient = torch.tensor([2.0, -3.0, 1.5])
learning_rate = 0.01
# Обновление
with torch.no_grad():
weights -= learning_rate * gradient
print(weights) # tensor([0.4800, 0.8300, 0.2850])
Пример 3 (сложный): Attention-взвешивание векторов
В механизме Attention мы взвешиваем векторы по “важности”:
# Три слова в предложении
word1 = [0.2, 0.5] # "I"
word2 = [0.8, 0.3] # "love"
word3 = [0.4, 0.7] # "cats"
# Attention scores (насколько каждое слово важно для текущего контекста)
attention_scores = [0.1, 0.7, 0.2] # "love" самое важное!
Найти: взвешенную сумму (каждый вектор умножаем на его attention score).
Решение:
Шаг 1: Умножаем каждый вектор на его attention score:
weighted1 = 0.1 * [0.2, 0.5] = [0.02, 0.05]
weighted2 = 0.7 * [0.8, 0.3] = [0.56, 0.21]
weighted3 = 0.2 * [0.4, 0.7] = [0.08, 0.14]
Шаг 2: Складываем взвешенные векторы:
output = weighted1 + weighted2 + weighted3
= [0.02, 0.05] + [0.56, 0.21] + [0.08, 0.14]
= [0.02+0.56+0.08, 0.05+0.21+0.14]
= [0.66, 0.40]
Шаг 3: Интерпретация: Итоговый вектор $[0.66, 0.40]$ ближе к вектору “love” (т.к. его вес 0.7 был максимальным). Attention “сфокусировал” представление на важном слове!
Ответ: Attention output = $[0.66, 0.40]$
В PyTorch (упрощённо):
import torch
# Векторы слов
words = torch.tensor([
[0.2, 0.5], # I
[0.8, 0.3], # love
[0.4, 0.7] # cats
])
# Attention scores
attention = torch.tensor([0.1, 0.7, 0.2])
# Взвешенная сумма (умножение + сложение)
# attention.unsqueeze(1) превращает [0.1, 0.7, 0.2] в [[0.1], [0.7], [0.2]]
weighted = words * attention.unsqueeze(1)
output = weighted.sum(dim=0)
print(output) # tensor([0.6600, 0.4000])
Где применяется: - Transformer модели (BERT, GPT) - Self-attention, cross-attention - Механизм внимания в Seq2Seq
Операция 4: Скалярное произведение (dot product) 📐
Что это такое простыми словами
Скалярное произведение — это одна из самых важных операций в ML!
Представь два вектора:
v1 = [1, 2, 3]
v2 = [4, 5, 6]
Скалярное произведение:
v1 · v2 = 1*4 + 2*5 + 3*6 = 4 + 10 + 18 = 32
Результат — одно число (скаляр), которое показывает “насколько векторы направлены в одну сторону”.
Почему это важно: - Cosine similarity = скалярное произведение нормализованных векторов! - Умножение матрицы на вектор = скалярные произведения строк на вектор - Attention в Transformers = скалярные произведения Q и K - Предсказание нейронной сети = скалярное произведение весов и входа!
Строгое определение
Определение: Скалярное произведение (dot product) векторов $\vec{v}$ и $\vec{w}$ размерности $n$ — это число, равное сумме произведений соответствующих координат:
$$ \vec{v} \cdot \vec{w} = \sum_{i=1}^{n} v_i w_i = v_1 w_1 + v_2 w_2 + \cdots + v_n w_n $$
Обозначения: - $\vec{v} \cdot \vec{w}$ — скалярное произведение (dot product) - $\langle \vec{v}, \vec{w} \rangle$ — альтернативное обозначение - Результат: число (скаляр), не вектор!
Свойства: - Коммутативность: $\vec{v} \cdot \vec{w} = \vec{w} \cdot \vec{v}$ - Дистрибутивность: $\vec{v} \cdot (\vec{w} + \vec{u}) = \vec{v} \cdot \vec{w} + \vec{v} \cdot \vec{u}$ - Ассоциативность со скаляром: $(\alpha \vec{v}) \cdot \vec{w} = \alpha (\vec{v} \cdot \vec{w})$ - $\vec{v} \cdot \vec{v} \geq 0$, причём $\vec{v} \cdot \vec{v} = 0$ только если $\vec{v} = \vec{0}$
Геометрическая интерпретация
$$ \vec{v} \cdot \vec{w} = |\vec{v}| \cdot |\vec{w}| \cdot \cos(\theta) $$
где: - $|\vec{v}|$ — длина вектора $\vec{v}$ - $|\vec{w}|$ — длина вектора $\vec{w}$ - $\theta$ — угол между векторами
Что это значит: - $\vec{v} \cdot \vec{w} > 0$ → векторы направлены в одну сторону (угол < 90°) - $\vec{v} \cdot \vec{w} = 0$ → векторы перпендикулярны (угол = 90°) - $\vec{v} \cdot \vec{w} < 0$ → векторы направлены в разные стороны (угол > 90°)
Примеры с подробным разбором
Пример 1 (простой): Скалярное произведение 2D векторов
Даны векторы:
v = [3, 4]
w = [1, 2]
Найти: $\vec{v} \cdot \vec{w}$
Решение:
Шаг 1: Перемножаем соответствующие координаты:
v · w = 3*1 + 4*2
Шаг 2: Суммируем:
= 3 + 8 = 11
Ответ: $\vec{v} \cdot \vec{w} = 11$
В Python:
import numpy as np
v = np.array([3, 4])
w = np.array([1, 2])
result = np.dot(v, w) # или v @ w
print(result) # 11
Пример 2 (средний): Cosine Similarity между embeddings
Самое частое применение в NLP!
Даны embeddings двух слов:
cat = [0.8, 0.6] # embedding слова "кот"
dog = [0.7, 0.5] # embedding слова "собака"
car = [-0.3, 0.9] # embedding слова "машина"
Найти: cosine similarity между “cat” и “dog”, а также между “cat” и “car”.
Решение:
Напоминание формулы: $$ \text{cosine_similarity}(\vec{v}, \vec{w}) = \frac{\vec{v} \cdot \vec{w}}{|\vec{v}| \cdot |\vec{w}|} $$
Для “cat” и “dog”:
Шаг 1: Вычисляем скалярное произведение:
cat · dog = 0.8*0.7 + 0.6*0.5 = 0.56 + 0.3 = 0.86
Шаг 2: Вычисляем длины векторов (нормы):
|cat| = √(0.8² + 0.6²) = √(0.64 + 0.36) = √1.0 = 1.0
|dog| = √(0.7² + 0.5²) = √(0.49 + 0.25) = √0.74 ≈ 0.86
Шаг 3: Делим:
cosine_sim = 0.86 / (1.0 * 0.86) = 0.86 / 0.86 = 1.0
Для “cat” и “car”:
Шаг 1: Скалярное произведение:
cat · car = 0.8*(-0.3) + 0.6*0.9 = -0.24 + 0.54 = 0.30
Шаг 2: Нормы:
|cat| = 1.0 (уже знаем)
|car| = √((-0.3)² + 0.9²) = √(0.09 + 0.81) = √0.90 ≈ 0.95
Шаг 3: Делим:
cosine_sim = 0.30 / (1.0 * 0.95) = 0.30 / 0.95 ≈ 0.316
Интерпретация: - “cat” и “dog”: similarity = 1.0 → очень похожи (почти параллельны) - “cat” и “car”: similarity = 0.316 → немного похожи (но не очень)
Ответ: - $\text{sim}(\text{cat}, \text{dog}) = 1.0$ - $\text{sim}(\text{cat}, \text{car}) \approx 0.316$
В Python (с нормализацией):
import numpy as np
from numpy.linalg import norm
cat = np.array([0.8, 0.6])
dog = np.array([0.7, 0.5])
car = np.array([-0.3, 0.9])
def cosine_similarity(v1, v2):
return np.dot(v1, v2) / (norm(v1) * norm(v2))
print(cosine_similarity(cat, dog)) # 1.0
print(cosine_similarity(cat, car)) # 0.316
Где применяется: - Поиск похожих документов в RAG - Рекомендательные системы - Semantic search (OpenAI, Cohere) - Duplicate detection
Пример 3 (сложный): Attention Score в Transformer
В механизме Self-Attention вычисляем “насколько каждое слово связано с другими”.
Упрощённо:
# Query вектор (текущее слово "love")
Q = [0.5, 0.8, 0.3]
# Key векторы (все слова в предложении)
K1 = [0.2, 0.4, 0.1] # "I"
K2 = [0.5, 0.7, 0.4] # "love" (само слово)
K3 = [0.6, 0.3, 0.2] # "cats"
Найти: attention scores (насколько “love” связано с каждым словом).
Решение:
Шаг 1: Вычисляем скалярные произведения Q с каждым K:
Q · K1 = 0.5*0.2 + 0.8*0.4 + 0.3*0.1
= 0.1 + 0.32 + 0.03
= 0.45
Q · K2 = 0.5*0.5 + 0.8*0.7 + 0.3*0.4
= 0.25 + 0.56 + 0.12
= 0.93
Q · K3 = 0.5*0.6 + 0.8*0.3 + 0.3*0.2
= 0.3 + 0.24 + 0.06
= 0.60
Шаг 2: Нормализуем через softmax (чтобы сумма = 1):
Сначала экспоненты:
e^0.45 ≈ 1.568
e^0.93 ≈ 2.535
e^0.60 ≈ 1.822
Сумма: $1.568 + 2.535 + 1.822 = 5.925$
Attention scores:
attention1 = 1.568 / 5.925 ≈ 0.265 (26.5%)
attention2 = 2.535 / 5.925 ≈ 0.428 (42.8%)
attention3 = 1.822 / 5.925 ≈ 0.307 (30.7%)
Интерпретация: Слово “love” больше всего “обращает внимание” на само себя (42.8%), потом на “cats” (30.7%), меньше всего на “I” (26.5%).
Ответ: Attention scores = $[0.265, 0.428, 0.307]$
В PyTorch (настоящий Attention):
import torch
import torch.nn.functional as F
Q = torch.tensor([[0.5, 0.8, 0.3]]) # (1, 3)
K = torch.tensor([
[0.2, 0.4, 0.1], # K1
[0.5, 0.7, 0.4], # K2
[0.6, 0.3, 0.2] # K3
]) # (3, 3)
# Скалярные произведения
scores = torch.matmul(Q, K.T) # (1, 3)
print("Raw scores:", scores) # tensor([[0.45, 0.93, 0.60]])
# Softmax
attention = F.softmax(scores, dim=-1)
print("Attention:", attention) # tensor([[0.265, 0.428, 0.307]])
Где применяется: - BERT, GPT, T5 - Self-attention, cross-attention - Vision Transformers (ViT)
Применение: Нейронная сеть (линейный слой)
Задача: Простейшая нейронная сеть с одним нейроном.
Входной вектор:
x = [1.0, 2.0, 3.0] # например, признаки картинки
Веса нейрона:
w = [0.5, -0.3, 0.8]
Bias (смещение):
b = 0.2
Найти: выход нейрона $y = \vec{w} \cdot \vec{x} + b$
Решение:
Шаг 1: Вычисляем скалярное произведение:
w · x = 0.5*1.0 + (-0.3)*2.0 + 0.8*3.0
= 0.5 - 0.6 + 2.4
= 2.3
Шаг 2: Добавляем bias:
y = 2.3 + 0.2 = 2.5
Шаг 3: (Опционально) Применяем функцию активации, например ReLU:
output = max(0, 2.5) = 2.5 (положительное, остаётся без изменений)
Ответ: Выход нейрона = $2.5$
В PyTorch:
import torch
import torch.nn as nn
# Входные данные
x = torch.tensor([1.0, 2.0, 3.0])
# Создаём линейный слой (1 вход размерности 3, 1 выход)
layer = nn.Linear(3, 1, bias=True)
# Устанавливаем веса вручную
with torch.no_grad():
layer.weight = nn.Parameter(torch.tensor([[0.5, -0.3, 0.8]]))
layer.bias = nn.Parameter(torch.tensor([0.2]))
# Прямой проход
output = layer(x)
print(output) # tensor([2.5000])
Операция 5: Норма вектора (длина) 📏
Что это такое простыми словами
Норма (или длина) вектора — это расстояние от начала координат до точки.
Для 2D вектора $\vec{v} = [3, 4]$:
Длина = √(3² + 4²) = √(9 + 16) = √25 = 5
Это теорема Пифагора! В ML норма показывает “величину” вектора, независимо от направления.
Зачем нужно: - Нормализация embeddings (приведение всех векторов к длине 1) - Regularization (L2 регуляризация = штраф за большую норму весов) - Вычисление расстояний (Euclidean distance = норма разности векторов)
Строгое определение
Определение: Евклидова норма (L2-норма) вектора $\vec{v}$ — это число:
$$ |\vec{v}| = |\vec{v}|_2 = \sqrt{v_1^2 + v_2^2 + \cdots + vn^2} = \sqrt{\sum{i=1}^{n} v_i^2} $$
Связь со скалярным произведением: $$ |\vec{v}| = \sqrt{\vec{v} \cdot \vec{v}} $$
Другие виды норм: - L1-норма (Manhattan): $|\vec{v}|_1 = |v_1| + |v_2| + \cdots + |vn|$ - L∞-норма (Max): $|\vec{v}|\infty = \max(|v_1|, |v_2|, \ldots, |v_n|)$
Мы будем использовать L2-норму (самая распространённая).
Нормализация вектора
Нормализовать вектор = привести его длину к 1, сохранив направление.
$$ \hat{v} = \frac{\vec{v}}{|\vec{v}|} $$
где $\hat{v}$ — единичный вектор (длина = 1).
Зачем: - Чтобы сравнивать векторы только по направлению, игнорируя величину - Для корректного вычисления cosine similarity - В нейронных сетях (Batch Normalization, Layer Normalization)
Примеры с подробным разбором
Пример 1 (простой): Длина 2D вектора
Дан вектор:
v = [3, 4]
Найти: длину вектора.
Решение:
Шаг 1: Возводим координаты в квадрат:
3² = 9
4² = 16
Шаг 2: Суммируем:
9 + 16 = 25
Шаг 3: Извлекаем корень:
√25 = 5
Ответ: $|\vec{v}| = 5$
В Python:
import numpy as np
v = np.array([3, 4])
length = np.linalg.norm(v)
print(length) # 5.0
Пример 2 (средний): Нормализация embedding вектора
Дан embedding вектор:
emb = [0.6, 0.8]
Найти: нормализованный вектор (длина = 1).
Решение:
Шаг 1: Вычисляем норму:
|emb| = √(0.6² + 0.8²) = √(0.36 + 0.64) = √1.0 = 1.0
Шаг 2: Делим каждую координату на норму:
normalized = [0.6/1.0, 0.8/1.0] = [0.6, 0.8]
Шаг 3: Проверка: Вектор уже был нормализован! (Его длина была 1.0)
Пример с ненормализованным вектором:
emb2 = [3, 4]
Шаг 1: Норма:
|emb2| = √(3² + 4²) = 5
Шаг 2: Нормализация:
normalized = [3/5, 4/5] = [0.6, 0.8]
Шаг 3: Проверка:
|[0.6, 0.8]| = √(0.36 + 0.64) = 1.0 ✓
Ответ: Нормализованный вектор = $[0.6, 0.8]$
В Python:
import numpy as np
emb2 = np.array([3.0, 4.0])
normalized = emb2 / np.linalg.norm(emb2)
print(normalized) # [0.6 0.8]
print(np.linalg.norm(normalized)) # 1.0
Пример 3 (сложный): Euclidean Distance в векторной БД
В векторной базе данных хранятся embeddings документов. Хотим найти расстояние между query и документом.
query = [0.5, 0.8, 0.2]
doc = [0.52, 0.78, 0.25]
Найти: Euclidean distance (L2 расстояние).
Решение:
Формула: $$ \text{distance}(\vec{q}, \vec{d}) = |\vec{q} - \vec{d}|2 = \sqrt{\sum{i=1}^{n} (q_i - d_i)^2} $$
Шаг 1: Вычисляем вектор разности:
diff = query - doc
= [0.5-0.52, 0.8-0.78, 0.2-0.25]
= [-0.02, 0.02, -0.05]
Шаг 2: Возводим компоненты в квадрат:
(-0.02)² = 0.0004
(0.02)² = 0.0004
(-0.05)² = 0.0025
Шаг 3: Суммируем:
0.0004 + 0.0004 + 0.0025 = 0.0033
Шаг 4: Извлекаем корень:
√0.0033 ≈ 0.0574
Интерпретация: Расстояние очень маленькое (0.057) → документ близок к запросу!
Ответ: Euclidean distance = $0.0574$
В Python:
import numpy as np
query = np.array([0.5, 0.8, 0.2])
doc = np.array([0.52, 0.78, 0.25])
# Способ 1: через разность и норму
distance = np.linalg.norm(query - doc)
print(distance) # 0.0574
# Способ 2: встроенная функция (в scipy)
from scipy.spatial.distance import euclidean
distance2 = euclidean(query, doc)
print(distance2) # 0.0574
Где применяется: - Векторные БД (Pinecone, Qdrant, Weaviate) - KNN алгоритмы - Кластеризация (K-means)
Пример 4 (применение): L2 Regularization
В нейронных сетях добавляют штраф за большие веса (чтобы избежать overfitting).
Функция потерь: $$ \text{Loss} = \text{MSE} + \lambda |\vec{w}|_2^2 $$
где: - MSE — основная ошибка - $\lambda$ — коэффициент регуляризации (например, 0.01) - $|\vec{w}|_2^2$ — квадрат L2-нормы весов
Задача:
weights = [0.5, 1.2, -0.8]
lambda_reg = 0.01
mse = 2.5 # основная ошибка
Найти: итоговую функцию потерь с регуляризацией.
Решение:
Шаг 1: Вычисляем норму весов:
|w| = √(0.5² + 1.2² + (-0.8)²)
= √(0.25 + 1.44 + 0.64)
= √2.33
≈ 1.527
Шаг 2: Возводим в квадрат:
|w|² = 1.527² ≈ 2.33
Шаг 3: Добавляем к MSE:
Loss = MSE + λ * |w|²
= 2.5 + 0.01 * 2.33
= 2.5 + 0.0233
= 2.5233
Интерпретация: Регуляризация добавила небольшой штраф (0.0233). Если бы веса были больше, штраф был бы сильнее!
Ответ: Loss с регуляризацией = $2.5233$
В PyTorch:
import torch
weights = torch.tensor([0.5, 1.2, -0.8])
lambda_reg = 0.01
mse = 2.5
# L2 регуляризация
l2_penalty = lambda_reg * torch.norm(weights, p=2) ** 2
total_loss = mse + l2_penalty
print(total_loss) # 2.5233
Практика: 30 заданий
Базовые (задания 1-10)
Задание 1: Дан вектор $\vec{v} = [2, 5, 3]$. Найдите $2\vec{v}$.
Задание 2: Даны векторы $\vec{a} = [1, 3]$ и $\vec{b} = [2, 4]$. Найдите $\vec{a} + \vec{b}$.
Задание 3: Даны векторы $\vec{u} = [5, 2]$ и $\vec{v} = [1, 3]$. Найдите $\vec{u} - \vec{v}$.
Задание 4: Вычислите скалярное произведение $\vec{v} = [2, 3]$ и $\vec{w} = [4, 1]$.
Задание 5: Найдите длину вектора $\vec{v} = [6, 8]$.
Задание 6: Даны векторы $\vec{a} = [1, 0, 2]$, $\vec{b} = [0, 1, 3]$. Найдите $\vec{a} + \vec{b}$.
Задание 7: Вычислите $3\vec{v}$, где $\vec{v} = [1, -2, 4]$.
Задание 8: Найдите $\vec{a} \cdot \vec{b}$, где $\vec{a} = [1, 2, 3]$, $\vec{b} = [0, 1, 0]$.
Задание 9: Вычислите длину вектора $\vec{v} = [3, 4, 0]$.
Задание 10: Даны $\vec{x} = [2, 1]$, $\vec{y} = [1, 2]$. Найдите $\vec{x} - \vec{y} + \vec{x}$.
Средние (задания 11-20)
Задание 11: Даны embeddings: $\vec{e}_1 = [0.2, 0.5, 0.8]$, $\vec{e}_2 = [0.3, 0.4, 0.6]$. Вычислите средний embedding.
Задание 12: Градиент $\vec{g} = [4.0, -2.0, 6.0]$, learning rate $\alpha = 0.1$. Вычислите шаг обновления $\alpha \vec{g}$.
Задание 13: Найдите расстояние между точками $A = [1, 2, 3]$ и $B = [4, 6, 8]$ (Euclidean distance).
Задание 14: Нормализуйте вектор $\vec{v} = [3, 4]$ (приведите к длине 1).
Задание 15: Вычислите cosine similarity между $\vec{a} = [1, 0]$ и $\vec{b} = [0, 1]$.
Задание 16: Даны веса нейрона $\vec{w} = [0.5, -0.2, 0.3]$, вход $\vec{x} = [1.0, 2.0, 3.0]$, bias $b = 0.1$. Вычислите выход: $y = \vec{w} \cdot \vec{x} + b$.
Задание 17: Найдите длину вектора $\vec{v} = [1, 1, 1, 1]$.
Задание 18: Вычислите $\vec{a} + 2\vec{b}$, где $\vec{a} = [1, 2]$, $\vec{b} = [3, 4]$.
Задание 19: Проверьте, перпендикулярны ли векторы $\vec{u} = [2, 3]$ и $\vec{v} = [3, -2]$ (вычислите скалярное произведение).
Задание 20: Нормализуйте вектор $\vec{v} = [1, 2, 2]$.
Продвинутые (задания 21-30)
Задание 21: Даны embeddings трёх слов:
cat = [0.8, 0.6]
dog = [0.7, 0.7]
car = [-0.5, 0.5]
Вычислите cosine similarity между “cat” и каждым из остальных слов.
Задание 22: В механизме Attention даны:
Q = [0.4, 0.6] # query
K1 = [0.3, 0.5] # key 1
K2 = [0.2, 0.8] # key 2
Вычислите attention scores (скалярные произведения Q с каждым K, затем softmax).
Задание 23: Даны три embedding вектора предложений. Найдите средний:
s1 = [0.1, 0.3, 0.5]
s2 = [0.2, 0.4, 0.6]
s3 = [0.3, 0.5, 0.7]
Задание 24: Вычислите L2 регуляризацию для весов $\vec{w} = [0.3, 0.4, 0.5]$ с коэффициентом $\lambda = 0.01$.
Задание 25: Выполните градиентный спуск: $\vec{w}{\text{new}} = \vec{w}{\text{old}} - \alpha \vec{g}$
w_old = [1.0, 0.5, 0.8]
gradient = [0.2, -0.1, 0.3]
learning_rate = 0.1
Задание 26: В RAG системе есть query и 2 документа:
query = [0.5, 0.5, 0.5]
doc1 = [0.5, 0.6, 0.4] # релевантный
doc2 = [0.1, 0.2, 0.9] # нерелевантный
Вычислите Euclidean distance от query до каждого документа. Какой документ ближе?
Задание 27: Нормализуйте все три вектора и убедитесь, что их длина = 1:
v1 = [1, 0, 0]
v2 = [3, 4]
v3 = [1, 1, 1]
Задание 28: Докажите, что если $\vec{v} \cdot \vec{w} = 0$, то векторы перпендикулярны. Проверьте на примере: $\vec{a} = [1, 2]$, $\vec{b} = [4, -2]$.
Задание 29: В Word2Vec выполните аналогию: $\text{king} - \text{man} + \text{woman} = ?$
king = [0.5, 0.8, 0.3]
man = [0.2, 0.3, 0.1]
woman = [0.3, 0.1, 0.2]
Задание 30: Продвинутое: даны embeddings 5 слов. Найдите 2 самых похожих слова (используйте cosine similarity).
apple = [0.8, 0.2, 0.1]
banana = [0.7, 0.3, 0.2]
car = [0.1, 0.8, 0.7]
bike = [0.2, 0.7, 0.6]
house = [0.5, 0.5, 0.5]
Частые ошибки
❌ Ошибка 1: Складывать векторы разной размерности Неправильно:
v1 = [1, 2]
v2 = [3, 4, 5]
result = v1 + v2 # ОШИБКА! Размерности не совпадают
Правильно: Складывать можно только векторы одинаковой размерности. Почему важно: В ML это часто приводит к багам при работе с embeddings разных моделей.
❌ Ошибка 2: Путать скалярное произведение с поэлементным умножением Неправильно:
# В NumPy * делает ПОЭЛЕМЕНТНОЕ умножение
v1 = np.array([1, 2])
v2 = np.array([3, 4])
result = v1 * v2 # [3, 8] — это НЕ скалярное произведение!
Правильно:
result = np.dot(v1, v2) # 11 — скалярное произведение
# или
result = v1 @ v2 # 11
Почему важно: Скалярное произведение даёт одно число, поэлементное — вектор.
❌ Ошибка 3: Забывать нормализовать перед вычислением cosine similarity Неправильно:
sim = np.dot(v1, v2) # Это НЕ cosine similarity!
Правильно:
sim = np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))
Почему важно: Без нормализации сравниваешь не только направление, но и величину векторов.
❌ Ошибка 4: Использовать L1-норму вместо L2 для расстояний Неправильно (если нужна Euclidean distance):
distance = np.sum(np.abs(v1 - v2)) # L1-норма (Manhattan)
Правильно:
distance = np.linalg.norm(v1 - v2) # L2-норма (Euclidean)
Почему важно: L1 и L2 дают разные результаты. Для большинства ML задач используют L2.
❌ Ошибка 5: Думать, что нормализованный вектор = нулевой вектор Неправильно: Нормализация не делает вектор нулевым! Она приводит длину к 1. Правильно:
v = [3, 4]
normalized = v / np.linalg.norm(v) # [0.6, 0.8]
# Длина = 1, но вектор НЕ нулевой!
Почему важно: Нормализация сохраняет направление, только меняет длину.
Главное запомнить
📝 Ключевые понятия
✅ Вектор — упорядоченный набор чисел, описывающий точку или направление в n-мерном пространстве. В ML это основной способ представления данных.
✅ Сложение векторов: $\vec{v} + \vec{w} = [v_1 + w_1, v_2 + w_2, \ldots]$ — покомпонентное сложение. Используется для усреднения embeddings, комбинирования признаков.
✅ Вычитание векторов: $\vec{v} - \vec{w} = [v_1 - w_1, v_2 - w_2, \ldots]$ — разность координат. Используется для вычисления расстояний, градиентов, изменений.
✅ Умножение на скаляр: $\alpha \vec{v} = [\alpha v_1, \alpha v_2, \ldots]$ — масштабирование вектора. Используется в градиентном спуске (learning rate), attention (веса), нормализации.
✅ Скалярное произведение: $\vec{v} \cdot \vec{w} = v_1 w_1 + v_2 w_2 + \cdots + v_n w_n$ — сумма произведений координат. Результат: одно число. Основа cosine similarity и нейронных сетей!
✅ L2-норма (длина): $|\vec{v}| = \sqrt{v_1^2 + v_2^2 + \cdots + v_n^2}$ — расстояние от начала координат до точки. Используется для нормализации, регуляризации, вычисления расстояний.
✅ Нормализация: $\hat{v} = \frac{\vec{v}}{|\vec{v}|}$ — приведение вектора к длине 1 с сохранением направления. Критично для правильного вычисления cosine similarity.
✅ Cosine Similarity: $\frac{\vec{v} \cdot \vec{w}}{|\vec{v}| |\vec{w}|}$ — мера схожести векторов по направлению (от -1 до 1). Основной метод сравнения embeddings в NLP.
✅ Euclidean Distance: $|\vec{v} - \vec{w}| = \sqrt{\sum (v_i - w_i)^2}$ — прямое расстояние между точками. Используется в векторных БД, KNN, кластеризации.
✅ Векторы в ML: Всё представляется векторами — тексты (embeddings), изображения (pixel vectors), аудио (spectrograms), пользователи (feature vectors), веса нейронок.
Связь с другими темами курса
Что нужно было знать до этого урока: - Базовая арифметика — сложение, умножение, квадратный корень (всё, что мы используем для координат) - Понятие координат — представление точек в 2D/3D пространстве (GPS координаты, графики)
Что изучить дальше: - Матричные операции — умножение матриц, транспонирование (следующий уровень после векторов!) - Собственные векторы и собственные значения — критично для PCA, анализа нейронных сетей - Градиентный спуск — оптимизация с использованием векторов градиентов - Transformers и Attention — где скалярные произведения играют ключевую роль
Где это нужно в ML/AI:
💻 В NLP: - Word embeddings (Word2Vec, GloVe) — слова как векторы - Sentence embeddings (SBERT) — предложения как векторы - Semantic search — поиск похожих текстов через cosine similarity - RAG системы — векторные БД хранят embeddings документов - Аналогии (king - man + woman = queen) — линейные операции над векторами смыслов!
🤖 В Deep Learning: - Нейронные сети — каждый слой: $y = Wx + b$ (матрично-векторное умножение) - Градиентный спуск — обновление весов: $w_{\text{new}} = w - \alpha \nabla L$ (вычитание векторов) - Backpropagation — цепочка векторных операций для вычисления градиентов - Attention механизм — скалярные произведения Q, K, V векторов - Batch Normalization — нормализация активаций (деление на норму)
📊 В Data Science: - Feature engineering — признаки объектов как векторы - Normalization — стандартизация данных (нормализация векторов) - Distance metrics — KNN, кластеризация (Euclidean, Cosine) - Dimensionality reduction (PCA, t-SNE) — проекции векторов в низкоразмерное пространство - Recommendation systems — векторы пользователей и товаров, cosine similarity
🖼️ В Computer Vision: - Image vectors — картинки представляются как векторы пикселей (например, 28×28 = 784 размерности для MNIST) - Convolutional filters — свёртки = скалярные произведения векторов - Feature maps — выходы слоёв CNN как векторы признаков - Image similarity — сравнение векторов признаков изображений
🔍 В векторных базах данных: - Pinecone, Weaviate, Qdrant — хранят embeddings как векторы - Similarity search — ищут ближайшие векторы (по Euclidean или Cosine distance) - Indexing (HNSW, IVF) — оптимизируют векторный поиск - Hybrid search — комбинируют keyword search и vector search
🎓 В теории: - Линейная алгебра — векторные пространства, базисы, линейные преобразования - Метрические пространства — понятие расстояния между объектами - Оптимизация — градиенты как векторы в пространстве параметров
Интересные факты
💡 Почему Cosine Similarity, а не Euclidean Distance?
В NLP чаще используют cosine similarity, а не Euclidean distance. Почему?
Потому что в embeddings направление важнее величины!
Пример:
v1 = [0.8, 0.6] # "кот"
v2 = [8.0, 6.0] # тот же "кот", но с другим масштабом
Euclidean distance: большое (эти векторы “далеко”) Cosine similarity: 1.0 (идеально похожи по направлению!)
В ML векторы часто масштабируются по-разному (разные модели, разная нормализация), поэтому направление (смысл) сохраняется, а величина может меняться.
💡 Word2Vec аналогии — не магия, а геометрия!
Классическая демонстрация: $\text{king} - \text{man} + \text{woman} \approx \text{queen}$
Как это работает? - Вектор “man” содержит информацию о мужском роде - Вычитая его, мы “удаляем” эту информацию из “king” - Остаётся “королевскость” без гендера - Добавляя “woman”, получаем “королевскость” + “женский род” = “queen”!
Это работает потому, что Word2Vec линейно кодирует смысловые отношения! Вектора образуют семантическую геометрию.
💡 L2 норма в физике: длина вектора скорости
В физике вектор скорости: $\vec{v} = [v_x, v_y, v_z]$
Модуль скорости (то, что показывает спидометр): $|\vec{v}| = \sqrt{v_x^2 + v_y^2 + v_z^2}$
Это L2-норма! Так что всё, что ты изучил про векторы, применяется и в физике, и в ML одинаково.
💡 Attention в Transformers = миллиарды скалярных произведений
GPT-4 имеет ~1.76 триллиона параметров. При генерации одного токена выполняется огромное количество скалярных произведений (Q·K в каждом attention слое).
Вся мощь современных языковых моделей построена на операции, которую ты только что изучил: dot product! 🚀
💡 Векторные БД растут экспоненциально
С 2022 года векторные базы данных (Pinecone, Weaviate, Qdrant) стали одной из самых быстрорастущих категорий инфраструктуры ML.
Почему? Потому что LLM генерируют embeddings, а их нужно где-то хранить и быстро искать! Вся эта индустрия построена на векторных операциях, которые ты сегодня изучил.
Лайфхаки и полезные трюки
1. Быстрая проверка перпендикулярности Не нужно вычислять угол! Просто посчитай скалярное произведение:
if np.dot(v1, v2) == 0:
print("Векторы перпендикулярны!")
Пример: В ML это используют для проверки ортогональности базисов (PCA).
2. Нормализация через broadcasting в NumPy Вместо цикла:
# Медленно
for i in range(len(vectors)):
vectors[i] = vectors[i] / np.linalg.norm(vectors[i])
Используй broadcasting:
# Быстро!
norms = np.linalg.norm(vectors, axis=1, keepdims=True)
normalized = vectors / norms
Где применяется: Нормализация батча embeddings перед поиском.
3. Cosine Similarity через sklearn (лениво и быстро) Не пиши формулу руками:
from sklearn.metrics.pairwise import cosine_similarity
sim = cosine_similarity([v1], [v2])[0][0]
Бонус: Работает для батчей векторов!
# Сразу все парные similarity
sims = cosine_similarity(vectors1, vectors2)
4. Euclidean Distance в SciPy Для расстояний между всеми парами векторов:
from scipy.spatial.distance import cdist
distances = cdist(vectors1, vectors2, metric='euclidean')
Где применяется: KNN, поиск ближайших соседей в RAG.
5. Мнемоника: DOT = Directional Overlap Test Скалярное произведение показывает “насколько векторы смотрят в одну сторону”: - Большое положительное → одинаковое направление - Ноль → перпендикулярны - Большое отрицательное → противоположные направления
Запомнить: DOT product = Directional Overlap Test
6. Unit vector trick для быстрой нормализации Если вектор уже близок к единичному, проверь норму:
norm = np.linalg.norm(v)
if abs(norm - 1.0) < 1e-6:
return v # уже нормализован
else:
return v / norm
Где применяется: OpenAI Embeddings уже нормализованы, не нужно лишний раз делить!
7. Attention score формула (упрощённая) Для Self-Attention достаточно помнить:
scores = Q @ K.T # скалярные произведения
attention = softmax(scores / sqrt(d_k)) # нормализация
output = attention @ V # взвешенная сумма
d_k — размерность ключей (для стабильности градиентов).
8. L2 регуляризация в PyTorch (автоматически) Не пиши норму вручную:
optimizer = torch.optim.Adam(model.parameters(), lr=0.001, weight_decay=0.01)
weight_decay = автоматическая L2 регуляризация!
9. Проверка размерностей перед операциями Перед скалярным произведением:
assert v1.shape == v2.shape, f"Размерности не совпадают: {v1.shape} vs {v2.shape}"
result = np.dot(v1, v2)
Где применяется: Отладка ML пайплайнов, особенно при работе с embeddings разных моделей.
10. Batch processing векторов Работай с батчами, а не с отдельными векторами:
# Медленно
for v in vectors:
result.append(model.encode(v))
# Быстро
results = model.encode(vectors) # батч сразу
Ускорение: 10-100x при работе с GPU!
💡 Совет: Векторные операции — это фундамент ML. Не торопись переходить к сложным темам (нейронные сети, transformers), пока не прочувствуешь векторы интуитивно. Попрактикуйся на задачах, поиграй с NumPy, посмотри, как embeddings работают в реальных проектах (RAG, semantic search). Когда векторы станут естественными, всё остальное будет намного проще!
Следующий шаг: Попробуй построить простую RAG систему! Сгенерируй embeddings для нескольких документов, загрузи в векторную БД (например, FAISS или Qdrant), сделай поиск по запросу. Ты увидишь все изученные операции в действии — и это будет круто! 🚀
Понял тему? Закрепи в боте! 🚀
Попрактикуйся на задачах и получи персональные рекомендации от AI
💪 Начать тренировку