Основы

Линейная алгебра — набор выживания для машинного обучения

Краткое справочное руководство по наиболее распространенным понятиям с примерами в NumPy.

Линейную алгебру часто называют «математикой данных» и одним из фундаментальных столпов машинного обучения. Тем не менее, это обширное поле для охвата, и оно таит в себе опасность слишком быстрого падения в кроличью нору.

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

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

Математические объекты

Скаляры

Скаляр — это всего лишь одно число. Он называется так потому, что растягивает или масштабирует векторы или матрицы без изменения направления.

Мы можем представить скаляр с помощью простой переменной в python.

Векторы

Геометрически мы можем думать о векторе как о линии, определяемой величиной (длиной) и направлением. Однако определение вектора не включает его начальное или конечное положение.

Вектор v=[1, 2], например, только говорит нам, что он проходит одну единицу в первом и две единицы во втором измерении. По соглашению мы чаще всего думаем о векторе в стандартной позиции — это означает, что его хвост находится в начале координат [0, 0].

Мы также можем думать о векторе как о массиве чисел. Думая таким образом, мы можем представить вектор в NumPy следующим образом:

Матрицы

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

Предположим, что наш пример матрицы (A) содержит действительные числа, и мы хотим описать ее форму. Мы можем сделать это следующим образом:

Где m определяет высоту (строк) матрицы, а n сообщает нам ширину (столбцов) матрицы. В нашем примере и m, и n равны трем, следовательно, у нас есть матрица 3 на 3.

Мы можем определить матрицу несколькими способами, используя NumPy, некоторые полезные методы можно увидеть в коде ниже. Мы также можем распечатать размеры матрицы, используя numpy.shape(a)

Примечание. Матрицы больших размерностей с переменным количеством осей называются тензорами.

Матрицы можно использовать по-разному, вот некоторые из них:

  1. Представление линейного преобразования
  2. Представление системы уравнений
  3. Хранение и представление данных (наблюдения x функции)
  4. Хранение ядер, используемых, например, в свертке

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

Концепцию операции транспонирования можно представить следующим образом: заменить строки столбцами и наоборот.

Когда мы транспонируем вектор-столбец, мы получаем вектор-строку. Если мы транспонируем матрицу, мы получим зеркальное отображение по главной диагонали.

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

Операцию транспонирования легко применить в коде.

Добавление матрицы

Добавление матриц довольно просто, нам просто нужно добавить или вычесть каждый соответствующий элемент в двух матрицах. Мы также можем назвать это поэлементной операцией. Однако мы должны помнить одну вещь: две матрицы должны иметь одинаковую форму.

Примечание. Мы также можем добавить два вектора — концепция остается той же, что и для сложения матриц.

Выполнение сложения матриц в NumPy можно выполнить с помощью основного арифметического оператора или функции numpy.add(a,b).

Мы также можем добавить или вычесть один скаляр к матрице. Скаляр будет просто добавлен поэлементно.

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

Примечание. Длина вектора должна совпадать с количеством столбцов в матрице. В противном случае трансляция невозможна.

Умножение матриц и векторов

Теперь мы подошли к одной из самых, если не самой важной операции: умножению двух матриц.

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

Умножение матриц является дистрибутивным (1), ассоциативным (2) и некоммутативным (3):

Чтобы умножение матриц было допустимой операцией, «внутренние измерения» (n) должны совпадать. Результирующая матрица будет определяться «внешними измерениями» (m, p).

Давайте придумаем пример, чтобы лучше понять это.

Матрица (A) определяется формой (2 x 3), тогда как матрица (B) содержит 3 строки и 2 столбца, следовательно, форму (3 x 2). Поскольку «внутренние размеры» совпадают, умножение матриц определено — результатом будет матрица 2 на 2.

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

Мы можем в основном думать об умножении матриц как о скалярном произведении между вектором-строкой левой матрицы и вектор-столбцом правой матрицы. Мы можем визуализировать механизм следующим образом:

Давайте рассмотрим числовой пример, чтобы углубить наше понимание.

Примечание. Умножение матриц не выполняется поэлементно. Эта операция называется произведением Адамара и часто обозначается как A ⨀ B.

Умножение матриц можно выполнить несколькими способами с помощью встроенных функций NumPy, как мы можем видеть в примере кода ниже.

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

Возьмем, к примеру, следующее уравнение

которые можно переписать в виде нескольких уравнений, но менее плотных и элегантных.

Обратная и тождественная матрица

Обратная матрица позволяет нам решить уравнение Ax = b аналитически для x. Но прежде всего нам нужно знать, что такое единичная матрица.

Единичная матрица не изменяет вектор или матрицу путем умножения. Элементы на главной диагонали состоят только из единиц, тогда как внедиагональные элементы определяются только нулями. Более того, единичная матрица всегда квадратная (MxM).

Визуализируя единичную матрицу 2 на 2, мы получаем следующее:

С другой стороны, обратная матрица — это матрица, которая дает единичную матрицу при умножении на исходную матрицу.

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

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

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

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

