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

Мы повторим основные понятия, связанные с векторами, но с акцентом на их применение для решения реальных задач в области обработки данных и обучения моделей. Также покажем, как работать с векторами в Python, используя такие библиотеки, как numpy и pandas.

А начнём мы с определения вектора.

Определение

Вектор — это математический объект, который в зависимости от области применения может иметь различные интерпретации и свойства.

Так векторы можно встретить:

  • в геометрии,
  • компьютерных науках,
  • линейной алгебре.

В геометрии

Геометрически вектор — это направленный отрезок, задаваемый начальной точкой и конечной точкой. Для вектора, заданного точками и , координаты вычисляются следующим образом:

Например, вектор, соединяющий точки и , имеет координаты .

Вектор

Вектор

В компьютерных науках

В программировании и компьютерной графике векторы используются для представления данных в виде упорядоченного списка чисел для последующих вычислений над ними.

Так, в машинном обучении наблюдение может быть представлено в виде вектора, состоящего из чисел, где каждое число соответствует значению соответствующего признака.

Аналогично в NLP (Natural Language Processing, обработка естественного языка) слова или части слов кодируются векторами, чтобы компьютер мог понять их семантику, а затем применить к ним математические операции.

Пример кодирования слов векторами

Пример кодирования слов векторами

В линейной алгебре

Алгебраическое определение вектора в некотором роде объединяет два определения выше, но описывает его более абстрактно. Чтобы с ним разобраться, необходимо изучить понятие векторного пространства.

Векторным пространством называется множество с операциями сложения и умножения на скаляр, удовлетворяющими определённым свойствам. И элементы этого множества называются векторами.

Говоря по-простому, векторное пространство состоит из двух частей:

  • множество элементов,
  • операции над этими элементами, удовлетворяющие заданным свойствам.

Примеры:

  • векторы-столбцы длины ;
  • многочлены степени не выше ;
  • непрерывные функции, определённые на отрезке ;
  • и так далее.

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

Аналогично, чтобы задать точку на плоскости, нужна уже пара чисел , а множество всех таких пар есть плоскость. В трёхмерном пространстве всё описывается тремя числами , и мы получаем .

Продолжая увеличивать количество измерений, мы приходим к пространству — это обобщение на случай -измерений, и, чтобы задать точку, нам нужно указать координат. Таким образом, в -мерном пространстве вектор представляет собой упорядоченный набор чисел:

где каждое — это -я координата вектора.

Например: в двумерном пространстве вектор имеет координаты по оси и по оси :

Представим эту запись на графике:

Вектор $v$

Вектор

Примечание: Вектор можно записывать как вектор-столбец или как вектор-строку. Разницы между этими объектами нет, это, скорее, вопрос удобного формализма. Для согласованности мы по умолчанию будем считать, что все векторы — это именно векторы-столбцы. Перейти от вектора-столбца к вектору-строке можно с помощью операции транспонирования, которую мы разберём чуть позже.

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

Представление векторов в Python

В NumPy вектора представлены в виде массивов, позволяющих эффективно выполнять математические операции.

1import numpy as np
2
3# Для создания вектора с заданными значениями
4# используется функция `np.array()`
5v = np.array([2, 5])  # array([2, 5])
6
7# Также можно создавать специальные векторы.
8# Например, вектор нулей заданного размера,
9# используя функцию `np.zeros()`
10zeros = np.zeros(3)  # array([0., 0., 0.])
11
12# Или вектор с равномерным шагом (аналог функции range),
13# используя функцию `np.arange()`
14a = np.arange(0, 10, 2)  # array([0, 2, 4, 6, 8])

Есть много и других полезных функций и методов в этой библиотеке — о них мы поговорим позже.

Теперь, для полного представления о векторном пространстве, давайте разберём операции, которые мы можем выполнять над векторами, и свойства, которым должны удовлетворять эти операции.

Операции с векторами

Сложение

Для векторов и сумма определяется как:

Свойства:

  • Коммутативность: .
  • Ассоциативность: .
  • Существование нулевого вектора: .
  • Существование противоположного вектора: .

Где:

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

Для вектора умножение на число (скаляр) определяется как:

Свойства умножения на скаляр:

  • .
  • .
  • .
  • .

Где

Свойства, приведённые выше для операций сложения и умножения, — ключевые в определении векторного пространства. Мы рассмотрели, как реализованы данные операции на векторах, которые отождествляются с , так как в каком-то смысле это самые полезные и наглядные объекты, удовлетворяющие определению вектора.

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

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

Транспонирование

Для вектора операция транспонирования меняет форму записи: вектор представленный в виде столбца, преобразуется в вектор, представленный в виде строки, и наоборот.

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

Для векторов и , заданных в координатах, скалярное произведение — это операция, которая отображает пару векторов в скаляр и определяется как:

