Матрица и векторные операции

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

Моими двумя главными источниками были Кодирование матрицы из Университета Брауна и книга Матрицы и линейная алгебра Довера. Класс был жестоко сложным, но очень полезным. В нем мы использовали Python для решения самых разных задач линейной алгебры. Все было написано с нуля, и мы вообще не использовали Numpy!

В знак уважения к тем дням становления темой One Liners на этой неделе являются операции с матрицами и векторами.

21 января 2023 г.

Вычислить норму Фробениуса матрицы √

from math import sqrt

a = [  
  [0, 1, 2, 3],
  [4, 5, 6, 7]
]

f_norm = sqrt(sum([sum([j**2 for j in i]) for i in a]))

Обсуждение

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

Ресурсы



20 января 2023 г.

Вычислить косинусное сходство двух векторов ← ↑ →

from math import sqrt
a = [1, 3, -5]
b = [4, -2, -1]
sim = sum([x*y for x,y in zip(a,b)]) / (sqrt(sum([i**2 for i in a])) * (sqrt(sum([i**2 for i in b]))))

Обсуждение

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

Следуя нашему матричному умножению One Liner за несколько дней, мы берем скалярное произведение двух векторов и делим его на произведение их величин. Этот расчет вернет значение в интервале [-1, 1]. Где -1 указывает на противоположные углы, 0 указывает на ортогональность и 1 указывает на то, что углы векторов равны.

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

from math import acos
theta = acos(sim)

Ресурсы



19 января 2023 г.

Вычислить прямую сумму двух матриц ⊕

a = [
  [1, 1, 1, 1],
  [2, 2, 2, 2]
]

b = [
  [3, 3, 3, 3, 3, 3],
  [4, 4, 4, 4, 4, 4]
]

ds = [row+[0]*len(b[0]) for row in a] + [[0]*len(a[0])+row for row in b]

Обсуждение

Прямая сумма двух матриц определяется как блочно-диагональная матрица матриц A и B. Результат этой процедуры выглядит следующим образом:

[
  [1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
  [2, 2, 2, 2, 0, 0, 0, 0, 0, 0], 
  [0, 0, 0, 0, 3, 3, 3, 3, 3, 3],
  [0, 0, 0, 0, 4, 4, 4, 4, 4, 4]
]

В левой части этой однострочной строки мы эффективно расширяем строки a с len(b[0]) нулями. С правой стороны делаем наоборот. Мы заполняем первые len(a[0]) индекса каждой строки нулями, а затем объединяем каждую строку b. Затем мы объединяем обе стороны, чтобы создать новую матрицу.

Обратите внимание на эту маленькую хитрость: [0] * len(b). Это создает список нулей len(b). Первоначально я использовал другое понимание списка, чтобы составить список нулей, но этот синтаксический сахар избавляет нас от нескольких нажатий клавиш.

18 января 2023 г.

Разделите матрицу на подматрицу 🍕

a = [  
  [0, 1, 2, 3, 4, 5],
  [5, 4, 3, 2, 1, 0],
  [2, 4, 6, 8, 10, 12],
  [3, 6, 9, 12, 15, 18]
]

x, y = [0, 2], [1, 4]
sub = [m[y[0]:y[1]] for m in a[x[0]:x[1]]]

Обсуждение

Иногда вам может понадобиться взять кусочек из матрицы. Переменные x и y определяют начальный и конечный индексы срезов строк и столбцов. В этом случае раздел или «срез»:

[
  [1, 2, 3],
  [4, 3, 2]
]

17 января 2023 г.

Умножьте две матрицы 🅰️✖🅱️

a = [
  [1, 2, 3],
  [4, 5, 6]
]

b = [
  [7, 8, 0],
  [9, 10, 0],
  [11, 12, 0]
]

result = [[sum([x*y for x,y in zip(row, col)]) for col in zip(*b)] for row in a]

Обсуждение

Этот One Liner довольно умен. Имхо, легче читать справа налево. При этом мы видим, что для начала мы просто перебираем строки матрицы a. Затем мы перебираем столбцы b. Вот тут-то и начинается интересное. Метод zip создает генератор наборов элементов, существующих по одному и тому же индексу в разных списках. Однако мы не можем просто вызвать zip непосредственно на b. Вместо этого мы должны сначала «распаковать» b, что и делает звездочка. Это дает нам столбцы b.

Затем мы берем скалярное произведение каждой строки a и столбца b. И снова функция zip оказывается весьма полезной. Сжатие строки и столбца дает нам пары значений, которые мы затем перемножаем и, наконец, суммируем.

16 января 2023 г.

Найдите транспонированную квадратную матрицу 🙃

matrix = [ 
  [0, 1, 2],
  [3, 4, 5],
  [6, 7, 8]
]

transpose = [[matrix[n][m] for n in range(len(i))] for m, i in enumerate(matrix)]

Обсуждение

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

Вот результат этой операции над матрицей выше:

[
  [0, 3, 6], 
  [1, 4, 7], 
  [2, 5, 8]
]

15 января 2023 г.

Создайте матрицу идентичности 🪪

n = 5
matrix = [[1 if i == j else 0 for j in range(n)] for i in range(n)]

Обсуждение

Еще одно понимание вложенного списка! Единичная матрица представляет собой матрицу размера n на n с единицами по диагонали и нулями в других местах. Это матричный аналог мультипликативного тождества 1. То есть любая квадратная матрица A, умноженная на единичную матрицу той же формы, равна A. Кроме того, квадратная матрица, умноженная на обратную, равна единичной матрице.

Присоединяйся…

Не стесняйтесь оставлять комментарии здесь или клонировать репозиторий на Github и делать запрос на включение, если считаете, что у вас есть лучшее решение. Тесты тоже приветствуются!



Дополнительные материалы на PlainEnglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord .

Заинтересованы в масштабировании запуска вашего программного обеспечения? Ознакомьтесь с разделом Схема.