Skip to content

第 11 章 向量空间、基与维数

学习目标

  • 理解向量空间与子空间的定义
  • 理解「基」与「维数」,知道坐标为什么唯一
  • 掌握列空间、行空间、零空间的含义
  • 掌握秩的概念与秩-零化度定理
  • 会用 NumPy 与 PyTorch 计算矩阵的秩

11.1 向量空间:加法和数乘「关上门」也不跑出去

第 2~5 章我们一直在「二维向量」上做加法与数乘。把视角抬高:所有二维向量组成的集合,叫 ;所有三维向量,叫

这些集合有一个共同特点:你在里面做加法、数乘,结果还在里面。任意两个二维向量相加还是二维向量,任意二维向量数乘还是二维向量——这叫「对运算封闭」。

向量空间:一个集合 ,如果定义了加法与数乘,并且满足:

  1. 对加法封闭:;
  2. 对数乘封闭:;
  3. 第 3 章列出的运算律(交换律、结合律、分配律等)全部成立,

就叫向量空间 都是向量空间;零向量必须在空间里(取 即可看出)。

子空间:向量空间 的非空子集 ,如果自己对加法与数乘也封闭,就叫 子空间

几何直觉最重要:

  • 过原点的直线是 的子空间(直线上的向量相加、数乘仍在直线上);
  • 过原点的平面是 的子空间;
  • 不过原点的直线不是子空间:直线上的向量相加后「飘」到别处,而且零向量不在直线上。

子空间

判断子空间只需三句话:含零向量吗?加法封闭吗?数乘封闭吗?

python
import matplotlib.pyplot as plt
from matplotlib import font_manager
for f in font_manager.findSystemFonts():
    if any(k in f for k in ("NotoSansCJK", "NotoSansSC", "wqy", "SimHei", "msyh", "PingFang")):
        font_manager.fontManager.addfont(f)
plt.rcParams["font.sans-serif"] = ["Noto Sans CJK SC", "WenQuanYi Zen Hei", "SimHei", "Microsoft YaHei", "PingFang SC"]
plt.rcParams["axes.unicode_minus"] = False

import numpy as np

fig, axes = plt.subplots(1, 2, figsize=(12, 5.5))
t = np.linspace(-3, 3, 100)

for ax, title, is_subspace in zip(axes, ["过原点的直线:是子空间", "不过原点的直线:不是子空间"], [True, False]):
    ax.axhline(0, color="black", linewidth=1)
    ax.axvline(0, color="black", linewidth=1)
    ax.grid(True, linestyle=":", alpha=0.5)
    ax.set_xlim(-3.5, 3.5)
    ax.set_ylim(-3.5, 3.5)
    ax.set_aspect("equal")
    b = 0 if is_subspace else 1.5
    ax.plot(t, 1.5 * t + b, color="tab:blue", linewidth=2)
    ax.scatter([0], [b], color="tab:red", zorder=3)
    ax.annotate("零向量", (0, b), textcoords="offset points", xytext=(8, 8), color="tab:red")
    ax.set_title(title)

fig.savefig("book/public/figs/fig11-subspace.png", dpi=120, bbox_inches="tight")
plt.close(fig)

11.2 基与维数

第 5 章讲了张成空间与线性无关。把两者合在一起,就得到线性代数最重要的概念:

:向量空间 的一组向量 ,如果

  1. 它们线性无关;
  2. 它们张成 (),

就称这组向量是 的一组

维数:基中向量的个数,记

基

的基不止一组:

python
import matplotlib.pyplot as plt
from matplotlib import font_manager
for f in font_manager.findSystemFonts():
    if any(k in f for k in ("NotoSansCJK", "NotoSansSC", "wqy", "SimHei", "msyh", "PingFang")):
        font_manager.fontManager.addfont(f)
plt.rcParams["font.sans-serif"] = ["Noto Sans CJK SC", "WenQuanYi Zen Hei", "SimHei", "Microsoft YaHei", "PingFang SC"]
plt.rcParams["axes.unicode_minus"] = False

import numpy as np

fig, axes = plt.subplots(1, 2, figsize=(12, 5.5))

