Векторы: операции, длина и применение в ML и графике

Векторы: операции, длина и применение в ML и графике Полезное

Вектор — это математический объект, у которого есть длина и направление. У него два равноправных представления, и их важно не путать. Геометрически вектор — это направленный отрезок (стрелка) из точки A в точку B. Алгебраически тот же вектор — это упорядоченный набор чисел (координат), например [3, 4]. Одна и та же стрелка из начала координат в точку (3, 4) записывается как набор [3, 4], и ее длина равна 5.

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

Два представления одного вектора

Чтобы дальше не путаться, зафиксирую мини-цепочку «объект -> координаты -> число»:

  • Геометрический вектор — направленный отрезок. Есть начало, конец, длина и направление. Стрелку можно двигать: если длина и направление те же, это тот же (равный) вектор.
  • Координаты вектора — упорядоченный набор чисел. Стрелку из начала координат [0, 0] в точку (3, 4) описывают два числа: сдвиг по оси X и по оси Y. Порядок важен: [3, 4] и [4, 3] — разные векторы.
  • Скаляр — это просто число (без направления): длина вектора или множитель. Путать со скаляром нельзя: 2 — скаляр, [2, 0] — вектор.

Число координат задает размерность: два числа — двумерный вектор на плоскости XY, три — трехмерный в пространстве XYZ, больше трех — многомерный. Многомерные векторы графически не нарисовать, но алгебраически с ними работают так же — именно они чаще всего встречаются в машинном обучении.

Длина (норма) вектора

Длина вектора (модуль, или норма) — это неотрицательное число, показывающее «величину» стрелки. Обозначается как |a| или ||a||. Для вектора с координатами [x, y] длина считается по теореме Пифагора:

|a| = sqrt(x^2 + y^2)

Для трехмерного вектора [x, y, z] под корнем стоит сумма квадратов всех координат. Это евклидова норма (L2); есть и другие нормы (например L1 — сумма модулей координат), но по умолчанию под «длиной» понимают именно L2.

Минимальный рабочий пример на numpy:

import numpy as np

a = np.array([3, 4])
print(np.linalg.norm(a))  # 5.0

В консоли появится 5.0: sqrt(3^2 + 4^2) = sqrt(25) = 5. Длина всегда неотрицательна и равна нулю только у нулевого вектора [0, 0].

Сложение и умножение на скаляр

Обе базовые операции выполняются покоординатно.

Сложение. Координаты складывают попарно: [1, 2] + [3, 4] = [4, 6]. Геометрически это «правило треугольника»: приставляем начало второй стрелки к концу первой, а сумма — стрелка от начала первой к концу второй. Складывать можно только векторы одинаковой размерности.

Умножение на скаляр. Каждую координату умножаем на число k: 2 * [1, 2] = [2, 4]. Что происходит с вектором:

Значение k Что происходит с вектором
k > 1 длина растет в k раз, направление то же
0 < k < 1 длина уменьшается, направление то же
k = 1 вектор не меняется
k < 0 направление разворачивается на противоположное
k = 0 получается нулевой вектор [0, 0]

Пример на numpy сразу с несколькими операциями:

import numpy as np

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

print(a + b)   # [5 7 9]
print(2 * a)   # [2 4 6]
print(a - b)   # [-3 -3 -3]

Вывод: [5 7 9] для суммы, [2 4 6] для умножения на 2, [-3 -3 -3] для разности. Вычитание — не отдельная операция, а сложение с противоположным вектором: a - b = a + (-1) * b.

Скалярное произведение

Скалярное произведение (dot product) двух векторов дает число (скаляр), а не вектор — отсюда и название. Считается как сумма произведений соответствующих координат:

a . b = x1x2 + y1y2 + z1*z2

Есть вторая, геометрическая формула, связывающая скалярное произведение с углом:

a . b = |a| * |b| * cos(theta)

где theta — угол между векторами (формула верна для ненулевых векторов). Отсюда важное свойство: если скалярное произведение равно нулю, то cos(theta) = 0, то есть векторы перпендикулярны (угол 90 градусов).

import numpy as np

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print(np.dot(a, b))  # 32

Результат 32: 14 + 25 + 3*6 = 4 + 10 + 18 = 32. Скалярное произведение работает для векторов любой размерности — в этом его отличие от векторного произведения ниже.

Угол между векторами через косинус

Из геометрической формулы скалярного произведения легко выразить косинус угла:

cos(theta) = (a . b) / (|a| * |b|)

Формула определена только для двух ненулевых векторов (иначе в знаменателе ноль). Значение косинуса лежит в диапазоне от -1 до 1: 1 — векторы сонаправлены (угол 0), 0 — перпендикулярны (90 градусов), -1 — противоположно направлены (180 градусов).

import numpy as np

a = np.array([1, 0])
b = np.array([1, 1])

cos = np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
print(cos)                          # 0.7071067811865475
print(np.degrees(np.arccos(cos)))   # 45.00000000000001

Косинус вышел 0.7071... (это 1/sqrt(2)), а угол — примерно 45 градусов. Хвост ...0001 в выводе угла — обычная погрешность чисел с плавающей точкой, а не ошибка: точное значение здесь 45 градусов. Именно эта формула лежит в основе косинусной близости в машинном обучении — о ней ниже.

Нормализация вектора

Нормализация — это приведение вектора к единичной длине с сохранением направления. Единичный вектор получают делением исходного на его длину:

u = a / |a|

