原文: https://machinelearningmastery.com/introduction-matrices-machine-learning/
矩阵是线性代数的基本元素。
在训练算法时,在算法和过程(例如输入数据变量(X))的描述中,在整个机器学习领域中使用矩阵。
在本教程中,您将发现线性代数中的矩阵以及如何在 Python 中对它们进行操作。
完成本教程后,您将了解:
- 什么是矩阵以及如何使用 NumPy 在 Python 中定义矩阵。
- 如何执行元素操作,如加法,减法和 Hadamard 产品。
- 如何将矩阵相乘以及操作背后的直觉。
让我们开始吧。
机器学习矩阵的温和介绍 Maximiliano Kolus 的照片,保留一些权利。
本教程分为 6 个部分;他们是:
- 什么是矩阵?
- 定义矩阵
- 矩阵算术
- 矩阵 - 矩阵乘法(点积)
- 矩阵向量乘法
- 矩阵 - 标量乘法
矩阵是具有一个或多个列和一个或多个行的标量的二维数组。
矩阵是数字的二维数组(表)。
- 第 115 页,无线性代数废话指南,2017 年
矩阵的符号通常是大写字母,例如 A,并且条目由它们的行(i)和列(j)的二维下标引用,例如 aij。例如:
A = ((a11, a12), (a21, 22), (a31, a32))
更常见的是使用水平表示法定义矩阵。
a11, a12
A = (a21, a22)
a31, a32
您可能在机器学习中遇到矩阵的第一个地方是模型训练数据,该数据由许多行和列组成,并且通常使用大写字母“X”表示。
用于帮助理解向量及其某些操作的几何类比不适用于矩阵。此外,向量本身可以被认为是具有一列和多行的矩阵。
对于行数和列数,矩阵的尺寸通常表示为 m 和 n。
既然我们知道矩阵是什么,那么让我们看看在 Python 中定义矩阵。
我们可以使用二维 NumPy 数组在 Python 中表示矩阵。
可以在给定列表列表的情况下构造 NumPy 数组。例如,下面是 3 行,2 列矩阵。
# create matrix
from numpy import array
A = array([[1, 2, 3], [4, 5, 6]])
print(A)
运行该示例将打印显示预期结构的创建矩阵。
[[1 2 3]
[4 5 6]]
在本节中将演示简单的矩阵 - 矩阵算法,其中所有操作在相同大小的两个矩阵之间以元素方式执行,以产生具有相同大小的新矩阵。
可以将具有相同尺寸的两个矩阵相加在一起以创建新的第三矩阵。
C = A + B
所得矩阵中的标量元素被计算为添加的每个矩阵中元素的相加。
a11 + b11, a12 + b12
A + B = (a21 + b21, a22 + b22)
a31 + b31, a32 + b32
或者,换句话说:
C[0,0] = A[0,0] + B[0,0]
C[1,0] = A[1,0] + B[1,0]
C[2,0] = A[2,0] + B[2,0]
C[0,1] = A[0,1] + B[0,1]
C[1,1] = A[1,1] + B[1,1]
C[2,1] = A[2,1] + B[2,1]
我们可以在 python 中使用 plus 运算符直接在两个 NumPy 数组上实现它。
# add matrices
from numpy import array
A = array([[1, 2, 3], [4, 5, 6]])
print(A)
B = array([[1, 2, 3], [4, 5, 6]])
print(B)
C = A + B
print(C)
该示例首先定义两个 2×3 矩阵,然后将它们相加。
运行该示例首先打印两个父矩阵,然后将它们添加到一起。
[[1 2 3]
[4 5 6]]
[[1 2 3]
[4 5 6]]
[[ 2 4 6]
[ 8 10 12]]
类似地,可以从具有相同尺寸的另一个矩阵中减去一个矩阵。
C = A - B
计算得到的矩阵中的标量元素,作为每个矩阵中元素的减法。
a11 - b11, a12 - b12
A - B = (a21 - b21, a22 - b22)
a31 - b31, a32 - b32
Or, put another way:
C[0,0] = A[0,0] - B[0,0]
C[1,0] = A[1,0] - B[1,0]
C[2,0] = A[2,0] - B[2,0]
C[0,1] = A[0,1] - B[0,1]
C[1,1] = A[1,1] - B[1,1]
C[2,1] = A[2,1] - B[2,1]
我们可以在 python 中使用 minus 运算符直接在两个 NumPy 数组上实现它。
# subtract matrices
from numpy import array
A = array([[1, 2, 3], [4, 5, 6]])
print(A)
B = array([[0.5, 0.5, 0.5], [0.5, 0.5, 0.5]])
print(B)
C = A - B
print(C)
该示例首先定义两个 2×3 矩阵,然后从另一个中减去一个。
运行该示例首先打印两个父矩阵,然后从第二个矩阵中减去第一个矩阵。
[[1 2 3]
[4 5 6]]
[[ 0.5 0.5 0.5]
[ 0.5 0.5 0.5]]
[[ 0.5 1.5 2.5]
[ 3.5 4.5 5.5]]
具有相同大小的两个矩阵可以相乘,这通常称为逐元素矩阵乘法或 Hadamard 乘积。
当提到矩阵乘法时,这不是典型的操作,因此经常使用不同的算子,例如圆圈“o”。
C = A o B
与逐元素减法和加法一样,逐元素乘法涉及从每个父矩阵乘以元素以计算新矩阵中的值。
a11 * b11, a12 * b12
A o B = (a21 * b21, a22 * b22)
a31 * b31, a32 * b32
Or, put another way:
C[0,0] = A[0,0] * B[0,0]
C[1,0] = A[1,0] * B[1,0]
C[2,0] = A[2,0] * B[2,0]
C[0,1] = A[0,1] * B[0,1]
C[1,1] = A[1,1] * B[1,1]
C[2,1] = A[2,1] * B[2,1]
我们可以在 python 中使用 star 运算符直接在两个 NumPy 数组上实现它。
# element-wise multiply matrices
from numpy import array
A = array([[1, 2, 3], [4, 5, 6]])
print(A)
B = array([[1, 2, 3], [4, 5, 6]])
print(B)
C = A * B
print(C)
该示例首先定义两个 2×3 矩阵,然后将它们相乘。
运行该示例首先打印两个父矩阵,然后将它们与 Hadamard 产品相乘。
[[1 2 3]
[4 5 6]]
[[1 2 3]
[4 5 6]]
[[ 1 4 9]
[16 25 36]]
一个矩阵可以被具有相同尺寸的另一个矩阵划分。
C = A / B
得到的矩阵中的标量元素被计算为每个矩阵中元素的划分。
a11 / b11, a12 / b12
A / B = (a21 / b21, a22 / b22)
a31 / b31, a32 / b32
Or, put another way:
C[0,0] = A[0,0] / B[0,0]
C[1,0] = A[1,0] / B[1,0]
C[2,0] = A[2,0] / B[2,0]
C[0,1] = A[0,1] / B[0,1]
C[1,1] = A[1,1] / B[1,1]
C[2,1] = A[2,1] / B[2,1]
我们可以直接在两个 NumPy 数组上使用除法运算符在 python 中实现它。
# divide matrices
from numpy import array
A = array([[1, 2, 3], [4, 5, 6]])
print(A)
B = array([[1, 2, 3], [4, 5, 6]])
print(B)
C = A / B
print(C)
该示例首先定义两个 2×3 矩阵,然后将第一个与第二个矩阵相除。
首先运行该示例打印两个父矩阵,然后将第一个矩阵除以第二个矩阵。
[[1 2 3]
[4 5 6]]
[[1 2 3]
[4 5 6]]
[[ 1\. 1\. 1.]
[ 1\. 1\. 1.]]
矩阵乘法(也称为矩阵点乘积)比先前的操作更复杂,并且涉及规则,因为并非所有矩阵都可以相乘。
C = A * B
要么
C = AB
矩阵乘法的规则如下:
- 第一矩阵(A)中的列数(n)必须等于第二矩阵(B)中的行数(m)。
例如,矩阵 A 的尺寸为 m 行 n 列,矩阵 B 的尺寸为 n 和 k。 A 行和 n 行 b 中的 n 列相等。结果是一个 m 行和 k 列的新矩阵。
C(m,k) = A(m,n) * B(n,k)
此规则适用于矩阵乘法链,其中链中一个矩阵中的列数必须与链中下一个矩阵中的行数匹配。
涉及矩阵的最重要的操作之一是两个矩阵的乘法。矩阵 A 和 B 的矩阵乘积是第三矩阵 C.为了定义该乘积,A 必须具有与 B 具有行相同的列数。如果 A 的形状为 m×n 且 B 的形状为 n×p,则 C 的形状为 m×p。
- 第 34 页,深度学习,2016 年。
矩阵乘法的直觉是我们计算矩阵 A 中每一行与矩阵 B 中每列之间的点积。例如,我们可以逐步降低 A 列的行数并将每一行乘以 B 中的第 1 列来给出标量 C 列第 1 列中的值
使用以下图像可以清楚地看到这一点。
矩阵乘法的描述,取自 Wikipedia ,保留一些权利。
下面描述使用矩阵表示法的矩阵乘法。
a11, a12
A = (a21, a22)
a31, a32
b11, b12
B = (b21, b22)
a11 * b11 + a12 * b21, a11 * b12 + a12 * b22
C = (a21 * b11 + a22 * b21, a21 * b12 + a22 * b22)
a31 * b11 + a32 * b21, a31 * b12 + a32 * b22
通过删除乘法符号可以简化这一点:
a11b11 + a12b21, a11b12 + a12b22
C = (a21b11 + a22b21, a21b12 + a22b22)
a31b11 + a32b21, a31b12 + a32b22
我们可以使用数组表示法描述矩阵乘法运算。
C[0,0] = A[0,0] * B[0,0] + A[0,1] * B[1,0]
C[1,0] = A[1,0] * B[0,0] + A[1,1] * B[1,0]
C[2,0] = A[2,0] * B[0,0] + A[2,1] * B[1,0]
C[0,1] = A[0,0] * B[0,1] + A[0,1] * B[1,1]
C[1,1] = A[1,0] * B[0,1] + A[1,1] * B[1,1]
C[2,1] = A[2,0] * B[0,1] + A[2,1] * B[1,1]
矩阵乘法运算可以使用 dot()函数在 NumPy 中实现。
# matrix dot product
from numpy import array
A = array([[1, 2], [3, 4], [5, 6]])
print(A)
B = array([[1, 2], [3, 4]])
print(B)
C = A.dot(B)
print(C)
该示例首先定义两个 2×3 矩阵,然后计算它们的点积。
运行该示例首先打印两个父矩阵,然后打印点积的结果。
[[1 2]
[3 4]
[5 6]]
[[1 2]
[3 4]]
[[ 7 10]
[15 22]
[23 34]]
只要观察到矩阵乘法的规则,矩阵和向量就可以相乘。
具体而言,矩阵中的列数必须等于向量中的项数。与矩阵乘法一样,可以使用点表示法编写操作。因为向量只有一列,所以结果总是一个向量。
c = A . v
或者没有紧凑形式的圆点。
c = Av
结果是一个与父矩阵具有相同行数的向量。
a11, a12
A = (a21, a22)
a31, a32
v1
v = (v2)
a11 * v1 + a12 * v2
c = (a21 * v1 + a22 * v2)
a31 * v1 + a32 * v2
或者,更紧凑。
a11v1 + a12v2
c = (a21v1 + a22v2)
a31v1 + a32v2
矩阵向量乘法可以使用 dot()函数在 NumPy 中实现。
# matrix-vector multiplication
from numpy import array
A = array([[1, 2], [3, 4], [5, 6]])
print(A)
B = array([0.5, 0.5])
print(B)
C = A.dot(B)
print(C)
该示例首先定义 2×3 矩阵和 2 元素向量,然后将它们相乘。
首先运行示例打印父矩阵和向量,然后将它们相乘的结果打印出来。
[[1 2]
[3 4]
[5 6]]
[ 0.5 0.5]
[ 1.5 3.5 5.5]
矩阵可以乘以标量。
这可以使用矩阵和标量之间的点表示法来表示。
C = A . b
或者没有点符号。
C = Ab
结果是具有与父矩阵相同大小的矩阵,其中矩阵的每个元素乘以标量值。
a11, a12
A = (a21, a22)
a31, a32
b
a11 * b, a12 * b
C = (a21 * b, a22 * b)
a31 * b, a32 * b
or
a11b, a12b
C = (a21b, a22b)
a31b, a32b
我们也可以用数组表示法来表示它。
C[0,0] = A[0,0] * b
C[1,0] = A[1,0] * b
C[2,0] = A[2,0] * b
C[0,1] = A[0,1] * b
C[1,1] = A[1,1] * b
C[2,1] = A[2,1] * b
这可以使用乘法运算符直接在 NumPy 中实现。
# matrix-scalar multiplication
from numpy import array
A = array([[1, 2], [3, 4], [5, 6]])
print(A)
b = 0.5
print(b)
C = A * b
print(C)
该示例首先定义 2×3 矩阵和标量,然后将它们相乘。
首先运行示例打印父矩阵和标量,然后将它们相乘的结果打印出来。
[[1 2]
[3 4]
[5 6]]
0.5
[[ 0.5 1\. ]
[ 1.5 2\. ]
[ 2.5 3\. ]]
本节列出了一些扩展您可能希望探索的教程的想法。
- 使用您自己的数据使用每个操作创建 5 个示例。
- 为定义为列表列表的矩阵手动实现每个矩阵操作。
- 搜索机器学习论文并找到每个正在使用的操作的示例。
如果你探索任何这些扩展,我很想知道。
如果您希望深入了解,本节将提供有关该主题的更多资源。
- 第 2.3 节,矩阵运算。 线性代数无废话指南,2017 年。
- 第 3.3 节,矩阵乘法。 线性代数无废话指南,2017 年。
- 第 1.3 节矩阵,线性代数简介,第五版,2016 年。
- 第 2.4 节矩阵运算规则,线性代数导论,第五版,2016 年。
- 第 2.1 节标量,向量,矩阵和张量,深度学习,2016 年。
- 第 2.2 节乘以矩阵和向量,深度学习,2016。
在本教程中,您发现了线性代数中的矩阵以及如何在 Python 中对它们进行操作。
具体来说,你学到了:
- 什么是矩阵以及如何使用 NumPy 在 Python 中定义矩阵。
- 如何执行元素操作,如加法,减法和 Hadamard 产品。
- 如何将矩阵相乘以及操作背后的直觉。
你有任何问题吗? 在下面的评论中提出您的问题,我会尽力回答。