Эта статья открывает список уроков на тему “Линейная алгебра с примерами на Python“. Мы постараемся рассказать о базовых понятиях линейной алгебры, которые могут быть полезны тем, кто занимается машинным обучением и анализом данных, и будем сопровождать все это примерами на языке Python.
Матрицы
Матрицей в математике называют объект, записываемый в виде прямоугольной таблицы, элементами которой являются числа (могут быть как действительные, так и комплексные). Пример матрицы приведен ниже.
\(M\;=\;\begin{pmatrix}1&3&5\\7&2&4\end{pmatrix}\)
В общем виде матрица записывается так:
\(M=\begin{pmatrix}a_{11}&a_{12}&…&a_{1n}\\a_{21}&a_{22}&…&a_{2n}\\…&…&…&…\\a_{m1}&a_{m2}&…&a_{mn}\end{pmatrix}\)
Представленная выше матрица состоит из i-строк и j-столбцов. Каждый ее элемент имеет соответствующее позиционное обозначение, определяемое номером строки и столбца на пересечении которых он расположен: \(a_{ij}\)- находится на i-ой строке и j-м столбце.
Важным элементом матрицы является главная диагональ, ее составляют элементы, у которых совпадают номера строк и столбцов.
Виды матриц и способы их создания в Python
Матрица в Python – это двумерный массив, поэтому задание матриц того или иного вида предполагает создание соответствующего массива. Для работы с массивами в Python используется тип данных список (англ. list). Но с точки зрения представления матриц и проведения вычислений с ними списки – не очень удобный инструмент, для этих целей хорошо подходит библиотека Numpy, ее мы и будем использовать в дальнейшей работе.
Напомним, для того, чтобы использовать библиотеку Numpy ее нужно предварительно установить, после этого можно импортировать в свой проект. По установке Numpy можно подробно прочитать в разделе “Установка библиотеки Numpy” из введения. Для того чтобы импортировать данный модуль, добавьте в самое начало программы следующую строку
import numpy as np
Если после импорта не было сообщений об ошибке, то значит все прошло удачно и можно начинать работу. Numpy содержит большое количество функций для работы с матрицами, которые мы будем активно использовать. Обязательно убедитесь в том, что библиотека установлена и импортируется в проект без ошибок.
Рассмотрим, различные варианты матриц и способы их задания в Python.
Вектор
Вектором называется матрица, у которой есть только один столбец или одна строка. Более подробно свойства векторов, их геометрическая интерпретация и операции над ними будут рассмотрены в “Главе 2 Векторная алгебра”.
Вектор-строка
Вектор-строка имеет следующую математическую запись.
\(v=(1\;2)\)
Такой вектор в Python можно задать следующим образом.
>>> v_hor_np = np.array([1, 2]) >>> print(v_hor_np ) [1 2]
Если необходимо создать нулевой или единичный вектор, то есть вектор, у которого все элементы нули либо единицы, то можно использовать специальные функции из библиотеки Numpy.
Создадим нулевую вектор-строку размера 5.
>>> v_hor_zeros_v1 = np.zeros((5,)) >>> print(v_hor_zeros_v1 ) [0. 0. 0. 0. 0.]
В случае, если требуется построить вектор-строку так, чтобы она сама являлась элементом какого-то массива, это нужно для возможности транспонирования матрицы (см. раздел “1.3 Транспонирование матрицы”), то данную задачу можно решить так.
>>> v_hor_zeros_v2 = np.zeros((1, 5)) >>> print(v_hor_zeros_v2 ) [[0. 0. 0. 0. 0.]]
Построим единичную вектор-строку в обоих из представленных для нулевого вектора-строки форм.
>>> v_hor_one_v1 = np.ones((5,)) >>> print(v_hor_one_v1) [1. 1. 1. 1. 1.]
>>> v_hor_one_v2 = np.ones((1, 5)) >>> print(v_hor_one_v2) [[1. 1. 1. 1. 1.]]
Вектор-столбец
Вектор-столбец имеет следующую математическую запись.
\(v=\begin{pmatrix}1\\2\end{pmatrix}\)
В общем виде вектор столбец можно задать следующим образом.
>>> v_vert_np = np.array([[1], [2]]) >>> print(v_vert_np) [[1] [2]]
Рассмотрим способы создания нулевых и единичных векторов-столбцов. Построим нулевой вектор-столбец.
>>> v_vert_zeros = np.zeros((5, 1)) >>> print(v_vert_zeros) [[0.] [0.] [0.] [0.] [0.]]
Единичный вектор-столбец можно создать с помощью функции ones().
>>> v_vert_ones = np.ones((5, 1)) >>> print(v_vert_ones) [[1.] [1.] [1.] [1.] [1.]]
Квадратная матрица
Довольно часто, на практике, приходится работать с квадратными матрицами. Квадратной называется матрица, у которой количество столбцов и строк совпадает. В общем виде они выглядят так.
\(Msqr=\begin{pmatrix}a_{11}&a_{12}&…&a_{1n}\\a_{21}&a_{22}&…&a_{2n}\\…&…&…&…\\a_{n1}&a_{n2}&…&a_{nn}\end{pmatrix}\)
Создадим следующую матрицу.
\(Msqr=\begin{pmatrix}1&2&3\\4&5&6\\7&8&9\end{pmatrix}\)
В Numpy можно создать квадратную матрицу с помощью метода array().
>>> m_sqr_arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> print(m_sqr_arr) [[1 2 3] [4 5 6] [7 8 9]]
Как вы уже наверное заметили, аргументом функции np.array() является список Python, его можно создать отдельно и передать в функцию.
>>> m_sqr = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] >>> m_sqr_arr = np.array(m_sqr) >>> print(m_sqr_arr) [[1 2 3] [4 5 6] [7 8 9]]
Но в Numpy есть еще одни способ создания матриц – это построение объекта типа matrix с помощью одноименного метода. Задать матрицу можно в виде списка.
>>> m_sqr_mx = np.matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) >>> print(m_sqr_mx) [[1 2 3] [4 5 6] [7 8 9]]
Также доступен стиль Matlab, когда между элементами ставятся пробелы, а строки разделяются точкой с запятой, при этом такое описание должно быть передано в виде строки.
>>> m_sqr_mx = np.matrix('1 2 3; 4 5 6; 7 8 9') >>> print(m_sqr_mx) [[1 2 3] [4 5 6] [7 8 9]]
Диагональная матрица
Особым видом квадратной матрицы является диагональная – это такая матрица, у которой все элементы, кроме тех, что расположены на главной диагонали, равны нулю.
\(Mdiag=\begin{pmatrix}a_{11}&0&…&0\\0&a_{22}&…&0\\…&…&…&…\\0&0&…&a_{nn}\end{pmatrix}\)
Диагональную матрицу можно построить вручную, задав только значения элементам на главной диагонали.
>>> m_diag = [[1, 0, 0], [0, 5, 0], [0, 0, 9]] >>> m_diag_np = np.matrix(m_diag) >>> print(m_diag_np) [[1 0 0] [0 5 0] [0 0 9]]
Библиотека Numpy предоставляет инструменты, которые могут упростить построение такой матрицы.
Первый вариант подойдет в том случае, если у вас уже есть матрица, и вы хотите сделать из нее диагональную. Создадим матрицу размера 3 3.
>>> m_sqr_mx = np.matrix('1 2 3; 4 5 6; 7 8 9')
Извлечем ее главную диагональ.
>>> diag = np.diag(m_sqr_mx) >>> print(diag) [1 5 9]
Построим диагональную матрицу на базе полученной диагонали.
>>> m_diag_np = np.diag(np.diag(m_sqr_mx)) >>> print(m_diag_np) [[1 0 0] [0 5 0] [0 0 9]]
Второй вариант подразумевает построение единичной матрицы, ей будет посвящен следующий параграф.
Единичная матрица
Единичной матрицей называют такую квадратную матрицу, у которой элементы главной диагонали равны единицы, а все остальные нулю.
\(E=\begin{pmatrix}1&0&…&0\\0&1&…&0\\…&…&…&…\\0&0&…&1\end{pmatrix}\)
Создадим единичную матрицу на базе списка, который передадим в качестве аргумента функции matrix().
>>> m_e = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] >>> m_e_np = np.matrix(m_e) >>> print(m_e_np) [[1 0 0] [0 1 0] [0 0 1]]
Такой способ не очень удобен, к счастью для нас, для построения такого типа матриц в библиотеке Numpy есть специальная функция – eye().
>>> m_eye = np.eye(3) >>> print(m_eye) [[ 1. 0. 0.] [ 0. 1. 0.] [ 0. 0. 1.]]
В качестве аргумента функции передается размерность матрицы, в нашем примере – это матрица 3 3. Тот же результат можно получить с помощью функции identity().
>>> m_idnt = np.identity(3) >>> print(m_idnt) [[ 1. 0. 0.] [ 0. 1. 0.] [ 0. 0. 1.]]
Нулевая матрица
У нулевой матрицы все элементы равны нулю.
\(Z=\begin{pmatrix}0&0&…&0\\0&0&…&0\\…&…&…&…\\0&0&…&0\end{pmatrix}\)
Пример того, как создать такую матрицу с использованием списков, мы приводить не будем, он делается по аналогии с предыдущим разделом. Что касается Numpy, то в составе этой библиотеки есть функция zeros(), которая создает нужную нам матрицу.
>>> m_zeros = np.zeros((3, 3)) >>> print(m_zeros) [[ 0. 0. 0.] [ 0. 0. 0.] [ 0. 0. 0.]]
В качестве параметра функции zeros() передается размерность требуемой матрицы в виде кортежа из двух элементов, первый из которых – число строк, второй – столбцов. Если функции zeros() передать в качестве аргумента число, то будет построен нулевой вектор-строка, это мы делали в параграфе, посвященном векторам.
Задание матрицы в общем виде
Если у вас уже есть данные о содержимом матрицы, то создать ее можно используя списки Python или функцию matrix() из библиотеки Numpy.
>>> m_mx = np.matrix('1 2 3; 4 5 6') >>> print(m_mx) [[1 2 3] [4 5 6]]
Если же вы хотите создать матрицу заданного размера с произвольным содержимым, чтобы потом ее заполнить, проще всего для того использовать функцию zeros(), которая создаст матрицу заданного размера, заполненную нулями.
>>> m_var = np.zeros((2, 5)) >>> print(m_var) [[ 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0.]]
P.S.
Вводные уроки по “Линейной алгебре на Python” вы можете найти соответствующей странице нашего сайта. Все уроки по этой теме собраны в книге “Линейная алгебра на Python”.
Если вам интересна тема анализа данных, то мы рекомендуем ознакомиться с библиотекой Pandas. Для начала вы можете познакомиться с вводными уроками. Все уроки по библиотеке Pandas собраны в книге “Pandas. Работа с данными”.