Свойства скалярного произведения:

  • и

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

Покажем, как выглядит скалярное произведение, на примере.

Предположим, что у нас есть два объекта с более сложными признаками:

  • Вектор признаков для объекта №1:

  • Вектор признаков для объекта №2:

Скалярное произведение этих двух векторов рассчитывается как:

Что это нам говорит? Поскольку скалярное произведение дало отрицательное значение, значит, векторы направлены в противоположные стороны в многомерном пространстве. В контексте, например, метода опорных векторов это может означать, что объекты, представленные этими векторами, принадлежат к разным классам.

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

Также со скалярным произведением тесно связаны следующие полезные определения:

  • Длина (норма) вектора может быть выражена как:

  • Косинусная мера для векторов и — это нормированное скалярное произведение, которое показывает, насколько близки направления двух векторов независимо от их длин. Вычисляется как:

    • , если векторы направлены в одну сторону;
    • , если векторы ортогональны (перпендикулярны);
    • , если векторы направлены в противоположные стороны;

Где
.

Косинусная мера очень часто применяется в NLP-моделях для оценки близости слов. Сейчас покажем на примере.

Ранее мы упомянули, что в NLP-моделях слова (для простоты будем считать, что токен — это одно слово) кодируются векторами, которые отражают их семантические связи между собой.

Такие векторы часто называют эмбеддингами (англ. word embeddings). Пусть у нас есть два векторных представления слов:

  • Эмбеддинг слова «гитара»: .
  • Эмбеддинг слова «пианино»: .

Мы можем вычислить косинусную меру между этими векторами с помощью следующей формулы:

Сначала находим скалярное произведение этих векторов:

Теперь вычислим нормы этих векторов:

Теперь вычислим косинусную меру:

Это значение довольно близко к 1, что означает, что слова «гитара» и «пианино» схожи в семантическом смысле. Это подтверждается тем, что они часто встречаются в похожих контекстах, что делает их векторные представления близкими.

Ещё пример: в рекомендательных системах мы можем использовать косинусную меру для сравнения пользователей или товаров. Например, если два пользователя имеют похожие предпочтения, векторные представления таких пользователей будут схожи, и это отразится в высоком значении косинусной меры. Это поможет системе рекомендовать товары или фильмы, которые понравятся похожим пользователям.

Векторные представления пользователей

Векторные представления пользователей

Давайте рассмотрим применение операций с векторами в библиотеке numpy, которые там представлены в виде векторизованных массивов. Это ускоряет вычисления и позволяет эффективно работать с многомерными данными.

Операции с векторами в Python

Размер векторов может быть различен в зависимости от используемой модели. Например:

  • BERT — 768.
  • DeepSeek-V3 — 7 168.
  • ChatGPT-3 — 12 288.
  • Llama 3 — 16 384.

Давайте разберём несколько наглядных примеров с эмбеддингами намного меньшего размера, равного 5. Данные примеры также будут отражать суть семантической близости. Для этого будем выполнять операции сложения и вычитания векторов и оценивать косинусное сходство результирующего вектора.

1import numpy as np
2
3def cosine_similarity(vec1: np.array, vec2: np.array) -> float:
4    """Вычисляет косинусную меру двух векторов."""
5    return np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2))
6
7def evaulate_result(embeddings: np.array, result_embedding: np.array) -> None:
8    """Вычисляет косинусное сходство результата с каждым словом в словаре."""
9    print("Косинусное сходство результата с каждым словом:")
10    for word, vec in embeddings.items():
11		    print(f"{word}: {cosine_similarity(result_embedding, vec):.3f}")
12
13# Пример 1: ebook ≈ book - pages + digital
14embeddings = {
15    "book":     np.array([0.5, 0.7, 0.6, 0.4, 0.3]),
16    "pages":    np.array([0.2, 0.3, 0.1, 0.0, 0.2]),
17    "digital":  np.array([0.1, 0.2, 0.4, 0.3, 0.4]),
18    "ebook":    np.array([0.3, 0.6, 1.0, 0.7, 0.5]),
19    "magazine": np.array([0.3, 0.5, 0.5, 0.2, 0.1])
20}
21
22result = embeddings["book"] - embeddings["pages"] + embeddings["digital"]
23evaulate_result(embeddings, result)
24
25# Output:
26# Косинусное сходство результата с каждым словом:
27# book: 0.951
28# pages: 0.737
29# digital: 0.953
30# ebook: 0.996
31# magazine: 0.921

В результате получаем, что .

Рассмотрим ещё один пример:

