Матрично-векторные произведения через оператор @
Содержание курса
Три случая оператора @: вектор–вектор, матрица–вектор, матрица–матрица
Правило внутренних размеров абстрактно, пока не видишь, что именно происходит с числами и формой результата в каждом из трёх возможных случаев.
Случай 1: вектор @ вектор → скаляр
Когда оба операнда одномерные и имеют одинаковую длину, @ вычисляет скалярное произведение — попарно умножает элементы и суммирует. Результат — NumPy-скаляр с shape ():
import numpy as np
w = np.array([0.5, 0.3, 0.2])
x = np.array([80.0, 90.0, 70.0])
result = w @ x
print(result) # 81.0
print(result.shape) # ()
Здесь 0.5*80 + 0.3*90 + 0.2*70 = 40 + 27 + 14 = 81.0. Это и есть взвешенная сумма: w — веса, x — значения. Удобный случай на практике: итоговый балл экзамена, портфельная доходность, взвешенное среднее — всё это один вызов @. Обратите внимание, что result.shape возвращает (), а не (1,): NumPy-скаляр не имеет измерений вообще.
Случай 2: матрица @ вектор → вектор
Если левый операнд — матрица shape (m, k), а правый — вектор shape (k,), результат — вектор shape (m,). Каждая строка матрицы независимо перемножается на вектор и суммируется:
A = np.array([[1, 2, 3],
[4, 5, 6]]) # shape (2, 3)
v = np.array([1.0, 0.0, -1.0]) # shape (3,)
result = A @ v
print(result) # [-2. -2.]
print(result.shape) # (2,)
Первая строка A: 1*1 + 2*0 + 3*(-1) = -2. Вторая: 4*1 + 5*0 + 6*(-1) = -2. Форма (2, 3) @ (3,) даёт (2,) — внутренний размер 3 исчезает, остаётся m=2.
Этот случай — рабочая лошадка линейных моделей: матрица признаков умножается на вектор весов и даёт вектор предсказаний.
Случай 3: матрица @ матрица → матрица
Два двумерных операнда shape (m, k) и (k, n) дают матрицу shape (m, n). Каждый элемент результата — скалярное произведение строки левой матрицы и столбца правой:
A = np.array([[1, 2, 3],
[4, 5, 6]]) # shape (2, 3)
B = np.array([[1, 0],
[0, 1],
[1, 1]]) # shape (3, 2)
result = A @ B
print(result)
# [[ 4 5]
# [10 11]]
print(result.shape) # (2, 2)
Результат (2, 3) @ (3, 2) → (2, 2): внутренний размер 3 «схлопнулся», внешние 2 и 2 образовали новую матрицу.
Сводка по shape результата:
(n,) @ (n,)→()— скаляр(m, k) @ (k,)→(m,)— вектор(m, k) @ (k, n)→(m, n)— матрица
Во всех трёх случаях работает одно и то же правило: внутренний размер сокращается, внешние формируют shape результата.
