原文:
www.kdnuggets.com/2023/05/vector-matrix-norms-numpy-linalg-norm.html
作者提供的图片
Numerical Python 或 NumPy 是一个流行的 Python 科学计算库。NumPy 库有大量内置功能,用于创建 n 维数组并对其进行计算。
1. 谷歌网络安全证书 - 快速进入网络安全职业生涯。
2. 谷歌数据分析专业证书 - 提升你的数据分析技能
3. 谷歌 IT 支持专业证书 - 支持你的组织的 IT
如果你对数据科学、计算线性代数和相关领域感兴趣,学习如何计算向量和矩阵的范数会很有帮助。本教程将教你如何使用 NumPy 的linalg模块中的函数来做到这一点。
要进行代码编写,你需要在开发环境中安装 Python 和 NumPy。为了使 print()
语句中的 f-strings 正常工作,你需要安装 Python 3.8 或更高版本。
让我们开始吧!
在本讨论中,我们将首先查看向量范数。稍后我们会讨论矩阵范数。从数学上讲,范数是一个从 n 维向量空间到实数集合的函数(或映射):
注意:范数也可以定义在复数向量空间上,C^n → R 也是一种有效的范数定义。但在本讨论中,我们将限制在实数向量空间。
对于 n 维向量x = (x1,x2,x3,...,xn),x 的范数通常表示为 ||x||,应满足以下性质:
-
||x|| 是非负量。对于向量x,范数 ||x|| 总是大于或等于零。当且仅当向量x是全零向量时,||x|| 才等于零。
-
对于两个向量x = (x1,x2,x3,...,xn) 和 y = (y1,y2,y3,...,yn),它们的范数 ||x|| 和 ||y|| 应满足三角不等式:||x + y|| <= ||x|| + ||y||。
-
此外,所有范数都满足 ||αx|| = |α| ||x||,其中 α 为标量。
一般来说,n 维向量x = (x1,x2,x3,...,xn)的 Lp 范数(或 p-范数)对于 p >= 0 定义为:
让我们来看看常见的向量范数,即 L1、L2 和 L∞ 范数。
L1 范数等于向量中所有元素绝对值的总和:
将 p =2 代入一般的 Lp 范数方程,我们得到向量的 L2 范数的以下表达式:
对于给定的向量 x,L∞ 范数是 x 元素 绝对 值中的 最大值:
验证这些范数是否满足前面列出的范数属性是相当简单的。
NumPy 中的 linalg 模块包含我们可以用来计算范数的函数。
在开始之前,让我们初始化一个向量:
import numpy as np
vector = np.arange(1,7)
print(vector)
Output >> [1 2 3 4 5 6]
让我们从 NumPy 中导入 linalg 模块:
from numpy import linalg
norm()
函数用于计算矩阵和向量的范数。此函数需要一个必需的参数——我们需要计算范数的向量或矩阵。此外,它还接受以下 可选 参数:
-
ord
决定了计算的范数的阶数,以及 -
axis
指定了计算范数的轴。
当我们在函数调用中没有指定 ord
时,norm()
函数默认计算 L2 范数:
l2_norm = linalg.norm(vector)
print(f"{l2_norm = :.2f}")
Output >> l2_norm = 9.54
我们可以通过明确将 ord
设置为 2 来验证这一点:
l2_norm = linalg.norm(vector, ord=2)
print(f"{l2_norm = :.2f}")
Output >> l2_norm = 9.54
要计算向量的 L1 范数,请调用 norm()
函数,设置 ord = 1
:
l1_norm = linalg.norm(vector, ord=1)
print(f"{l1_norm = :.2f}")
Output >> l1_norm = 21.00
由于我们的示例 vector
仅包含正数,我们可以验证在这种情况下 L1 范数等于元素的总和:
assert sum(vector) == l1_norm
要计算 L∞ 范数,将 ord
设置为 'np.inf':
inf_norm = linalg.norm(vector, ord=np.inf)
print(f"{inf_norm = }")
在这个例子中,我们得到 6,向量中的 最大 元素(绝对值意义上):
Output >> inf_norm = 6.0
在 norm()
函数中,你还可以将 ord
设置为 '-np.inf'。
neg_inf_norm = linalg.norm(vector, ord=-np.inf)
print(f"{neg_inf_norm = }")
如你所猜,负的 L∞ 范数返回向量中的 最小 元素(绝对值意义上):
Output >> neg_inf_norm = 1.0
L0 范数给出向量中非零元素的数量。从技术上讲,这不是一个范数。它实际上是一个伪范数,因为它违反了 ||αx|| = |α| ||x|| 的属性。这是因为,即使向量被一个标量乘以,非零元素的数量 保持不变。
要获取向量中非零元素的数量,将 ord
设置为 0:
another_vector = np.array([1,2,0,5,0])
l0_norm = linalg.norm(another_vector,ord=0)
print(f"{l0_norm = }")
在这里,another_vector
有 3 个非零元素:
Output >> l0_norm = 3.0
到目前为止,我们已经看到如何计算向量范数。就像你可以将向量范数视为从 n 维向量空间到实数集合的映射一样,矩阵范数是从 m x n 矩阵空间到实数集合的映射。数学上,你可以表示为:
常见的矩阵范数包括 Frobenius 范数和核范数。
对于一个 m x n 的矩阵 A,其中 m 行 n 列,Frobenius 范数由下式给出:
奇异值分解(SVD)是一种矩阵分解技术,用于主题建模、图像压缩和协同过滤等应用。
SVD 将输入矩阵分解为一个左奇异向量矩阵(U)、一个奇异值矩阵(S)和一个右奇异向量矩阵(V_T)。而核范数是矩阵的最大奇异值。
继续讨论如何在 NumPy 中计算矩阵范数,让我们将 vector
重塑为一个 2 x 3 的矩阵:
matrix = vector.reshape(2,3)
print(matrix)
Output >>
[[1 2 3]
[4 5 6]]
如果你不指定 ord
参数,norm()
函数默认计算 Frobenius 范数。
让我们通过将 ord
设置为 'fro'
来验证这一点:
frob_norm = linalg.norm(matrix,ord='fro')
print(f"{frob_norm = :.2f}")
Output >> frob_norm = 9.54
当我们不传入可选的 ord
参数时,我们也得到 Frobenius 范数:
frob_norm = linalg.norm(matrix)
print(f"{frob_norm = :.2f}")
Output >> frob_norm = 9.54
总结来说,当 norm()
函数以矩阵作为输入时,默认返回矩阵的 Frobenius 范数。
要计算矩阵的核范数,你可以传入矩阵并在 norm()
函数调用中将 ord
设置为 'nuc':
nuc_norm = linalg.norm(matrix,ord='nuc')
print(f"{nuc_norm = :.2f}")
Output >> nuc_norm = 10.28
我们通常不会在矩阵上计算 L1 和 L2 范数,但 NumPy 允许你计算任意 ord
的矩阵(2D 数组)和其他多维数组的范数。
让我们看看如何在特定轴上计算矩阵的 L1 范数——沿行和列。
类似地,我们可以设置 axis = 1
。
axis = 0
表示矩阵的行。如果设置 axis = 0
,则计算矩阵的 L1 范数是 跨行(或沿列)进行的,如下所示:
图片由作者提供
让我们在 NumPy 中验证这一点:
matrix_1_norm = linalg.norm(matrix,ord=1,axis=0)
print(f"{matrix_1_norm = }")
Output >> matrix_1_norm = array([5., 7., 9.])
类似地,我们可以设置 axis = 1
。
axis = 1
表示矩阵的列。因此,通过设置 axis = 1
计算矩阵的 L1 范数是 跨列(沿行)进行的。
图片由作者提供
matrix_1_norm = linalg.norm(matrix,ord=1,axis=1)
print(f"{matrix_1_norm = }")
Output >> matrix_1_norm = array([ 6., 15.])
我建议你试验 ord
和 axis
参数,并尝试不同的矩阵,直到你掌握它。
我希望你现在明白了如何使用 NumPy 计算向量和矩阵范数。然而,需要注意的是,Frobenius 范数和核范数仅对矩阵定义。因此,如果你计算向量或维度超过两个的多维数组,你会遇到错误。这就是本教程的全部内容!
Bala Priya C 是一位技术作家,喜欢创作长篇内容。她的兴趣领域包括数学、编程和数据科学。她通过编写教程、使用指南等方式与开发者社区分享她的学习成果。