7.2 矩阵乘法与线性方程组
NumPy矩阵乘法与线性方程组教程:np.dot, np.matmul, 向量运算与方程求解
本教程详细讲解NumPy中的矩阵乘法(np.dot, np.matmul, @运算符)、向量运算(内积、外积、点积)以及线性方程组求解(np.linalg.solve, np.linalg.lstsq)。适合新人学习,提供简单易懂的示例和解释,帮助您掌握线性代数在数据科学中的应用。
NumPy矩阵乘法与线性方程组教程
简介
NumPy是Python中用于科学计算的核心库,尤其在处理线性代数问题时非常强大。线性代数在数据科学、机器学习和工程应用中无处不在。本教程将详细介绍NumPy中的矩阵乘法、向量运算以及如何求解线性方程组,适合初学者快速上手。
1. 矩阵乘法
矩阵乘法是线性代数的基本操作,在NumPy中有多种实现方式。
1.1 np.dot()
np.dot()函数用于计算两个数组的点积(dot product)。对于矩阵,它执行矩阵乘法。
示例代码:
import numpy as np
# 创建两个2x2矩阵
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
# 使用np.dot进行矩阵乘法
result = np.dot(A, B)
print("np.dot(A, B):")
print(result)
输出:
np.dot(A, B):
[[19 22]
[43 50]]
注意:np.dot()也适用于向量(一维数组),这时计算的是内积或点积。
1.2 np.matmul()
np.matmul()是专门用于矩阵乘法的函数,在NumPy 1.10.0中引入。它支持广播功能,并且对于高维数组更灵活。
示例代码:
# 使用np.matmul进行矩阵乘法
result = np.matmul(A, B)
print("np.matmul(A, B):")
print(result)
输出与np.dot()相同。区别在于np.matmul()不支持标量输入,而np.dot()可以处理标量。
1.3 @运算符
从Python 3.5开始,引入了@运算符作为矩阵乘法的简写。它内部调用np.matmul()。
示例代码:
# 使用@运算符进行矩阵乘法
result = A @ B
print("A @ B:")
print(result)
输出与前两者相同。使用@运算符使代码更简洁易读。
总结:
- 对于标准矩阵乘法,三者都可以使用。
- 如果处理高维数组或需要广播,建议使用
np.matmul()。 @运算符是最简洁的选择,但需确保Python版本支持。
2. 向量运算
向量是矩阵的特殊情况,NumPy提供了函数处理向量的内积、外积和点积。
2.1 内积(Inner Product)
内积通常指两个向量的点积,计算为对应元素乘积的和。在NumPy中,可以使用np.inner()或np.dot()。
示例代码:
# 创建两个向量
v1 = np.array([1, 2, 3])
v2 = np.array([4, 5, 6])
# 使用np.inner计算内积
inner_product = np.inner(v1, v2)
print("np.inner(v1, v2):", inner_product)
# 使用np.dot(对于向量,np.dot就是内积)
dot_product = np.dot(v1, v2)
print("np.dot(v1, v2):", dot_product)
输出:两者都是32(14 + 25 + 3*6 = 4+10+18=32)。
2.2 外积(Outer Product)
外积是两个向量的张量积,产生一个矩阵。使用np.outer()函数。
示例代码:
# 计算外积
outer_product = np.outer(v1, v2)
print("np.outer(v1, v2):")
print(outer_product)
输出:
np.outer(v1, v2):
[[ 4 5 6]
[ 8 10 12]
[12 15 18]]
解释:结果矩阵的每个元素是v1和v2对应元素的乘积。
2.3 点积(Dot Product)
点积通常与内积同义,但在NumPy中,np.dot()是一个通用函数:对于向量计算内积,对于矩阵计算矩阵乘法。
术语澄清:
- 在NumPy中,
np.dot()和np.inner()对于向量是一样的,但np.inner()只适用于一维数组。 - 使用时要根据上下文选择合适的函数。
3. 解线性方程组
线性方程组通常表示为Ax = b,其中A是系数矩阵,x是未知向量,b是常数向量。NumPy提供了np.linalg.solve()来求解。
3.1 np.linalg.solve()
这个函数用于求解线性方程组Ax = b,其中A必须是方阵且非奇异(可逆)。
示例代码:
# 定义系数矩阵A和常数向量b
A = np.array([[3, 1], [1, 2]])
b = np.array([9, 8])
# 使用np.linalg.solve求解
x = np.linalg.solve(A, b)
print("解x:", x)
# 验证:计算A @ x是否等于b
print("验证 A @ x:", A @ x)
输出:
解x: [2. 3.]
验证 A @ x: [9. 8.]
注意:如果A是奇异的,会引发LinAlgError。在使用前,可以检查A的条件数或其他方法。
4. 最小二乘解
当线性方程组无解或过定(方程数大于未知数)时,可以使用最小二乘法找到最佳近似解。NumPy的np.linalg.lstsq()实现了这一点。
4.1 np.linalg.lstsq()
这个函数求解线性最小二乘问题,最小化误差||Ax - b||^2。
示例代码:
# 定义一个过定系统:A是3x2,b是3维向量
A = np.array([[1, 1], [1, 2], [2, 1]])
b = np.array([2, 3, 4])
# 使用np.linalg.lstsq求解
x, residuals, rank, s = np.linalg.lstsq(A, b, rcond=None)
print("最小二乘解x:", x)
print("残差和:", residuals) # 误差平方和
print("秩:", rank)
print("奇异值:", s)
输出:
最小二乘解x: [1. 1.]
残差和: [0.5]
秩: 2
奇异值: [3.868 0.606]
解释:
x是最小二乘解。residuals是残差平方和(误差)。rank是矩阵A的秩。s是奇异值。
使用场景: 适用于回归分析、数据拟合等。
总结
本教程覆盖了NumPy中关键的线性代数操作:
- 矩阵乘法: 使用
np.dot()、np.matmul()或@运算符,各有适用场景。 - 向量运算: 内积用
np.inner()或np.dot(),外积用np.outer(),注意术语区别。 - 解线性方程组:
np.linalg.solve()用于方阵系统,np.linalg.lstsq()用于最小二乘问题。
学习建议:
- 实践代码示例,尝试修改参数加深理解。
- 探索NumPy文档了解更多线性代数函数,如特征值计算。
- 在线性代数知识基础上,应用到实际数据科学项目中。
通过本教程,您应该能够使用NumPy高效处理矩阵和向量运算,解决常见的线性代数问题。