В предыдущем разделе мы вычислили обратную матрицу, чтобы найти Ax=b для x.

Чтобы была определена обратная матрица, для каждого b должно быть ровно одно решение. Однако уравнение также может не иметь ни одного решения или иметь много решений.

Если мы представим столбцы матрицы (A) как разные направления в пространстве, мы сможем выяснить, сколько существует способов достижения b. Вектор (x) в нашем примере определяет, как далеко мы должны пройти в каждом из этих направлений.

Диапазон набора векторов — столбцы матрицы (A) — определяет все точки, которые можно получить линейной комбинацией Ax. Поэтому спрашивать, есть ли решение для Ax=b, в основном то же самое, что спрашивать, лежит ли b в диапазоне. Подпространство, натянутое на векторы, называется пространством столбцов.

Теперь представьте, что один из векторов является линейной комбинацией другого, образуя таким образом одну линию. Составное подпространство теперь уменьшено до 1-мерного, и Ax=b имеет решение только в том случае, если b лежит точно на этой линии. Если b не находится в этой строке, у нас нет возможности добраться до него.

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

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

Нормы

Грубо говоря, норма измеряет размер или длину вектора. Более формально норму можно интерпретировать как функцию, отображающую векторы в неотрицательные значения.

Одной из часто используемых норм является евклидова норма или норма ℓ2:

Другие примеры полезных норм включают норму ℓ1, норму ℓ∞ или норму Фробениуса.

В коде мы можем использовать функцию numpy.linalg.norm() и указать порядок нормы через параметр ord=None

Примечание. По умолчанию мы вычисляем норму Фробениуса для матрицы и норму ℓ2 для вектора.

Специальные матрицы и векторы

Некоторые матрицы имеют особые элементы или форму и поэтому особенно полезны.

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

Мы уже сталкивались с диагональной матрицей, когда узнали о единичной матрице.

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

Мы можем построить диагональную матрицу, указав вектор и просто применив функцию numpy.diag(v)

Симметричная матрица — это любая матрица, равная своей собственной транспонированной, это означает

Мы можем представить пример матрицы, которая выглядит следующим образом:

Предположим, у нас есть вектор v и вектор w. Теперь представьте, что оба вектора идут в разных направлениях — на самом деле они перпендикулярны с углом 90°. Эти векторы также можно назвать ортогональными — если оба вектора имеют единичную норму длины, равную единице, они называются ортонормированными.

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

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

собственное разложение

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

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



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

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



Разложение по сингулярным значениям

Разложение по сингулярным числам (SVD) и собственное разложение тесно связаны, поскольку в обоих случаях мы разлагаем или факторизуем матрицу.

Однако SVD более универсален. Например, собственное разложение не определено, если матрица не является квадратной, тогда как SVD все еще можно применять.

Разложение по сингулярным числам разлагает матрицу на сингулярные значения и сингулярные векторы. При применении мы разлагаем одну матрицу на произведение трех специальных матриц.

Матрицы (U) и (V) ортогональны и содержат левые сингулярные векторы и правые сингулярные векторы соответственно. Матрица (D) представляет собой диагональную матрицу, содержащую сингулярные значения на главной диагонали.

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

Мы можем положиться на использование numpy.linalg.svd(a) для применения SVD.

Псевдоинверсия Мура-Пенроуза

Обратная матрица не определена для неквадратных матриц. Псевдоинверсия Мура-Пенроуза, однако, позволяет нам вычислить или аппроксимировать инверсию для высоких и широких матриц.

Практические алгоритмы полагаются на SVD при вычислении псевдоинверсии.

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

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

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

Сумма всех диагональных элементов матрицы может быть вычислена оператором трассировки.

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

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

Определяющий

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

Его также можно интерпретировать геометрически как площадь или объем соответственно. Детерминант, грубо говоря, дает меру того, насколько умножение на матрицу расширяет или сужает пространство.



Определитель можно вычислить с помощью встроенной функции NumPy numpy.linalg.det(a)

Заключение

В этой статье мы постарались охватить много вопросов. Мы кратко изложили теорию, лежащую в основе некоторых наиболее распространенных концепций линейной алгебры, имеющих отношение к машинному обучению. Кроме того, мы реализовали большинство концепций на Python с помощью NumPy.

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

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

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

Спасибо за чтение! Обязательно оставайтесь на связи и следите за мной здесь на Medium, Kaggle или просто скажите Привет на LinkedIn.

Понравилась статья? Станьте Medium Member и продолжайте учиться без ограничений. Я получу часть вашего членского взноса, если вы перейдете по следующей ссылке, без каких-либо дополнительных затрат с вашей стороны.



Ссылки/Дополнительные материалы:

  • Глубокое обучение (Ян Дж. Гудфеллоу, Йошуа Бенджио и Аарон Курвиль), глава 2, MIT Press, 2016.
  • Майк X Коэн, доктор философии. Линейная алгебра: теория, интуиция, код.