1# Пример 2: hybrid ≈ motor - gasoline + electricity
2
3embeddings = {
4    "motor":       np.array([0.6, 0.7, 0.4, 0.2, 0.3]),
5    "gasoline":    np.array([0.2, 0.3, 0.1, 0.0, 0.1]),
6    "electricity": np.array([0.4, 0.5, 0.3, 0.4, 0.3]),
7    "hybrid":      np.array([0.8, 0.9, 0.7, 0.6, 0.5]),
8    "battery":     np.array([0.1, 0.4, 0.2, 0.5, 0.2])
9}
10
11result = embeddings["motor"] - embeddings["gasoline"] + embeddings["electricity"]
12evaulate_result(embeddings, result)
13
14# Output:
15# Косинусное сходство результата с каждым словом:
16# motor: 0.975
17# gasoline: 0.896
18# electricity: 0.995
19# hybrid: 0.998
20# battery: 0.873
21

В результате получаем, что .

И, наконец, последний пример:

1# Пример 3:  profit ≈ investment - risk + opportunity
2
3embeddings = {
4    "investment":   np.array([0.7, 0.8, 0.6, 0.7, 0.5]),
5    "risk":         np.array([0.3, 0.4, 0.2, 0.2, 0.3]),
6    "opportunity":  np.array([0.5, 0.6, 0.4, 0.5, 0.6]),
7    "profit":       np.array([0.9, 0.9 , 0.8, 1. , 0.8]),
8    "loss":         np.array([-0.6, -0.7, -0.5, -0.6, -0.4])
9}
10
11result = embeddings["investment"] - embeddings["risk"] + embeddings["opportunity"]
12evaulate_result(embeddings, result)
13
14# Output:
15# Косинусное сходство результата с каждым словом:
16# investment: 0.997
17# risk: 0.969
18# opportunity: 0.989
19# profit: 0.999
20# loss: -0.995
21

В результате получаем, что .

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

Изучив векторы и базовые операции над ними, мы можем исследовать их взаимосвязи через понятие линейной зависимости. Оно поможет нам определить, насколько один набор векторов достаточен для описания всего пространства.

Линейная зависимость

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

Линейная комбинация называется тривиальной, если все , в противном случае она нетривиальная.

  • Векторы называются линейно зависимыми, если существует нетривиальная линейная комбинация этих векторов, равная нулевому вектору. То есть линейно зависимы, если существуют , такие, что хотя бы один из не равен нулю и .
  • Если никакая нетривиальная комбинация не может дать ноль, то векторы линейно независимы.

Примеры

  1. Рассмотрим , и пусть:

    Тогда векторы:

    • — линейно независимы;
    • — линейно независимы;
    • — линейно зависимы ();
    • — линейно зависимы ().
  2. Один вектор линейно зависим тогда и только тогда, когда он равен нулю.

  3. Два вектора линейно зависимы тогда и только тогда, когда они пропорциональны, то есть , где .

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

Ответ (не открывайте сразу, сначала подумайте сами!)

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

После того как мы подробно рассмотрели векторы, освоили базовые операции над ними и исследовали понятие линейной зависимости, следующим логическим шагом будет ввести понятие базиса.

Базис позволяет описывать любое векторное пространство с помощью минимального набора линейно независимых векторов, обеспечивая таким образом удобные способы представления данных и решений в выбранном пространстве.

Базис

Базис векторного пространства — это система линейно независимых векторов , которые порождают всё пространство . Это означает, что любой вектор можно представить в виде линейной комбинации базисных векторов:

где — координаты вектора в выбранном базисе.

Рисунок 4.2.5: Канонический базис

Канонический базис в

Свойства базиса:

  • Всякое векторное пространство обладает базисом.
  • Любой вектор в единственным образом представляется через базис.
  • Любые два базиса содержат одно и то же число векторов.

Примеры:

  • В : стандартный базис

  • В : стандартный базис

Смысл базиса заключается в том, что после его выбора можно отождествить с . То есть если , тогда ему соответствует единственный столбец:

Таким образом, про любое векторное пространство, когда это необходимо, можно думать как просто про .

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

Последнее, о чём поговорим в этом параграфе, — как раз о размерности.

Размерность

Размерность векторного пространства — это число векторов в базисе этого пространства. Обозначается как . Размерность показывает минимальное число векторов, достаточное для порождения пространства. Говоря по-простому, — это величина, показывающая, насколько векторное пространство большое, она характеризует «количество степеней свободы» в пространстве.

Примеры:

  • В : размерность равна .
  • В пространстве всех многочленов степени : размерность равна (по числу коэффициентов многочлена).

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


Итак, векторы — это не просто набор чисел, а мощное средство для описания и преобразования данных. Именно через векторы мы представляем наборы признаков, вычисляем расстояния и ищем оптимальные решения.

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



Отмечайте параграфы как прочитанные чтобы видеть свой прогресс обучения

Вступайте в сообщество хендбука

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