# 机器学习的矩阵和矩阵算法简介

> 原文： [https://machinelearningmastery.com/introduction-matrices-machine-learning/](https://machinelearningmastery.com/introduction-matrices-machine-learning/)

矩阵是线性代数的基本元素。

在训练算法时，在算法和过程（例如输入数据变量（X））的描述中，在整个机器学习领域中使用矩阵。

在本教程中，您将发现线性代数中的矩阵以及如何在 Python 中对它们进行操作。

完成本教程后，您将了解：

*   什么是矩阵以及如何使用 NumPy 在 Python 中定义矩阵。
*   如何执行元素操作，如加法，减法和 Hadamard 产品。
*   如何将矩阵相乘以及操作背后的直觉。

让我们开始吧。

![A Gentle Introduction to Matrices for Machine Learning](img/c57b334ad0ed881003cc804dfe0e16c1.jpg)

机器学习矩阵的温和介绍
[Maximiliano Kolus](https://www.flickr.com/photos/agent1994/5062439082/) 的照片，保留一些权利。

## 教程概述

本教程分为 6 个部分;他们是：

1.  什么是矩阵？
2.  定义矩阵
3.  矩阵算术
4.  矩阵 - 矩阵乘法（点积）
5.  矩阵向量乘法
6.  矩阵 - 标量乘法

## 什么是矩阵？

矩阵是具有一个或多个列和一个或多个行的标量的二维数组。

> 矩阵是数字的二维数组（表）。

- 第 115 页，[无线性代数废话指南](http://amzn.to/2k76D4C)，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 产品）

具有相同大小的两个矩阵可以相乘，这通常称为逐元素矩阵乘法或 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 页，[深度学习](http://amzn.to/2B3MsuU)，2016 年。

矩阵乘法的直觉是我们计算矩阵 A 中每一行与矩阵 B 中每列之间的点积。例如，我们可以逐步降低 A 列的行数并将每一行乘以 B 中的第 1 列来给出标量 C 列第 1 列中的值

使用以下图像可以清楚地看到这一点。

![Depiction of matrix multiplication.](img/111352d280178b57d37b0809545812fa.jpg)

矩阵乘法的描述，取自 [Wikipedia](https://en.wikipedia.org/wiki/Matrix_multiplication) ，保留一些权利。

下面描述使用矩阵表示法的矩阵乘法。

```
     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 节，矩阵运算。 [线性代数无废话指南](http://amzn.to/2k76D4)，2017 年。
*   第 3.3 节，矩阵乘法。 [线性代数无废话指南](http://amzn.to/2k76D4)，2017 年。
*   第 1.3 节矩阵，[线性代数简介](http://amzn.to/2AZ7R8j)，第五版，2016 年。
*   第 2.4 节矩阵运算规则，[线性代数导论](http://amzn.to/2AZ7R8j)，第五版，2016 年。
*   第 2.1 节标量，向量，矩阵和张量，[深度学习](http://amzn.to/2j4oKuP)，2016 年。
*   第 2.2 节乘以矩阵和向量，[深度学习](http://amzn.to/2B3MsuU)，2016。

### API

*   [numpy.array（）API](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.array.html)
*   [numpy.dot（）API](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.dot.html)

### 用品

*   [矩阵（数学）](https://en.wikipedia.org/wiki/Matrix_(mathematics))
*   [维基百科上的矩阵乘法](https://en.wikipedia.org/wiki/Matrix_multiplication)
*   [维基百科上的 Hadamard 产品（矩阵）](https://en.wikipedia.org/wiki/Hadamard_product_(matrices))
*   维基百科上的 [Dot 产品](https://en.wikipedia.org/wiki/Dot_product)

## 摘要

在本教程中，您发现了线性代数中的矩阵以及如何在 Python 中对它们进行操作。

具体来说，你学到了：

*   什么是矩阵以及如何使用 NumPy 在 Python 中定义矩阵。
*   如何执行元素操作，如加法，减法和 Hadamard 产品。
*   如何将矩阵相乘以及操作背后的直觉。

你有任何问题吗？
在下面的评论中提出您的问题，我会尽力回答。