前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >机器学习入门 3-7 Numpy 中的矩阵运算

机器学习入门 3-7 Numpy 中的矩阵运算

作者头像
触摸壹缕阳光
发布2022-05-25 14:02:11
7390
发布2022-05-25 14:02:11
举报

numpy.array 中的运算

给定一个向量,让向量中每一个数乘以 2

  • a = (0, 1, 2)
  • a * 2 = (0, 2, 4)

如何解决上面的问题呢?我们可以使用原生 Python 来实现。

代码语言:javascript
复制
n = 10
L = [i for i in range(n)]

print(2 * L)
'''
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
'''

显然,在 Python 中,列表 * N 中的 * 运算符为重复操作,将列表中的每个元素重复 N 次。

为了让列表中的每一个元素都乘以 2,我们可以使用 for 循环实现。

代码语言:javascript
复制
A = []
for e in L:
    A.append(2 * e)

print(A)
'''
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
'''

这种做法的效率是多少呢?为了测试效率,我们将列表中的元素个数设置的大一些。

代码语言:javascript
复制
n = 1000000
L = [i for i in range(n)]

在 jupyter 中,可以使用 %%time 魔法方法来测试时间。

代码语言:javascript
复制
%%time
A = []
for e in L:
    A.append(2 * e)

在我的电脑中用时:196 ms。众所周知,使用生成表达式的效率要比 for 循环高。

代码语言:javascript
复制
%%time
A = [2 * e for e in L]

用时是 103 ms。

那在 NumPy 中如何实现呢?

代码语言:javascript
复制
import numpy as np

n = 1000000
L = np.arange(n)
代码语言:javascript
复制
%%time
A = np.array(2 * e for e in L)

用时为 12 ms。

在 NumPy 中可以直接对进行一些向量和矩阵的操作。

代码语言:javascript
复制
%%time
A = 2 * L

用时为 2.03 ms。通过用时也可以看出 NumPy 能够显著地提升运算的效率。NumPy 会把数组当做向量或者矩阵来看待,并且支持很多向量和矩阵的运算操作。这些运算操作在 NumPy 中进行了非常好的优化,运行速度非常快。这种将数组看成向量或矩阵的运算有一个名字:Universal Functions。

Universal Functions

代码语言:javascript
复制
X = np.arange(1, 16).reshape((3, 5))

X + 1  # 矩阵加法
X - 1  # 矩阵减法
X * 2  # 矩阵数乘
X / 2  # 矩阵除法
X // 2 # 矩阵整除
X ** 2 # 幂运算
X % 2  # 求余运算
1 / X  # 矩阵运算取倒数

NumPy 同样也支持很多特殊的运算。

代码语言:javascript
复制
np.abs(X) # 求绝对值
np.sin(X) # 正弦函数
np.cos(X) # 余弦函数
np.tan(X) # 正切函数
np.exp(X) # 取e^X次方
np.power(3, X) # 等价于 3 ** X
np.log(X) # 以e为底取对数
np.log2(X) # 以2为底取对数
np.log10(X) # 以10为底取对数

以上这些运算都是针对一个数组进行运算,并且这些运算作用在数组中的每一个元素。

矩阵运算

NumPy 还支持矩阵和矩阵之间的运算。

代码语言:javascript
复制
A = np.arange(4).reshape(2, 2)
B = np.full((2, 2), 10)
代码语言:javascript
复制
A + B # 矩阵的加法
A - B # 矩阵的减法
A * B # Hadamard乘积,对应元素相乘
A / B # 矩阵对应元素相除

A.dot(B) # 矩阵的乘法
A.T   # 矩阵的转置

向量和矩阵的运算

在机器学习中除了矩阵和矩阵的运算外,还有一种运算使用的也比较多,就是向量和矩阵之间的运算。

代码语言:javascript
复制
v = np.array([1, 2]) # 向量
A = np.arange(4).reshape(2, 2) # 矩阵

print(v + A)
'''
array([[1, 3],
       [3, 5]])
'''

在线性代数中,向量和矩阵是没有办法相加的,不过在 NumPy 中,向量通过广播机制变成了矩阵相同的形状,进而进行运算。

我们可以显示的使用 vstack 函数,将向量 v 扩充到和矩阵 A 相同的形状。

代码语言:javascript
复制
print(np.vstack([v] * A.shape[0]))
'''
array([[1, 2],
       [1, 2]])
'''

print(np.vstack([v] * A.shape[0]) + A)
'''
array([[1, 3],
       [3, 5]])
'''

对于上面的操作,NumPy 还提供了更加简单的 tile 函数,tile 函数的第二个参数是一个数组类型,表示沿着每个维度重复的数量。比如,np.tile(v, (2, 1)) 第二个参数为 (2, 1),表示将 v 沿着第一个维度重复 2 次,沿着第二个维度重复 1 次。

代码语言:javascript
复制
print(np.tile(v, (2, 1)))
'''
array([[1, 2],
       [1, 2]])
'''

print(np.tile(v, (2, 1)) + A)
'''
array([[1, 3],
       [3, 5]])
'''

在 NumPy 中,向量和矩阵可以进行 Hadamard 乘积(对应元素相乘),这个同样是运用广播机制,将向量扩充成矩阵,然后再与矩阵进行 Hadamard 乘积。

代码语言:javascript
复制
print(v * A)
'''
array([[0, 2],
       [2, 6]])
'''

向量和矩阵之间可以进行矩阵的乘法,此时是将向量看成是行向量或列向量。具体将向量看成行向量还是列向量,NumPy 可以自动帮助我们判断。

代码语言:javascript
复制
print(v.dot(A)) # 将向量v看成行向量
print(A.dot(v)) # 将向量v看成列向量

矩阵的逆

代码语言:javascript
复制
A = np.arange(4).reshape(2, 2)
invA = np.linalg.inv(A) # 计算矩阵A的逆矩阵

在线性代数中,原矩阵和逆矩阵(或逆矩阵和原矩阵)进行矩阵相乘的运算,结果为单位矩阵。

代码语言:javascript
复制
print(A.dot(invA))
'''
array([[1., 0.],
       [0., 1.]])
'''

print(invA.dot(A))
'''
array([[1., 0.],
       [0., 1.]])
'''

不过需要注意,只有方阵才有可能有逆矩阵(未必任何方阵都有逆矩阵),不是方阵的矩阵肯定没有逆矩阵。

代码语言:javascript
复制
X = np.arange(16).reshape((2, 8))
print(np.linalg.inv(X))
'''
LinAlgError: Last 2 dimensions of the array must be square
'''

可是在机器学习中,很多时候需要求矩阵的逆。对于这种非方阵,可以求伪逆矩阵。

代码语言:javascript
复制
pinvX = np.linalg.pinv(X)
print(pinvX.shape)
'''
(8, 2)
'''

X 原矩阵的形状为 (2, 8),而 X 的伪逆矩阵 pinvX 为 (8, 2),它们之间满足矩阵 X 和 X 的伪逆矩阵进行矩阵相乘的运算,结果为单位矩阵。

代码语言:javascript
复制
print(X.dot(pinvX))
'''
array([[ 1.00000000e+00, -2.49800181e-16],
       [ 6.66133815e-16,  1.00000000e+00]])
'''

References:

  1. Python3入门机器学习 经典算法与应用: https://coding.imooc.com/class/chapter/169.html#Anchor
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-05-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AI机器学习与深度学习算法 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • numpy.array 中的运算
  • Universal Functions
  • 矩阵运算
  • 向量和矩阵的运算
  • 矩阵的逆
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档