def draw_basis(ax, b1, b2, title):
    ax.axhline(0, color="black", linewidth=1)
    ax.axvline(0, color="black", linewidth=1)
    ax.grid(True, linestyle=":", alpha=0.5)
    ax.set_xlim(-3.5, 3.5)
    ax.set_ylim(-3.5, 3.5)
    ax.set_aspect("equal")
    # 用基向量画网格,体现「张成整个平面」
    for a in range(-3, 4):
        for b in range(-3, 4):
            p = a * b1 + b * b2
            ax.scatter([p[0]], [p[1]], color="tab:orange", s=8, alpha=0.6)
    for v, c, label in [(b1, "tab:red", "b1"), (b2, "tab:blue", "b2")]:
        ax.quiver(0, 0, v[0], v[1], angles="xy", scale_units="xy", scale=1,
                  color=c, width=0.02)
        ax.annotate(label, v / 2, textcoords="offset points", xytext=(8, 6), color=c, fontsize=13)
    ax.set_title(title)

draw_basis(axes[0], np.array([1.0, 0.0]), np.array([0.0, 1.0]), "标准基 (1,0), (0,1)")
draw_basis(axes[1], np.array([1.0, 1.0]), np.array([1.0, -1.0]), "另一组基 (1,1), (1,-1)")

fig.savefig("book/public/figs/fig11-basis.png", dpi=120, bbox_inches="tight")
plt.close(fig)

都是 的基——每组都是两个不共线向量,张成整个平面。

第 5 章的关键定理在这里发光:基是线性无关的,所以空间里每个向量用基表示,方式唯一。这组唯一的系数,就是向量在该基下的坐标。坐标为什么不会「一个点两个答案」?因为基线性无关(第 5.5 的证明)。

过原点的直线是一维子空间,过原点的平面是二维子空间,整个空间 的维数是

11.3 矩阵的四个基本子空间:变换把什么送到哪里

矩阵 ,它把 维空间映射到 维空间。围绕 有四个重要的子空间:

  1. 列空间 : 的列张成的子空间。它是「变换的输出能到达的地方」,维数叫
  2. 行空间 : 的行张成的子空间,等于 。它的维数也等于秩。
  3. 零空间 :满足 的所有 。它是「被变换压扁到零的那些方向」,维数叫零化度
  4. 左零空间:满足 ,是「 维空间里列空间够不到的部分」。

最重要的结论是秩-零化度定理:

直觉:输入有 个独立方向,其中 个方向「存活」下来被输出, 个方向被压扁成零,加起来恰好是全部输入方向。

例子:

  • 两列成比例,列空间是一条直线,;
  • ,,零空间是一条直线,;
  • ✓。

11.4 用库与从零实现计算秩

python
import numpy as np

A = np.array([[1.0, 2.0],
              [2.0, 4.0]])
B = np.array([[1.0, 0.0, 1.0],
              [0.0, 1.0, 1.0],
              [0.0, 0.0, 0.0]])

print("rank(A) =", np.linalg.matrix_rank(A))
print("rank(B) =", np.linalg.matrix_rank(B))

运行输出:

text
rank(A) = 1
rank(B) = 2

PyTorch:

python
import torch

A = torch.tensor([[1.0, 2.0],
                  [2.0, 4.0]])
print("torch rank(A) =", torch.linalg.matrix_rank(A))

运行输出:

text
torch rank(A) = tensor(1)

从零实现:高斯消元后数主元个数,就是秩:

python
import numpy as np

def rank_gauss(A):
    """用高斯消元数主元个数,得到矩阵的秩"""
    M = np.array(A, dtype=float)
    rows, cols = M.shape
    rank = 0
    for col in range(cols):
        # 在未处理的行里找这一列绝对值最大的主元
        pivot = rank + np.argmax(np.abs(M[rank:, col]))
        if M[pivot, col] == 0:
            continue
        M[[rank, pivot]] = M[[pivot, rank]]
        for row in range(rank + 1, rows):
            f = M[row, col] / M[rank, col]
            M[row] -= f * M[rank]
        rank += 1
    return rank

