機械学習や統計学を学んでいると、正定値行列(positive definite matrix)や半正定値行列(positive semi-definite matrix)という用語が頻繁に登場します。共分散行列、カーネル行列、ヘッセ行列などの重要な行列はいずれも正定値性(または半正定値性)を持ち、この性質が理論の根幹を支えています。
本記事では、正定値行列の定義から始めて、性質や判定法を丁寧に解説し、Pythonでの具体的な確認方法まで紹介します。
本記事の内容
- 正定値行列・半正定値行列の定義
- 固有値との関係
- 正定値性の判定法
- 具体例とPythonでの実装
正定値行列の定義
正定値行列
$n \times n$ の対称行列 $\bm{A}$ が正定値(positive definite)であるとは、すべての非零ベクトル $\bm{x} \in \mathbb{R}^n \setminus \{\bm{0}\}$ に対して、
$$ \bm{x}^\top \bm{A} \bm{x} > 0 $$
が成り立つことをいいます。これを $\bm{A} \succ 0$ と書きます。
半正定値行列
$n \times n$ の対称行列 $\bm{A}$ が半正定値(positive semi-definite)であるとは、すべてのベクトル $\bm{x} \in \mathbb{R}^n$ に対して、
$$ \bm{x}^\top \bm{A} \bm{x} \geq 0 $$
が成り立つことをいいます。これを $\bm{A} \succeq 0$ と書きます。
直感的な理解
2次形式 $q(\bm{x}) = \bm{x}^\top \bm{A} \bm{x}$ は、$n$ 次元空間上のスカラー関数です。
- $\bm{A}$ が正定値ならば、$q(\bm{x})$ は原点で唯一の最小値0を取る「お椀型」の曲面になります
- $\bm{A}$ が半正定値ならば、$q(\bm{x}) \geq 0$ だが、$\bm{x} \neq \bm{0}$ でも $q(\bm{x}) = 0$ となる方向が存在しうる
固有値との関係
正定値性は固有値で完全に特徴づけられます。
対称行列 $\bm{A}$ の固有値を $\lambda_1, \lambda_2, \dots, \lambda_n$ とすると、
$$ \bm{A} \succ 0 \iff \lambda_i > 0 \quad \forall i $$
$$ \bm{A} \succeq 0 \iff \lambda_i \geq 0 \quad \forall i $$
導出
対称行列 $\bm{A}$ はスペクトル分解(固有値分解)できます。
$$ \bm{A} = \bm{P} \bm{\Lambda} \bm{P}^\top $$
ここで、$\bm{P}$ は直交行列($\bm{P}^\top \bm{P} = \bm{I}$)、$\bm{\Lambda} = \text{diag}(\lambda_1, \dots, \lambda_n)$ は固有値の対角行列です。
$\bm{y} = \bm{P}^\top \bm{x}$ と置くと($\bm{x} \neq \bm{0}$ のとき $\bm{y} \neq \bm{0}$)、
$$ \bm{x}^\top \bm{A} \bm{x} = \bm{x}^\top \bm{P} \bm{\Lambda} \bm{P}^\top \bm{x} = \bm{y}^\top \bm{\Lambda} \bm{y} = \sum_{i=1}^{n} \lambda_i y_i^2 $$
全ての $\lambda_i > 0$ ならば、$\bm{y} \neq \bm{0}$ のとき $\sum \lambda_i y_i^2 > 0$ です。逆に、$\lambda_k \leq 0$ となる固有値が存在すれば、対応する固有ベクトルの方向で $\bm{x}^\top \bm{A} \bm{x} \leq 0$ となります。
正定値行列の性質
基本的な性質
$\bm{A}, \bm{B}$ が正定値行列のとき、
- 対角成分が正: $a_{ii} > 0 \quad \forall i$
- 正の行列式: $\det(\bm{A}) > 0$
- 正の固有値: すべての固有値が正
- 正のスカラー倍: $c > 0$ のとき $c\bm{A}$ も正定値
- 和: $\bm{A} + \bm{B}$ も正定値
- 逆行列: $\bm{A}^{-1}$ も正定値
- コレスキー分解可能: $\bm{A} = \bm{L}\bm{L}^\top$($\bm{L}$ は下三角行列)
シルベスターの判定法
対称行列 $\bm{A}$ が正定値であるための必要十分条件は、すべての首座小行列式が正であることです。
$$ a_{11} > 0, \quad \begin{vmatrix} a_{11} & a_{12} \\ a_{21} & a_{22} \end{vmatrix} > 0, \quad \begin{vmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{vmatrix} > 0, \quad \dots $$
具体例
2×2の正定値行列
$$ \bm{A} = \begin{pmatrix} 2 & 1 \\ 1 & 3 \end{pmatrix} $$
2次形式を計算すると、
$$ \bm{x}^\top \bm{A} \bm{x} = 2x_1^2 + 2x_1 x_2 + 3x_2^2 $$
固有値を求めます。
$$ \det(\bm{A} – \lambda \bm{I}) = (2 – \lambda)(3 – \lambda) – 1 = \lambda^2 – 5\lambda + 5 = 0 $$
$$ \lambda = \frac{5 \pm \sqrt{5}}{2} $$
$\lambda_1 \approx 3.618 > 0$, $\lambda_2 \approx 1.382 > 0$ なので、$\bm{A}$ は正定値です。
Pythonでの実装
正定値行列の判定と2次形式の可視化を行います。
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
def is_positive_definite(A):
"""行列が正定値かどうかを固有値で判定"""
eigenvalues = np.linalg.eigvalsh(A)
return np.all(eigenvalues > 0), eigenvalues
# テスト行列
matrices = {
'Positive Definite': np.array([[2, 1], [1, 3]]),
'Positive Semi-Definite': np.array([[1, 1], [1, 1]]),
'Indefinite': np.array([[1, 2], [2, 1]]),
}
for name, A in matrices.items():
is_pd, eigenvalues = is_positive_definite(A)
print(f"{name}: eigenvalues = {eigenvalues}, positive definite = {is_pd}")
# 2次形式の可視化
fig, axes = plt.subplots(1, 3, figsize=(15, 5), subplot_kw={'projection': '3d'})
x1 = np.linspace(-2, 2, 100)
x2 = np.linspace(-2, 2, 100)
X1, X2 = np.meshgrid(x1, x2)
for ax, (name, A) in zip(axes, matrices.items()):
# 2次形式 x^T A x の計算
Z = A[0,0]*X1**2 + (A[0,1]+A[1,0])*X1*X2 + A[1,1]*X2**2
ax.plot_surface(X1, X2, Z, cmap='viridis', alpha=0.8)
ax.set_xlabel('$x_1$')
ax.set_ylabel('$x_2$')
ax.set_zlabel('$x^T A x$')
ax.set_title(name, fontsize=10)
plt.suptitle('Quadratic Forms: $q(x) = x^T A x$', fontsize=13)
plt.tight_layout()
plt.show()
# コレスキー分解の実装
A = np.array([[4, 2, 1],
[2, 5, 3],
[1, 3, 6]], dtype=float)
print(f"\n行列 A:\n{A}")
is_pd, eigenvalues = is_positive_definite(A)
print(f"固有値: {eigenvalues}")
print(f"正定値: {is_pd}")
# NumPyのコレスキー分解
L = np.linalg.cholesky(A)
print(f"\nコレスキー分解 L:\n{L}")
print(f"L @ L^T:\n{L @ L.T}")
print(f"A と L@L^T の差のノルム: {np.linalg.norm(A - L @ L.T):.2e}")
3Dプロットで、正定値行列の2次形式が「お椀型」(原点が最小値)、不定行列では「鞍型」になることが視覚的に確認できます。
まとめ
本記事では、正定値行列の定義と性質について解説しました。
- 正定値行列は全ての非零ベクトルに対して $\bm{x}^\top \bm{A} \bm{x} > 0$ を満たす対称行列である
- 正定値性は全ての固有値が正であることと同値である
- 正定値行列はコレスキー分解が可能であり、数値計算で重要な役割を果たす
- 共分散行列、カーネル行列、ヘッセ行列など、機械学習の多くの場面で正定値性が要求される