ベクトル空間の「大きさ」や「広がり」を特徴づけるのが 次元 であり、その空間の「座標系」を定めるのが 基底 です。イメージとしては、基底とは「空間の中で方向を表す最小限のベクトルの組」であり、次元はその本数のことです。
基底と次元の概念は、線形代数における最も基本的な構造を明らかにします。行列のランク、線形写像の性質、固有空間の構造など、線形代数の主要テーマはすべて基底と次元の言葉で記述されます。応用面でも、データの次元削減(PCA)、座標系の変換(ロボティクス、コンピュータグラフィックス)など、幅広い場面で活用されます。
本記事の内容
- 生成系(span)の定義
- 基底の定義(線形独立 + 生成系)
- 次元の定義と性質
- 標準基底と一般の基底
- 座標ベクトルと基底変換
- Pythonでの基底変換の実装と可視化
前提知識
この記事を読む前に、以下の記事を読んでおくと理解が深まります。
生成系(span)とは
定義
ベクトル空間 $V$ のベクトル $\bm{v}_1, \bm{v}_2, \ldots, \bm{v}_k$ の 生成する部分空間(span)を次のように定義します。
$$ \begin{equation} \mathrm{span}(\bm{v}_1, \bm{v}_2, \ldots, \bm{v}_k) = \{c_1 \bm{v}_1 + c_2 \bm{v}_2 + \cdots + c_k \bm{v}_k \mid c_i \in \mathbb{R}\} \end{equation} $$
すなわち、$\bm{v}_1, \ldots, \bm{v}_k$ のすべての線形結合の集合です。
$\mathrm{span}(\bm{v}_1, \ldots, \bm{v}_k) = V$ のとき、$\bm{v}_1, \ldots, \bm{v}_k$ は $V$ を 生成する(span する)といい、$\{\bm{v}_1, \ldots, \bm{v}_k\}$ を $V$ の 生成系 と呼びます。
直感
生成系とは「空間のすべての点を線形結合で作り出せるベクトルの組」です。$\mathbb{R}^2$ では、平行でない2本のベクトルがあれば平面全体を覆えます。3本あっても覆えますが、その場合は余分なベクトルが含まれています。
基底とは
定義
ベクトル空間 $V$ のベクトルの組 $\mathcal{B} = \{\bm{v}_1, \bm{v}_2, \ldots, \bm{v}_n\}$ が $V$ の 基底(basis)であるとは、次の2条件を同時に満たすことです。
(1) 線形独立: $c_1\bm{v}_1 + c_2\bm{v}_2 + \cdots + c_n\bm{v}_n = \bm{0} \implies c_1 = c_2 = \cdots = c_n = 0$
(2) 生成系: $\mathrm{span}(\bm{v}_1, \bm{v}_2, \ldots, \bm{v}_n) = V$
大雑把に言えば、基底は「空間を生成するのに必要な、過不足のないベクトルの組」です。
基底による一意表示
基底の重要な性質として、任意のベクトルが基底の線形結合で一意に表せる ことがあります。
定理: $\mathcal{B} = \{\bm{v}_1, \ldots, \bm{v}_n\}$ が $V$ の基底ならば、任意の $\bm{x} \in V$ に対して、
$$ \bm{x} = c_1 \bm{v}_1 + c_2 \bm{v}_2 + \cdots + c_n \bm{v}_n $$
を満たす係数 $c_1, c_2, \ldots, c_n$ が 一意に 存在する。
証明:
存在: $\mathcal{B}$ が生成系なので、$\bm{x}$ を $\bm{v}_1, \ldots, \bm{v}_n$ の線形結合で表す係数が存在します。
一意性: もう一つの表現 $\bm{x} = d_1\bm{v}_1 + \cdots + d_n\bm{v}_n$ があったとすると:
$$ \begin{align} c_1\bm{v}_1 + \cdots + c_n\bm{v}_n &= d_1\bm{v}_1 + \cdots + d_n\bm{v}_n \\ (c_1 – d_1)\bm{v}_1 + \cdots + (c_n – d_n)\bm{v}_n &= \bm{0} \end{align} $$
$\mathcal{B}$ が線形独立なので、$c_i – d_i = 0$($i = 1, \ldots, n$)、すなわち $c_i = d_i$ です。$\square$
次元の定義
定義
ベクトル空間 $V$ の 次元(dimension)とは、$V$ の基底に含まれるベクトルの本数です。これを $\dim V$ と書きます。
$$ \begin{equation} \dim V = n \iff V \text{ の基底が } n \text{ 本のベクトルからなる} \end{equation} $$
次元の一意性
「基底の選び方によって本数が変わったりしないのか?」という疑問が自然に生じます。実は、同じベクトル空間の基底は、どれも同じ本数を持つ ことが証明できます。
定理(次元の well-definedness): $V$ の2つの基底 $\{\bm{v}_1, \ldots, \bm{v}_m\}$ と $\{\bm{w}_1, \ldots, \bm{w}_n\}$ に対して $m = n$ が成り立つ。
この証明には交換補題(Steinitz exchange lemma)を使います。詳細は発展的な内容なのでここでは省略しますが、要点は「線形独立なベクトルの本数は生成系のベクトルの本数を超えない」ということです。
具体例
| ベクトル空間 | 次元 | 基底の例 |
|---|---|---|
| $\mathbb{R}^n$ | $n$ | $\{\bm{e}_1, \ldots, \bm{e}_n\}$(標準基底) |
| $P_n$($n$次以下の多項式) | $n + 1$ | $\{1, x, x^2, \ldots, x^n\}$ |
| $M_{m \times n}(\mathbb{R})$ | $mn$ | 各成分が1で他が0の行列 |
| $\{\bm{0}\}$(零空間) | $0$ | $\emptyset$ |
標準基底
$\mathbb{R}^n$ の 標準基底 とは:
$$ \bm{e}_1 = \begin{pmatrix} 1 \\ 0 \\ \vdots \\ 0 \end{pmatrix}, \quad \bm{e}_2 = \begin{pmatrix} 0 \\ 1 \\ \vdots \\ 0 \end{pmatrix}, \quad \ldots, \quad \bm{e}_n = \begin{pmatrix} 0 \\ 0 \\ \vdots \\ 1 \end{pmatrix} $$
任意の $\bm{x} = (x_1, x_2, \ldots, x_n)^T \in \mathbb{R}^n$ は:
$$ \bm{x} = x_1 \bm{e}_1 + x_2 \bm{e}_2 + \cdots + x_n \bm{e}_n $$
と一意に表せます。標準基底は計算上最も扱いやすい基底ですが、問題によっては別の基底のほうが自然な場合があります。
座標ベクトルと基底変換
座標ベクトル
基底 $\mathcal{B} = \{\bm{v}_1, \ldots, \bm{v}_n\}$ に関する $\bm{x}$ の 座標ベクトル とは、
$$ \bm{x} = c_1 \bm{v}_1 + c_2 \bm{v}_2 + \cdots + c_n \bm{v}_n $$
における係数を並べたベクトル $[\bm{x}]_\mathcal{B} = (c_1, c_2, \ldots, c_n)^T$ のことです。
基底変換行列
2つの基底 $\mathcal{B} = \{\bm{v}_1, \ldots, \bm{v}_n\}$ と $\mathcal{B}’ = \{\bm{w}_1, \ldots, \bm{w}_n\}$ があるとき、基底 $\mathcal{B}$ の座標から基底 $\mathcal{B}’$ の座標に変換する行列 $\bm{P}$ を 基底変換行列 と呼びます。
$$ \begin{equation} [\bm{x}]_{\mathcal{B}’} = \bm{P} [\bm{x}]_{\mathcal{B}} \end{equation} $$
基底変換行列の具体的な構成は次の通りです。基底 $\mathcal{B}$ のベクトルを列に並べた行列を $\bm{B}$、基底 $\mathcal{B}’$ のベクトルを列に並べた行列を $\bm{B}’$ とすると:
$$ \bm{x} = \bm{B} [\bm{x}]_\mathcal{B} = \bm{B}’ [\bm{x}]_{\mathcal{B}’} $$
よって:
$$ \begin{align} [\bm{x}]_{\mathcal{B}’} &= (\bm{B}’)^{-1} \bm{B} [\bm{x}]_\mathcal{B} \end{align} $$
したがって基底変換行列は:
$$ \begin{equation} \bm{P} = (\bm{B}’)^{-1} \bm{B} \end{equation} $$
具体例
$\mathbb{R}^2$ での基底変換
標準基底 $\mathcal{E} = \{\bm{e}_1, \bm{e}_2\}$ から新しい基底 $\mathcal{B} = \{\bm{v}_1, \bm{v}_2\}$ への変換を考えます。
$\bm{v}_1 = (1, 1)^T$, $\bm{v}_2 = (1, -1)^T$ とすると:
$$ \bm{B} = \begin{pmatrix} 1 & 1 \\ 1 & -1 \end{pmatrix} $$
標準基底での座標 $\bm{x} = (3, 1)^T$ を基底 $\mathcal{B}$ での座標に変換します。
$$ \begin{align} [\bm{x}]_\mathcal{B} &= \bm{B}^{-1} \bm{x} \\ &= \frac{1}{-2} \begin{pmatrix} -1 & -1 \\ -1 & 1 \end{pmatrix} \begin{pmatrix} 3 \\ 1 \end{pmatrix} \\ &= \frac{1}{-2} \begin{pmatrix} -4 \\ -2 \end{pmatrix} \\ &= \begin{pmatrix} 2 \\ 1 \end{pmatrix} \end{align} $$
検算: $2\bm{v}_1 + 1 \cdot \bm{v}_2 = 2(1,1)^T + (1,-1)^T = (3, 1)^T = \bm{x}$ ✓
Pythonでの実装
基底変換の実装
import numpy as np
def change_basis(x, B_from, B_to):
"""
基底 B_from での座標ベクトル x を基底 B_to での座標に変換する
Parameters
----------
x : ndarray
B_from 基底での座標ベクトル
B_from : ndarray
変換元の基底(列ベクトルを並べた行列)
B_to : ndarray
変換先の基底(列ベクトルを並べた行列)
Returns
-------
ndarray
B_to 基底での座標ベクトル
"""
# 標準座標に変換してから、新しい基底の座標に変換
x_standard = B_from @ x
x_new = np.linalg.solve(B_to, x_standard)
return x_new
# 標準基底
E = np.eye(2)
# 新しい基底
B = np.array([[1, 1],
[1, -1]], dtype=float)
# 標準座標での x
x_standard = np.array([3.0, 1.0])
# 基底 B での座標を求める
x_B = np.linalg.solve(B, x_standard)
print(f"標準座標: {x_standard}")
print(f"基底 B での座標: {x_B}")
# 検算
x_reconstructed = B @ x_B
print(f"復元: {x_reconstructed}")
print(f"一致: {np.allclose(x_standard, x_reconstructed)}")
基底変換の可視化
import numpy as np
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
# --- 標準基底での表示 ---
ax = axes[0]
# 標準基底ベクトル
ax.quiver(0, 0, 1, 0, angles='xy', scale_units='xy', scale=1,
color='gray', linewidth=1.5, label='$\\mathbf{e}_1$')
ax.quiver(0, 0, 0, 1, angles='xy', scale_units='xy', scale=1,
color='gray', linewidth=1.5, label='$\\mathbf{e}_2$')
# ベクトル x
x = np.array([3, 1])
ax.quiver(0, 0, x[0], x[1], angles='xy', scale_units='xy', scale=1,
color='black', linewidth=2, label=f'$\\mathbf{{x}} = ({x[0]}, {x[1]})$')
# 成分の分解
ax.plot([x[0], x[0]], [0, x[1]], 'k--', alpha=0.3)
ax.plot([0, x[0]], [x[1], x[1]], 'k--', alpha=0.3)
# グリッド(標準基底に沿った)
for i in range(-4, 5):
ax.axhline(y=i, color='lightgray', linewidth=0.5)
ax.axvline(x=i, color='lightgray', linewidth=0.5)
ax.set_xlim(-1, 5)
ax.set_ylim(-2, 4)
ax.set_aspect('equal')
ax.set_xlabel('$x_1$')
ax.set_ylabel('$x_2$')
ax.set_title('Standard Basis $\\mathcal{E}$: $[\\mathbf{x}]_\\mathcal{E} = (3, 1)$')
ax.legend(fontsize=9)
# --- 新しい基底での表示 ---
ax = axes[1]
# 新しい基底ベクトル
v1 = np.array([1, 1])
v2 = np.array([1, -1])
ax.quiver(0, 0, v1[0], v1[1], angles='xy', scale_units='xy', scale=1,
color='blue', linewidth=2, label='$\\mathbf{v}_1 = (1, 1)$')
ax.quiver(0, 0, v2[0], v2[1], angles='xy', scale_units='xy', scale=1,
color='red', linewidth=2, label='$\\mathbf{v}_2 = (1, -1)$')
# ベクトル x
ax.quiver(0, 0, x[0], x[1], angles='xy', scale_units='xy', scale=1,
color='black', linewidth=2, label=f'$\\mathbf{{x}} = ({x[0]}, {x[1]})$')
# 成分の分解(新しい基底に沿って)
# x = 2*v1 + 1*v2
ax.quiver(0, 0, 2*v1[0], 2*v1[1], angles='xy', scale_units='xy', scale=1,
color='blue', linewidth=1, alpha=0.4)
ax.quiver(2*v1[0], 2*v1[1], v2[0], v2[1], angles='xy', scale_units='xy', scale=1,
color='red', linewidth=1, alpha=0.4)
# グリッド(新しい基底に沿った)
for i in range(-4, 5):
for j in range(-4, 5):
p = i * v1 + j * v2
if -1 <= p[0] <= 5 and -2 <= p[1] <= 4:
ax.plot(p[0], p[1], '.', color='lightblue', markersize=3)
ax.set_xlim(-1, 5)
ax.set_ylim(-2, 4)
ax.set_aspect('equal')
ax.set_xlabel('$x_1$')
ax.set_ylabel('$x_2$')
ax.set_title('Basis $\\mathcal{B}$: $[\\mathbf{x}]_\\mathcal{B} = (2, 1)$')
ax.legend(fontsize=9)
plt.tight_layout()
plt.savefig("basis_change.png", dpi=150, bbox_inches='tight')
plt.show()
次元の確認
import numpy as np
# 様々なベクトル空間の次元をランクで確認する
# R^3 の部分空間の次元
print("=== R^3 の部分空間の次元 ===")
# 3本の線形独立なベクトル → 3次元
v1 = np.array([1, 0, 0])
v2 = np.array([0, 1, 0])
v3 = np.array([0, 0, 1])
A = np.column_stack([v1, v2, v3])
print(f"v1, v2, v3 の張る空間の次元: {np.linalg.matrix_rank(A)}")
# 2本の線形独立なベクトル → 2次元(平面)
v1 = np.array([1, 1, 0])
v2 = np.array([0, 1, 1])
A = np.column_stack([v1, v2])
print(f"v1, v2 の張る空間の次元: {np.linalg.matrix_rank(A)}")
# 3本だが線形従属 → 2次元
v1 = np.array([1, 1, 0])
v2 = np.array([0, 1, 1])
v3 = np.array([1, 2, 1]) # v3 = v1 + v2
A = np.column_stack([v1, v2, v3])
print(f"v1, v2, v3(従属)の張る空間の次元: {np.linalg.matrix_rank(A)}")
# 1本のベクトル → 1次元(直線)
v1 = np.array([2, 3, 1])
A = v1.reshape(-1, 1)
print(f"v1 の張る空間の次元: {np.linalg.matrix_rank(A)}")
# 多項式空間 P_2 の次元(係数ベクトルで表現)
print("\n=== P_2 の次元 ===")
# 基底 {1, x, x^2} → 係数ベクトル (a0, a1, a2)
basis_P2 = np.eye(3)
print(f"P_2 の次元: {np.linalg.matrix_rank(basis_P2)}")
# M_{2x2} の次元
print("\n=== M_{2x2} の次元 ===")
# 基底: E11, E12, E21, E22(各成分が1で他が0)
basis_M = np.eye(4)
print(f"M_{{2x2}} の次元: {np.linalg.matrix_rank(basis_M)}")
まとめ
本記事では、基底と次元の定義について解説しました。
- 生成系 は、線形結合で空間全体を覆えるベクトルの組である
- 基底 は、線形独立かつ生成系であるベクトルの組で、空間を表す「最小限の座標系」である
- 次元 は基底のベクトルの本数であり、基底の選び方によらず一定である
- 基底を決めると、任意のベクトルは座標ベクトルで 一意に 表現できる
- 基底変換行列 $\bm{P} = (\bm{B}’)^{-1}\bm{B}$ で異なる基底間の座標を変換できる
次のステップとして、以下の記事も参考にしてください。