print("rank_gauss(A) =", rank_gauss([[1.0, 2.0], [2.0, 4.0]]))
print("rank_gauss(B) =", rank_gauss([[1.0, 0.0, 1.0],
                                     [0.0, 1.0, 1.0],
                                     [0.0, 0.0, 0.0]]))

运行输出:

text
rank_gauss(A) = 1
rank_gauss(B) = 2

11.5 AI 视角:数据矩阵的秩

在机器学习里,数据常常排成一个样本 × 特征矩阵:每行是一个样本,每列是一个特征。秩的意义是:数据真正占用的独立方向有多少

比如 100 个学生,记录了「身高」和「身高 × 2」两个特征——这两列完全成比例,秩只有 1,第二个特征没有带来任何新信息。真实数据里,特征之间总是近似相关,所以秩往往远小于特征数。

「特征很多但独立方向很少」正是降维(PCA、SVD)存在的前提:把 维数据压到 个独立方向,丢掉几乎不占方向的那部分。第 14 章的奇异值分解会把这个想法做成一套完整的数学工具。

动手实践

  1. 判断下列集合是否 的子空间,并说明理由:
    • 第一象限()
    • 直线 (过原点)
    • 直线 (不过原点)
    • 只有零向量的集合
  2. 验证 的基:写出张成与线性无关的论证,再用 np.linalg.matrix_rank 确认。
  3. 的秩与零化度,验证秩-零化度定理。
  4. 找出 的解集: ,说出零空间是什么图形。
  5. rank_gaussnp.linalg.matrix_rank 计算一个 4×3 矩阵的秩,并互相验证。

常见错误

错误写法/理解原因
认为不过原点的直线也是子空间子空间必须含零向量且对加法和数乘封闭;不过原点的直线两条都不满足
认为子空间里只要有零向量就够了还要验证加法与数乘封闭,缺一不可
把「基」理解成唯一的基不唯一,但同一个空间的基,向量个数(维数)相同
认为秩是「非零元素的个数」秩是线性无关的行(列)的最大个数,即高斯消元后的主元个数
混淆列空间维数与矩阵形状列空间维数 ≤ 列数,由独立的列决定,不是行列数本身

章末练习

基础

  1. 的一组基至少有几个向量?最多呢?为什么?
  2. 判断 是否构成 的基,用行列式说明。
  3. 计算 的秩与零化度,验证

提高

  1. 中直线 上的所有向量。验证 是子空间,并写出它的一组基与维数。
  2. 证明:若 的基,则 中每个向量有唯一坐标表示(提示:用第 5.5 的反证法)。

挑战

  1. ,求秩、零空间的一组基与零化度,并解释为什么零空间只有零向量。
  2. 两个向量空间 的交集 (同时属于两者的向量)还是子空间吗?证明或举反例。

章末自测

  1. 向量空间必须满足?
    • A. 只含正向量
    • B. 对加法和数乘封闭
    • C. 所有向量长度相等
    • D. 只含整数分量
  2. 过原点的直线是 的?
    • A. 基
    • B. 子空间
    • C. 零空间
    • D. 向量
    • A.
    • B.
    • C.
    • D. 无穷大
  3. 一组基需要满足?
    • A. 线性无关且张成空间
    • B. 只张成空间
    • C. 只线性无关
    • D. 两两垂直
  4. 的基吗?
    • A. 是
    • B. 不是,因为共线
    • C. 不是,因为只有两个向量
    • D. 无法判断
  5. 矩阵的秩等于?
    • A. 行数
    • B. 列数
    • C. 列空间的维数
    • D. 元素个数
  6. 零空间是?
    • A. 的解集
    • B. 的解集
    • C. 的行向量集合
    • D. 全零矩阵
  7. 秩-零化度定理:
    • A. ( 的行数)
    • B. ( 的列数)
    • C.
    • D.
  8. 不过原点的直线不是子空间,最主要的原因是?
    • A. 不够长
    • B. 不含零向量
    • C. 方向太多
    • D. 维数太高
  9. 数据矩阵的「秩」直观上表示?
    • A. 样本个数
    • B. 特征个数
    • C. 数据真正占用的独立方向数
    • D. 数据总量