当前位置:首页>python>我的Python100天打卡:67/100 Numpy线性代数练习题

我的Python100天打卡:67/100 Numpy线性代数练习题

  • 2026-10-11 08:39:36
我的Python100天打卡:67/100 Numpy线性代数练习题

#鸢尾花数学大系

挑战100天持续练习Python
今天是第67天
---

上次笔记,完成了第十七章Numpy关于几个常见的矩阵分解的知识,包括:Cholesky分解、特征值分解(EVD)、奇异值分解(SVD)。

今天的学习内容,做一下书本提供的练习题。

--

练习:

--
Q1:要解决“列向量的模、单位向量、内积、夹角 + 格拉姆矩阵关联”,需紧扣线性代数基本定义和格拉姆矩阵的定义(G = X的T次方 · X,其中 X是数据矩阵)
由于这里学习的是Python代码,因此均以代码为回答重点,不过多涉及数学公式等知识点。
1. 求列向量的模:
因为列向量是数组X的每一列,而“模”是L2范数(具体见这篇笔记关于向量运算的部分),所以用如下代码进行求解:
norms = [np.linalg.norm(col, ord=2) for col in cols]  
2. 求列向量的单位向量:
数学公式为:“向量/模长”
代码:
units = [col / norm for col, norm in zip(cols, norms)]  
3. 求两两内积:就是求两个向量的点积,而特殊的点积就是“格拉姆矩阵”(格拉姆矩阵 G = X.T @ X的 (i,j)元素恰好是第 i列与第 j列的内积)
代码:
inner_prods = np.zeros((4, 4))  for i in range(4):    for j in range(4):        inner_prods[i, j] = np.dot(cols[i], cols[j])  
4.求两两夹角:由内积公式推导,cosθ = (内积) / (模长i × 模长j),再通过 np.arccos计算弧度和角度
代码:
angles_rad = np.zeros((4, 4))  for i in range(4):    for j in range(4):        if norms[i] * norms[j] == 0:            angles_rad[i, j] = 0  # 避免除以0(实际数据无此情况)        else:            angles_rad[i, j] = np.arccos(inner_prods[i, j] / (norms[i] * norms[j]))angles_deg = np.rad2deg(angles_rad)  
--
Q2:计算格拉姆矩阵 G的第2行第3列元素
格拉姆矩阵 G = X.T @ X的 (i,j)元素是第 i列与第 j列的内积。因此,第2行第3列元素(Python 索引 [1,2])等价于第2列与第3列的内积。
代码:
# 第一种解法# 直接计算第2列(索引1)与第3列(索引2)的内积g_23 = np.dot(X[:, 1], X[:, 2])  print("G的第2行第3列元素:", g_23)  # 第二种解法:# 通过格拉姆矩阵计算# 无需手动遍历,直接用点积即可。G = X.T @ Xprint("通过G直接取值:", G[1, 2])
--
Q3:格拉姆矩阵做 Cholesky 分解并解释报错原因
1️⃣Cholesky 分解要求矩阵是 正定+对称矩阵(实对称且所有特征值 > 0)
2️⃣格拉姆矩阵 G = X.T @ X是 半正定+对称矩阵(对任意向量 z,z.T G z = ||Xz||² ≥ 0)
3️⃣若X列不满秩(如特征维度 > 样本数,或列线性相关),G存在零特征值,不满足 Cholesky 分解的“正定”要求,因此会报错。
--
Q4:对格拉姆矩阵做特征值分解,对比图17.11的特征值
看起来很唬人,但作为一个优秀的调包侠,这就是一个调用工具的事~
# 计算特征值分解eigvals, eigvecs = np.linalg.eig(G)
--
Q5:对格拉姆矩阵做特征值分解,对比图17.11的奇异值
# 计算奇异值分解U, S, VT = np.linalg.svd(A)
---
让AI帮忙整理了这几道题的代码:
import numpy as npfrom sklearn.datasets import load_irisimport matplotlib.pyplot as plt# 1. 加载鸢尾花数据iris = load_iris()X = iris.data  # 形状: (150, 4)# 2. 计算格拉姆矩阵(图17.6(a))G = X.T @ Xprint("格拉姆矩阵 G 的形状:", G.shape)print("\n格拉姆矩阵 G 的前几行前几列:")print(G[:4, :4])# 3. 对格拉姆矩阵进行特征值分解(Q4要求)eigenvalues, eigenvectors = np.linalg.eig(G)print("\n格拉姆矩阵的特征值(未排序):")print(eigenvalues)print("\n特征值之和(等于G的迹):", np.sum(eigenvalues))# 4. 对X进行奇异值分解(Q5要求)U, S, VT = np.linalg.svd(X, full_matrices=False)print("\nX的奇异值 S:")print(S)print("\n奇异值的平方 S²:")print(S**2)# 5. 比较特征值和奇异值平方的关系print("\n" + "="*60)print("特征值与奇异值平方的比较:")for i in range(4):    print(f"λ{i+1} = {eigenvalues[i]:.4f}, σ{i+1}² = {S[i]**
---
那么今天就到这里吧!
明天进行第十八章的学习!吼吼吼

---

笔记写于:2026年4月21日22:58:30

结束于:2026年4月21日23:45:03

用时:约1小时

--

#鸢尾花数学大系

#编程随记

最新文章

随机文章