📌 写在前面
大家好!👋
欢迎来到**【一起学Python】**的第87天!🎉
前86天,我们从安装环境一路学到字符串处理,已经掌握了NumPy处理日常数据的完整技能。但如果你想进入机器学习、深度学习、计算机视觉等进阶领域,线性代数是绕不开的基石!
🤔 为什么要学线性代数?
- ✅ 机器学习核心:神经网络本质就是矩阵运算的堆叠
- ✅ 数据降维必备:PCA、SVD等算法依赖特征值分解
- ✅ 图像处理基础:旋转、缩放、卷积都是线性变换
- ✅ 科学计算标配:求解方程组、优化问题全靠它
今天你将学到:
- 🔸 矩阵乘法、转置、逆的核心操作
- 🔸 行列式与矩阵可逆性判断
- 🔸 特征值与特征向量的计算与应用
- 🔸 实战:用线性代数解多元方程组
准备好了吗?让我们开始吧!🚀
一、线性代数基础:从向量到矩阵 🔢
1.1 向量与矩阵的创建
import numpy as np# 创建向量(1维数组)vector = np.array([1, 2, 3])print("向量:", vector)print("形状:", vector.shape) # (3,)# 创建矩阵(2维数组)matrix = np.array([[1, 2, 3], [4, 5, 6]])print("矩阵:\n", matrix)print("形状:", matrix.shape) # (2, 3)
💡 关键理解:
- 向量 = 1维数组,矩阵 = 2维数组
- 高维数组 = 张量(Tensor),深度学习的基础
1.2 矩阵的基本属性
A = np.array([[1, 2, 3], [4, 5, 6]])print("形状:", A.shape) # (2, 3)print("维度数:", A.ndim) # 2print("元素总数:", A.size) # 6print("转置形状:", A.T.shape) # (3, 2)
二、核心矩阵运算:乘法、转置、逆 🔄
2.1 矩阵乘法:@ 或 np.dot()
A = np.array([[1, 2], [3, 4]]) # 2×2B = np.array([[5, 6], [7, 8]]) # 2×2# 方法1:使用 @ 操作符(推荐!)C1 = A @ B# 方法2:使用 np.dot()C2 = np.dot(A, B)print("矩阵乘法结果:\n", C1)# 输出:# [[19 22]# [43 50]]
1×5 + 2×7 = 5 + 14 = 19 ✅
# ❌ 错误示例A = np.array([[1, 2, 3]]) # 1×3B = np.array([[4, 5]]) # 1×2# result = A @ B # ValueError: 形状不匹配!# ✅ 正确示例B_T = B.T # 转置后变为 2×1result = A @ B_T # 1×3 @ 3×1 = 1×1 ✅
2.2 矩阵转置:.T 或 np.transpose()
M = np.array([[1, 2, 3], [4, 5, 6]])print("原矩阵:\n", M)print("转置后:\n", M.T)# 输出:# [[1 4]# [2 5]# [3 6]]
💡 应用场景:
- 特征矩阵转置:样本×特征 → 特征×样本
- 计算协方差矩阵:
X.T @ X
2.3 矩阵的逆:np.linalg.inv()
只有方阵(行数=列数)且可逆(行列式≠0)才能求逆!
A = np.array([[1, 2], [3, 4]])# 先判断是否可逆:计算行列式det = np.linalg.det(A)print("行列式:", det) # -2.0 ≠ 0 → 可逆 ✅# 计算逆矩阵A_inv = np.linalg.inv(A)print("逆矩阵:\n", A_inv)# 输出:# [[-2. 1. ]# [ 1.5 -0.5]]# 验证:A @ A_inv ≈ 单位矩阵identity = A @ A_invprint("验证结果:\n", np.round(identity, 10))# 输出:# [[1. 0.]# [0. 1.]]
⚠️ 避坑指南:
- 奇异矩阵(行列式=0)无法求逆,会报错
- 浮点数计算有精度误差,验证时用
np.allclose()而非==
三、特征值与特征向量:矩阵的"基因" 🧬
3.1 概念理解
对于方阵 A,如果存在非零向量 v 和标量 λ,使得:
则 λ 称为特征值,v 称为对应的特征向量。
💡 直观理解:特征向量是经过矩阵变换后方向不变的向量,特征值表示缩放比例。
3.2 计算实战
A = np.array([[4, 2], [1, 3]])# 计算特征值和特征向量eigenvalues, eigenvectors = np.linalg.eig(A)print("特征值:", eigenvalues)# 输出: [5. 2.]print("特征向量:\n", eigenvectors)# 输出:# [[ 0.89442719 -0.70710678]# [ 0.4472136 0.70710678]]# 验证:A @ v ≈ λ @ vv1 = eigenvectors[:, 0] # 第一个特征向量λ1 = eigenvalues[0] # 第一个特征值print("A @ v1:", A @ v1)print("λ1 @ v1:", λ1 * v1)print("是否相等:", np.allclose(A @ v1, λ1 * v1)) # True ✅
3.3 应用场景:主成分分析(PCA)简化版
# 模拟2维数据(100个样本)np.random.seed(42)X = np.random.multivariate_normal( mean=[0, 0], cov=[[3, 1], [1, 1]], size=100)# 1. 中心化(减去均值)X_centered = X - np.mean(X, axis=0)# 2. 计算协方差矩阵cov_matrix = np.cov(X_centered.T)# 3. 计算特征值和特征向量eigenvalues, eigenvectors = np.linalg.eig(cov_matrix)# 4. 按特征值降序排序,取最大特征值对应的特征向量(主成分)idx = eigenvalues.argsort()[::-1]principal_component = eigenvectors[:, idx[0]]print("主成分方向:", principal_component)print("解释方差比例:", eigenvalues[idx[0]] / np.sum(eigenvalues))
📊 输出解读:
- 主成分方向:数据变化最大的方向
- 解释方差比例:该方向能解释多少原始数据的信息
四、实战:用线性代数解多元方程组 🧩
场景:求解线性方程组
import numpy as np# 系数矩阵 AA = np.array([[2, 3], [4, 5]])# 常数项向量 bb = np.array([8, 14])# 方法1:使用逆矩阵(理论方法)x_inv = np.linalg.inv(A) @ bprint("解(逆矩阵法):", x_inv) # [1. 2.]# 方法2:使用np.linalg.solve(推荐!数值更稳定)x_solve = np.linalg.solve(A, b)print("解(solve法):", x_solve) # [1. 2.]# 验证print("验证:", A @ x_solve) # [ 8. 14.] ✅
💡 为什么推荐solve()?
- 避免显式求逆,数值稳定性更高
- 计算效率更好,尤其对大矩阵
拓展:最小二乘法拟合(超定方程组)
当方程数 > 未知数时,用最小二乘求最优解:
# 模拟数据:y = 2x + 1 + 噪声x_data = np.array([1, 2, 3, 4, 5])y_data = 2 * x_data + 1 + np.random.randn(5) * 0.5# 构建设计矩阵 [x, 1]X = np.column_stack([x_data, np.ones_like(x_data)])# 最小二乘解:(XᵀX)⁻¹Xᵀycoeffs = np.linalg.solve(X.T @ X, X.T @ y_data)print("拟合参数 [斜率, 截距]:", coeffs)# 输出示例: [2.05 0.92] ≈ [2, 1] ✅
📝 今日作业
基础题 ⭐
- 创建两个2×2矩阵,计算它们的乘积和转置
- 判断矩阵
[[1,2],[2,4]] 是否可逆,并说明原因 - 计算矩阵
[[3,1],[1,3]] 的特征值和特征向量
进阶题 ⭐⭐
- 用
np.linalg.solve()求解方程组:3x+2y=7, x+4y=9 - 生成随机3×3矩阵,验证
A @ A⁻¹ ≈ I - 对2维随机数据计算协方差矩阵,并找出主成分方向
挑战题 ⭐⭐⭐
- 图像旋转:用旋转矩阵
[[cosθ, -sinθ], [sinθ, cosθ]] 对2D点集进行旋转变换 - PCA降维:对100个3维样本降维到2维,可视化降维前后分布
- 线性回归实现:不用sklearn,纯NumPy实现多元线性回归(含截距项)
💡 参考代码(基础题):
import numpy as np# 矩阵乘法A = np.array([[1, 2], [3, 4]])B = np.array([[5, 6], [7, 8]])print("A @ B:\n", A @ B)# 判断可逆性C = np.array([[1, 2], [2, 4]])det_C = np.linalg.det(C)print("行列式:", det_C) # 0 → 不可逆 ❌# 特征值计算D = np.array([[3, 1], [1, 3]])vals, vecs = np.linalg.eig(D)print("特征值:", vals) # [4. 2.]
💡 学习小贴士
- 矩阵乘法:
- 优先用
@ 操作符,代码更清晰 - 形状不匹配?先
print(A.shape, B.shape) 检查
- 求逆注意事项:
- 先算行列式
np.linalg.det() 判断可逆性 - 实际求解优先用
np.linalg.solve(),避免显式求逆
- 特征分解:
np.linalg.eig() 返回的特征向量是列向量- 验证时用
np.allclose() 而非 ==,避免浮点误差
- 调试技巧:
- 形状错误?用
.shape 和 .ndim 快速定位 - 结果不对?用小矩阵手动验算一步
💬 写在最后
线性代数是机器学习的数学语言,掌握它,你就能:
✅ 理解神经网络的前向/反向传播原理✅ 自主实现降维、回归等核心算法✅ 读懂论文中的矩阵公式,不再"天书"
今天重点掌握:
- ✅ 矩阵乘法的形状规则与
@ 操作符 - ✅ 逆矩阵的计算条件与
solve() 的优先使用 - ✅ 特征值/特征向量的物理意义与验证方法
如果觉得有用,记得:
- 👍 点赞支持一下
- ⭐ 收藏方便复习
- 📤 分享给更多小伙伴
完成作业的同学,欢迎在评论区打卡! 💪
【一起学Python】每天进步一点点,365天后遇见更优秀的自己!
👉 关注公众号,不错过每天的学习内容!
🎯 今日金句:
"矩阵是数据的骨架,线性代数是它的灵魂。掌握运算规则,让AI算法为你所用!" 🤖✨
明天见! 🌟