Операция определена только для ненулевого вектора: у нулевого длина равна нулю, и деление невозможно. Единичные векторы удобны там, где важно только направление, а не масштаб (например направление освещения в графике).

import numpy as np

v = np.array([3.0, 4.0])
unit = v / np.linalg.norm(v)
print(unit)                   # [0.6 0.8]
print(np.linalg.norm(unit))   # 1.0

Из [3, 4] получился [0.6, 0.8], и его длина равна 1.0 (с точностью до погрешности float). Направление осталось прежним, изменился только масштаб. Важно использовать обычное деление / (оно возвращает float): целочисленное деление // в ручном коде обнулило бы дробную часть.

Векторное произведение (только в 3D)

Векторное произведение (cross product) двух векторов дает не число, а новый вектор, перпендикулярный обоим исходным. Важная граница: операция определена именно для трехмерных векторов (строго говоря, еще и в семимерном пространстве, но на практике это 3D). Для двумерных или многомерных векторов «векторного произведения» в обычном смысле нет.

Длина результата связана с синусом угла: |a x b| = |a| * |b| * sin(theta). Если векторы параллельны (угол 0 или 180 градусов), их векторное произведение — нулевой вектор.

import numpy as np

a = np.array([1, 0, 0])
b = np.array([0, 1, 0])
print(np.cross(a, b))  # [0 0 1]

Векторное произведение орта оси X на орт оси Y дало [0, 0, 1] — орт оси Z, то есть вектор, перпендикулярный плоскости XY. Это ключевая операция в 3D-графике и физике: так вычисляют нормаль к поверхности и момент силы.

Не путайте две операции умножения: скалярное произведение (np.dot) дает число и работает в любой размерности; векторное произведение (np.cross) дает вектор и определено только в 3D.

Операция Вход Результат Размерность
Скалярное (dot) два вектора число (скаляр) любая
Векторное (cross) два вектора вектор, перпендикулярный обоим только 3D

Где векторы применяются

Машинное обучение. Здесь вектор — это упорядоченный набор чисел, описывающий объект. Признаки объекта (рост, вес, возраст) складывают в вектор признаков. Текст, картинку или пользователя переводят в эмбеддинг — плотный числовой вектор большой размерности (сотни и тысячи координат). Близость объектов измеряют косинусной близостью — косинусом угла между их векторами: чем ближе к 1, тем более похожи объекты. На этом работают поиск похожих товаров и рекомендации.

import numpy as np

def cosine_sim(a, b):
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

u1 = np.array([1, 0, 1])   # эмбеддинг объекта 1
u2 = np.array([1, 1, 1])   # эмбеддинг объекта 2
print(round(cosine_sim(u1, u2), 3))  # 0.816

Косинусная близость вышла примерно 0.816 — объекты похожи по направлению. Функция не знает смысла координат, она сравнивает только геометрию векторов. Для реальных эмбеддингов размерность будет не 3, а сотни, но формула та же.

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

Физика и инженерия. Скорость, сила, ускорение — величины с направлением, их естественно представлять векторами: сложение векторов дает суммарную силу или скорость, скалярное произведение силы на перемещение — работу, а векторное произведение — момент силы.

Выводы

  • Вектор имеет два представления: геометрическое (направленный отрезок) и алгебраическое (упорядоченный набор чисел); в машинном обучении почти всегда работают со вторым.
  • Базовые операции — сложение и умножение на скаляр — выполняются покоординатно; длина (норма) считается как корень из суммы квадратов координат.
  • Скалярное произведение дает число и работает в любой размерности; векторное произведение дает перпендикулярный вектор и определено только в 3D — это разные операции.
  • Угол между векторами и косинусная близость считаются через скалярное произведение и нормы; формула определена только для ненулевых векторов.
  • Векторы — основа признаков и эмбеддингов в ML, геометрии в компьютерной графике и описания сил и скоростей в физике.

Где применяется / связь с практикой

Освойте тему на практике

Векторы, нормы и скалярное произведение — это фундамент машинного обучения: признаки, эмбеддинги, метрики близости, а дальше матрицы и градиенты. Без уверенного владения этими операциями сложно понять, как модель хранит данные и считает расстояния между объектами. Чтобы системно дойти от базовой математики до рабочих ML-моделей, посмотрите курс ML-старт: базовый курс по машинному обучению, где линейная алгебра разбирается на практических задачах.

Освойте тему на практике

Оценить формат и уровень подачи помогут бесплатные открытые уроки Otus — на них можно вживую задать вопрос преподавателю.

FAQ

Чем вектор отличается от массива в программировании?
Массив — это структура данных (контейнер) для хранения элементов, а вектор — математический объект с определенными операциями (сложение, норма, произведения). Координаты вектора удобно хранить в массиве, поэтому в коде вектор часто и есть массив (np.array), но не всякий массив трактуют как вектор.

Может ли длина вектора быть отрицательной?
Нет. Длина (норма) — это корень из суммы квадратов координат, она всегда неотрицательна и равна нулю только у нулевого вектора. Отрицательными бывают отдельные координаты, но не длина.

Почему для сравнения объектов в ML берут косинус, а не разность координат?
Косинусная близость измеряет совпадение направлений и не зависит от длины векторов, поэтому объекты с разным «масштабом», но похожей структурой признаков считаются близкими. Евклидово расстояние (норма разности) чувствительно к длине, что не всегда желательно для эмбеддингов.

OTUS Журнал