「eigenvalue」は統計データ分析の文脈で扱う重要概念のひとつ。 本ページでは「eigenvalue」を取り巻く中核キーワードを以下にチップで一覧化する。 各キーワードは関連する概念・手法・道具立てを含み、 文献検索や学習計画の起点になる。
これらのキーワードは「eigenvalue の理解 → 適用 → 検証」のプロセスを構成する。 各章で詳しく解説する。
🍰 まずはやさしく
行列にとっての特別な軸のことです。
データの広がりを調べるために使います。
スマホのデータ分析などで役立ちます。
まずは結論から簡単に説明します。
(A + A.T) / 2)を試すか、 元データに誤差がないか確認。 動的システム解析では複素固有値は「振動成分」を表すので、 そのまま扱う場合もある。scipy.sparse.linalg.eigs)でランチョス法を使い、 上位 k 個だけ計算。 全 n 個を計算する必要はないことが多い。 SSDSE では小規模なので不要だが、 グラフラプラシアン(数百万ノード)では必須。🍰 まずはやさしく
データの主軸を見つける道具です。
複雑なデータの構造を出すために使います。
都道府県の人口データなどで考えます。
このページで計算方法を学びます。
「固有値・固有ベクトル」は、 行列の「主軸」を見つける道具です。 SSDSE-B-2026 の 47 都道府県 × 多変数データから共分散行列 $\Sigma$ を作り、 その固有分解 $\Sigma = Q\Lambda Q^\top$ を計算すると、 大きい固有値の方向に「人口規模軸」「人口動態軸」が現れます。 これが 主成分分析 の正体。 本ページでは、 SSDSE 共分散行列の固有値を実際に計算し、 都道府県データの構造を露わにします。
🍰 まずはやさしく
データの形を決める骨組みのようなものです。
自然な軸を見つけて整理するために使います。
部活の成績など複数の項目をまとめます。
図を使って直感的に解説します。
イメージ 1: 主軸。 楕円形のデータ雲を考えてください。 長軸と短軸(互いに直交する 2 方向)がデータの「主軸」。 共分散行列の固有ベクトルが、 まさにこの主軸の方向。 固有値が、 各方向のデータの広がり(分散)。
イメージ 2: 引き伸ばし装置。 行列 $A$ をベクトルに掛けると、 多くは向きが変わる。 ところがある特別な向き $v$ では「ちょうど $\lambda$ 倍に伸びるだけ」になる。 この $v$ が固有ベクトル、 $\lambda$ が固有値。
イメージ 3: 都道府県データの主軸。 SSDSE-B の共分散行列を固有分解すると、 第 1 固有ベクトル ≒「総人口・出生数・婚姻件数・一般診療所数・延べ宿泊者数といった規模系指標が同じ向きにそろう軸」。 つまり 県の規模軸。 第 2 軸は「都市部 vs 地方」の対比軸になることが多い。 なお GDP(県内総生産)のような経済規模の代表指標は SSDSE-B-2026 には含まれない点に注意。
$2\times2$ 行列 $A=\begin{pmatrix}a&b\\c&d\end{pmatrix}$ の 4 成分をスライダーで動かしてみましょう。 灰色の 単位円 が行列変換でどんな 楕円 に写るか、 そして 固有ベクトルの方向(変換で向きが変わらない方向) がどこかを、 リアルタイムで確かめられます。 オレンジのベクトルは ドラッグで動かせます(スマホは指でなぞる)。 固有ベクトルの向きに重ねると、 変換後の緑ベクトル $A\mathbf{v}$ がぴったり同じ向き($\lambda$ 倍に伸縮するだけ)になるのを体感してください。
試してほしいこと: (1)「対称にする」を押すと $b=c$ となり、 2 本の赤い固有ベクトルが必ず 直交 します(共分散行列と同じ性質)。 (2)「回転」を押すと固有値が複素数になり、 実数の固有ベクトルが存在しない(どの向きも回転してしまう)ことが分かります。 (3) オレンジのベクトルを赤い線に重ねると、 緑の $A\mathbf{v}$ が同じ向きに一直線になり、 その長さの比がちょうど固有値 $\lambda$ になります。
意味(方向の保存と伸縮)。 一般のベクトル $\mathbf{v}$ に行列 $A$ を掛けると、 向きと長さの両方が変わります(オレンジ→緑で向きがズレる)。 しかし特別な向き=固有ベクトル $\mathbf{v}$ に対してだけは $A\mathbf{v}=\lambda\mathbf{v}$ となり、 向きは変わらず長さだけ $\lambda$ 倍になります。 これがデモで「赤い線の上にオレンジを重ねると緑が一直線になる」現象の正体です。 $\lambda$ が負なら向きは反転し($180°$)、 それでも「同じ直線上」なので固有ベクトルです。
特性方程式($2\times2$ の求め方)。 $A\mathbf{v}=\lambda\mathbf{v}$ すなわち $(A-\lambda I)\mathbf{v}=\mathbf 0$ が非零解を持つ条件は $\det(A-\lambda I)=0$。 $2\times2$ では
$$ \det\!\begin{pmatrix} a-\lambda & b \\ c & d-\lambda \end{pmatrix} = \lambda^2 - (a+d)\lambda + (ad-bc) = \lambda^2 - (\mathrm{tr}\,A)\,\lambda + \det A = 0 $$解の公式より $\displaystyle \lambda = \frac{\mathrm{tr}\,A \pm \sqrt{(\mathrm{tr}\,A)^2 - 4\det A}}{2}$。 判別式 $D=(\mathrm{tr}\,A)^2-4\det A$ が $D\ge0$ なら実固有値、 $D<0$ なら複素共役の固有値(デモの「回転」がこれ)。 固有ベクトルは $(a-\lambda)v_x+b\,v_y=0$ を解いて $\mathbf{v}\propto(b,\ \lambda-a)$、 または $\mathbf{v}\propto(\lambda-d,\ c)$ で得られます(デモも数値的に安定な方を選んで計算)。
対称行列の性質。 $b=c$($A^\top=A$)にすると、 判別式は $D=(a-d)^2+4b^2\ge0$ となり 必ず実固有値。 さらに 2 つの固有ベクトルは 直交 します(スペクトル定理)。 デモの「対称にする」で赤い 2 本が直角に交わるのがこれ。 共分散行列 $\Sigma$ はつねに対称かつ半正定値なので、 固有値は実数かつ非負、 固有ベクトルは直交基底になります。
主成分分析(PCA) は、 データの 共分散行列の固有値分解そのもの です。 $\Sigma=Q\Lambda Q^\top$ と分解したとき、 固有ベクトル($Q$ の各列)が 主成分の方向(主軸)、 対応する固有値 $\lambda_k$ が その軸方向の分散 になります。 デモの「変換後の楕円」を「データ雲」だと思えば、 赤い固有ベクトルが楕円の長軸・短軸、 固有値がそれぞれの広がり。 寄与率 $c_k=\lambda_k/\sum_i\lambda_i$ で「その軸が全分散の何割を説明するか」が分かり、 大きい固有値の軸だけ残せば 次元削減 になります。
🍰 まずはやさしく
数式で決めた特別な方向と倍率のことです。
計算で正確な軸を出すために使います。
買い物などの数値データを分析します。
定義と計算式について詳しく読みます。
正方行列 $A\in\mathbb{R}^{n\times n}$ に対して、 $v\neq 0$ と $\lambda\in\mathbb{C}$ が以下を満たすとき:
$$ A v = \lambda v $$$v$ を $\lambda$ に対応する 固有ベクトル、 $\lambda$ を 固有値 と呼びます。 $\lambda$ は特性方程式 $\det(A - \lambda I) = 0$ の解。
対称行列 $A^\top = A$(共分散行列など)の場合、 すべての固有値は実数、 固有ベクトルは直交基底を成し、 次のように対角化できる:
$$ A = Q \Lambda Q^\top,\quad Q^\top Q = I,\quad \Lambda = \mathrm{diag}(\lambda_1, \ldots, \lambda_n) $$これが 固有値分解。 半正定値ならすべて $\lambda_i\ge 0$、 正定値なら $\lambda_i>0$。
関連する事実:
行列 $A$ は線形変換、 固有ベクトルは「変換しても向きが変わらない方向」、 固有値は「その方向の伸び率」。 SSDSE の共分散行列 $\Sigma$ の場合、 楕円のデータ雲を考えると:
$\det\Sigma = \lambda_1\lambda_2$ は楕円の面積に比例。 $\mathrm{tr}\,\Sigma = \lambda_1+\lambda_2$ は「全分散」。 SSDSE-B の 3 変数例(総人口・一般診療所数・合計特殊出生率、 標準化済み)では全分散の 80% が PC1 軸に集中する。
固有値分解は正方行列専用ですが、 一般のデータ行列 $X\in\mathbb{R}^{m\times n}$ に対しては SVD が使えます。 両者は深く関係しています。
$$ X = U\Sigma V^\top,\quad X^\top X = V\Sigma^2 V^\top,\quad XX^\top = U\Sigma^2 U^\top $$つまり SVD の特異値 $\sigma_i$ は $X^\top X$ の固有値の平方根。 PCA でも実際は SVD を内部で使うことで、 共分散行列を作らずに直接処理しています(数値的に安定)。
| 概念 | 固有値分解 | SVD |
|---|---|---|
| 対象 | 正方行列 | 任意の行列 |
| スカラー値 | 固有値 $\lambda$ | 特異値 $\sigma \ge 0$ |
| 関係 | 対称半正定値 | $\lambda_i = \sigma_i^2$ |
| 数値安定性 | 普通 | 高い |
約 110 次元の SSDSE データを 2-3 次元に。 視覚化・後段モデルの高速化。
グラフラプラシアン $L = D - W$ の小さい固有値の固有ベクトルでクラスタリング。 都道府県を「近隣関係」だけで分類できる。
Web ページの遷移行列 $A$ の最大固有値に対応する固有ベクトルがランクスコア。
SSDSE で $X^\top X$ の最小固有値が $\approx 0$ なら、 「総人口 ≒ 年少人口 + 生産年齢人口 + 高齢人口」のような線形従属関係が潜む。
PCA で再構成誤差が大きい点を異常値として検出。 沖縄・東京が外れ値として浮上することが多い。
Q1. 固有値が複素数になることは?
非対称行列ではあり得る(例:回転行列)。 統計の共分散行列は対称なので、 必ず実数。 さらに半正定値なので非負。
Q2. eigh と svd は同じ?
標準化済みデータでは関係が深い:$X = U\Sigma V^\top$ なら $X^\top X = V\Sigma^2 V^\top$、 つまり PCA の固有値は SVD の特異値の二乗。 数値安定性は SVD の方が高い。
Q3. 何個の主成分を残すべき?
累積寄与率 80-90%、 スクリープロットの「肘」、 Kaiser 基準(固有値 > 1)など複数の指標を組み合わせる。 SSDSE では上位 3-5 軸でだいたい説明可能。
Q4. なぜ「対称行列の固有ベクトルは直交」?
スペクトル定理による。 これによって PCA の主成分は互いに無相関(直交)になり、 「独立な軸」として解釈できる。
[::-1] で反転。固有値方程式:$$A \mathbf{v} = \lambda \mathbf{v}$$
特性多項式:$$\det(A - \lambda I) = 0$$
スペクトル分解(対称行列):$$A = Q \Lambda Q^T$$
特異値分解(SVD):$$X = U \Sigma V^T$$
トレース・行列式の固有値表現:$$\text{tr}(A) = \sum_i \lambda_i, \quad \det(A) = \prod_i \lambda_i$$
PCA の寄与率:$$c_k = \frac{\lambda_k}{\sum_i \lambda_i}$$
累積寄与率:$$C_k = \sum_{i=1}^k c_i$$
共分散行列:$$\Sigma = \frac{1}{n-1} X^T X$$
パワー法の収束:$$\mathbf{v}_{k+1} = \frac{A \mathbf{v}_k}{\|A \mathbf{v}_k\|} \to \mathbf{v}_{\max}$$
条件数:$$\kappa(A) = \frac{\lambda_{\max}}{\lambda_{\min}}$$
| 記号 | 読み方 | 意味 |
|---|---|---|
| $\lambda$ | ラムダ | 固有値(スカラー) |
| $v$ | ブイ | 固有ベクトル(非零) |
| $\Lambda$ | ラムダ大 | 固有値の対角行列 |
| $Q$ | キュー | 固有ベクトルを列に並べた直交行列 |
| $\Sigma$ | シグマ | 共分散行列(対称半正定値) |
| $\det(A-\lambda I)$ | 特性多項式 | この方程式の解 = 固有値 |
| $\lambda_i/\sum\lambda$ | 寄与率 | 第 $i$ 主成分の説明力 |
固有値分解の式 \( A\mathbf{v} = \lambda\mathbf{v} \) を 4 つの要素に分けて読み解きます。 この式は「行列 A を固有ベクトル v に作用させると、 v の向きは変わらず、 大きさだけが λ 倍される」という性質を表します。 固有値分解は主成分分析(PCA)・スペクトラルクラスタリング・グラフ理論など、 多変量データ解析の基礎中の基礎です。 SSDSE-B-2026 の 47 都道府県 × 5 指標から「日本全体の本質的な軸」を抽出する PCA で、 共分散行列の固有値分解が中心的な役割を果たします。
要素 ①「行列 A(変換)」:A は \( n \times n \) の正方行列で、 「ベクトル空間における線形変換」を表します。 SSDSE-B-2026 の (5, 5) 共分散行列は、 5 指標間の関係性を表す A です。 A の各要素 \( A_{ij} \) は、 指標 i と指標 j の共分散を示します。 行列の対称性(\( A = A^T \))が成り立つとき、 固有値は実数で固有ベクトルは直交化可能、 という強い性質を持ちます。 共分散行列は対称なので、 PCA は数学的に綺麗に進みます。
要素 ②「固有ベクトル v(不変軸)」:v は A による変換で 向きが変わらない特別なベクトル。 SSDSE-B-2026 の共分散行列の第 1 固有ベクトルは、 5 指標空間で「データのばらつきが最大になる方向」を指します。 たとえば「県の規模 = 総人口 + 年少人口 + 出生数」のような複合指標を表す方向です。 固有ベクトルは 単位ベクトルに正規化されるのが慣例(\( \|\mathbf{v}\| = 1 \))。
要素 ③「固有値 λ(伸縮率)」:λ は v 方向で A がベクトルを 何倍に伸縮するかを示すスカラー。 SSDSE-B-2026 の共分散行列の第 1 固有値は、 第 1 固有ベクトル方向のデータの 分散を示します。 λ が大きいほど「その方向にデータが広く分布している」ことを意味し、 λ の総和は元の指標の分散総和(行列の トレース)に等しくなります。 「λ_i / Σλ」が 寄与率で、 PCA で軸の重要度を測る基準。
要素 ④「等式 = の意味(不変性)」:式 \( A\mathbf{v} = \lambda\mathbf{v} \) は「A v と λv が同じベクトル」、 つまり「v の向きを変えずに λ 倍に伸縮するだけ」を意味します。 一般のベクトル w に対しては \( A\mathbf{w} \) は w と異なる方向を向きますが、 固有ベクトルだけが「変換の不変軸」になります。 SSDSE-B-2026 で 47 県の 5 指標データを共分散行列で変換すると、 第 1 固有ベクトル方向は変換後もそのままで、 λ_1 倍に伸ばされます。 これが「データの本質的な軸」と呼ばれる理由です。
固有値は 特性方程式 \( \det(A - \lambda I) = 0 \) の解として求まります。 (2, 2) 行列なら \( \lambda^2 - \text{tr}(A)\lambda + \det(A) = 0 \) という 2 次方程式。 (n, n) 行列なら一般に n 次方程式となり、 解析解は n ≤ 4 でのみ存在(Galois 理論)。 n ≥ 5 では QR 法・パワー法などの数値計算アルゴリズムで近似的に求めます。 SSDSE-B-2026 の (5, 5) 共分散行列なら、 numpy の np.linalg.eig が内部で LAPACK の dgeev ルーチン(QR 法)を呼び出します。
対称行列 \( A = A^T \) は、 必ず以下を満たします:(1) 固有値はすべて実数、 (2) 異なる固有値の固有ベクトルは直交、 (3) 直交行列 Q と対角行列 Λ を用いて \( A = Q\Lambda Q^T \) と分解可能。 これがスペクトル定理です。 SSDSE-B-2026 の共分散行列はこの恩恵を受け、 PCA で得られる軸は直交し、 寄与率(固有値の比)が綺麗に解釈できます。 非対称行列では複素固有値が出現する可能性があり、 解釈が難しくなります。
PCA は「データの分散が最大になる直交軸を順に取る」次元削減手法で、 数学的には共分散行列の固有値分解と等価です。 SSDSE-B-2026 の (47, 5) データから共分散行列 \( C = \frac{1}{n-1}X^T X \)(X はセンタリング済)を計算し、 \( C = V\Lambda V^T \) と分解。 V の列が主成分軸、 Λ の対角要素が各主成分の分散(固有値)。 第 k 主成分の寄与率は \( \lambda_k / \sum_i \lambda_i \)。 SSDSE-B では第 1 主成分が「都市規模」、 第 2 主成分が「出生率などの人口動態」を表すことが多い。
特異値分解 \( X = U\Sigma V^T \) は、 固有値分解の一般化(任意の m×n 行列に適用可能)です。 PCA は SVD で計算するのが数値的に安定(共分散行列を経由しないため誤差が小さい)。 SSDSE-B-2026 の X (47, 5) を直接 SVD すると、 V の列が主成分軸、 Σ の対角の二乗 / (n-1) が共分散行列の固有値に等しい。 sklearn の PCA は内部で SVD を使う設計。
パワー法は「最大固有値だけ知りたい」場合の超高速アルゴリズム:(1) ランダム初期ベクトル \( v_0 \)、 (2) 反復 \( v_{k+1} = Av_k / \|Av_k\| \)、 (3) 収束したら最大固有ベクトル。 計算量は O(n²) per iteration、 全固有値計算の O(n³) より圧倒的に速い。 Google の PageRank アルゴリズムは、 Web の遷移行列の最大固有ベクトルをパワー法で求めるもの。 SSDSE の都道府県間関係を表すグラフでも同様に応用可能。
グラフのクラスタリングは、 ラプラシアン行列 \( L = D - W \)(D は次数対角行列、 W は隣接行列)の小さい固有値の固有ベクトルでクラスタを抽出する手法。 SSDSE-B-2026 で 47 都道府県を「人口・家計消費・教育」の類似度でグラフ化し、 ラプラシアンの第 2-第 4 固有ベクトルで kmeans すれば、 「大都市群」「地方都市群」「過疎地域群」のような自然なクラスタが浮かび上がります。
行列の条件数 \( \kappa(A) = \lambda_{\max} / \lambda_{\min} \) は、 線形方程式 Ax = b の解 x がデータ b の誤差に対してどれくらい敏感かを示します。 SSDSE-B-2026 のように高度に相関した指標を含むデータは、 共分散行列の条件数が大きくなり(多重共線性)、 回帰係数の推定が不安定化します。 対策:① 主成分回帰、 ② Ridge 回帰、 ③ 変数選択。
非対称行列では固有値が複素数になることがあります。 たとえば回転行列 \( R(\theta) \) の固有値は \( e^{\pm i\theta} \)。 動的システムの解析(マルコフ連鎖の遷移行列、 状態空間モデル)では複素固有値が「周期的振動」を表します。 SSDSE-B-2026 の通常分析では対称な共分散行列を使うので複素数は出現しませんが、 「都道府県間の遷移確率行列」を扱う際は注意が必要。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn.decomposition import PCA # 1) SSDSE-B-2026 読み込み(2023 年度・47 都道府県に絞る) df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] features = ['A1101', 'A1303', 'A1301', 'A4101', 'A4103'] # 5 指標(総人口・高齢人口・年少人口・出生数・合計特殊出生率) X = df[features].values prefs = df['Prefecture'].values # 2) 標準化(PCA の前処理。 単位の違いを吸収) X_centered = (X - X.mean(axis=0)) / X.std(axis=0, ddof=1) # 3) 共分散行列(標準化後なので相関行列と同義。 5x5 対称行列) cov_mat = np.cov(X_centered.T) print(f'共分散行列 shape: {cov_mat.shape}') print(f'共分散行列:\n{cov_mat}') # 4) 固有値分解 eigenvalues, eigenvectors = np.linalg.eigh(cov_mat) # eigh: 対称行列用 # eigh は昇順で返すので降順に並び替え idx = eigenvalues.argsort()[::-1] eigenvalues = eigenvalues[idx] eigenvectors = eigenvectors[:, idx] print(f'\n[固有値(降順)]') for i, lam in enumerate(eigenvalues): print(f' λ_{i+1} = {lam:.3e}') # 5) 寄与率 contributions = eigenvalues / eigenvalues.sum() cumulative = np.cumsum(contributions) print(f'\n[寄与率]') for i, c in enumerate(contributions): print(f' PC{i+1}: 寄与率 {c*100:.1f}%, 累積 {cumulative[i]*100:.1f}%') # 6) 第 1・第 2 主成分への射影 PC = X_centered @ eigenvectors[:, :2] print(f'\n[第 1 主成分(PC1)が極端な県]') for i in PC[:, 0].argsort()[-3:][::-1]: print(f' {prefs[i]}: PC1 = {PC[i, 0]:.2e}') for i in PC[:, 0].argsort()[:3]: print(f' {prefs[i]}: PC1 = {PC[i, 0]:.2e}') # 7) sklearn PCA との一致確認 pca = PCA(n_components=2) PC_sklearn = pca.fit_transform(X_centered) print(f'\n[sklearn PCA 寄与率] {pca.explained_variance_ratio_}') # 8) パワー法で最大固有値を計算(検算) def power_iteration(A, n_iter=100): v = np.random.rand(A.shape[0]) v /= np.linalg.norm(v) for _ in range(n_iter): v = A @ v v /= np.linalg.norm(v) lam = v.T @ A @ v return lam, v lam_max, v_max = power_iteration(cov_mat) print(f'\n[パワー法による最大固有値] {lam_max:.3e}') print(f'[直接計算との誤差] {abs(lam_max - eigenvalues[0]):.3e}') |
SSDSE-B-2026 の 5 指標(標準化済み)から共分散行列を作り、 固有値分解で主成分軸を抽出。 実データ(2023 年度)では第 1 主成分の寄与率が 86.6% となり、 「人口規模軸(都市規模軸)」として解釈できる。
| 手法 | 対象行列 | 使う固有値 | 解釈 |
|---|---|---|---|
| PCA(主成分分析) | 共分散行列 | 大きい順 | 分散最大軸 |
| 因子分析 | 相関行列 | 1 以上 | 潜在因子 |
| スペクトラルクラスタリング | グラフラプラシアン | 小さい順(0 除く) | クラスタ構造 |
| PageRank | 遷移行列 | 最大(=1) | ページ重要度 |
| マルコフ連鎖 | 遷移行列 | 最大(=1) | 定常分布 |
| 構造方程式モデル | 共分散構造 | パラメータ推定 | 因果パス |
| 画像圧縮(SVD) | 画像行列 | 上位 k 個の特異値 | 画像の主要成分 |
np.linalg.eigh。 LAPACK の dsyevr を呼ぶ)SSDSE-B-2026 の 5 指標(総人口・高齢人口・年少人口・出生数・合計特殊出生率)から固有値分解で都道府県を分類。 5 ステップで段階的に解説。
SSDSE-B-2026 から 5 列抽出。 各指標の単位が違うので Z-score 標準化((x - mean) / std)で揃える。 標準化後の共分散行列は 相関行列と一致。
5×5 の対称行列が得られる。 対角要素は分散(標準化後は 1)、 非対角要素は相関係数(-1〜+1)。 たとえば「総人口」と「出生数」の相関は実測で 0.995(非常に強い)。
np.linalg.eigh で対称行列の固有値・固有ベクトルを取得。 5 つの固有値が降順で得られる。 実測結果(2023 年度):λ₁=4.33, λ₂=0.65, λ₃=0.02, λ₄・λ₅ ≈ 0.00。 トレース(合計)は 5(標準化済みなので)。 λ₄・λ₅ がほぼ 0 なのは人口系変数間の強い線形従属(多重共線性)のサイン。
λ_i / Σλ で寄与率(実測):PC1=86.6%, PC2=13.0%, PC3=0.3%, PC4・PC5≈0%。 累積で PC1+PC2 が 99.6% に達するので、 5 次元 → 2 次元に削減しても情報のほぼすべてを保持。
47 県を 2 次元に投影。 実測では PC1 軸の正側に東京 (+8.1)・神奈川 (+4.8)・大阪 (+4.6)(大都市)、 負側に鳥取 (-1.8)・島根 (-1.8)・福井 (-1.7)(小規模県)。 PC2 軸では沖縄 (+2.0)(出生率高)が分離。 「PC1 = 都市規模軸、 PC2 = 出生率軸」と解釈可能。
固有値の概念は 18 世紀末、 オイラー(Euler)が回転体の主軸を求める研究で導入。 「ラテン語の eigen(自分の、 固有の)」をハンガリーの数学者 Hilbert が 1904 年に使い始め、 現在の名称が定着。 20 世紀初頭、 ハイゼンベルクの行列力学(量子力学)で固有値分解が物理学の中心概念に。
Pearson(1901)が PCA を提唱、 Hotelling(1933)で形式化。 SSDSE のような多変量データの「本質的な軸」を抽出する技術として、 心理学(性格テスト)・経済学(景気指標)・社会学(地域格差)に応用。 教育・所得・健康など多指標の総合スコア化(HDI、 well-being index)も固有値分解の応用例。
量子力学:シュレーディンガー方程式 \( \hat H \psi = E \psi \) は固有値方程式。 E が許容エネルギー(固有値)、 ψ が波動関数(固有ベクトル)。 振動工学:橋・建物の固有振動数を固有値分解で求め、 共振を防ぐ設計に使う。
PCA・LDA(線形判別分析)・スペクトラルクラスタリング・カーネル PCA・グラフ Laplacian Eigenmap・PageRank。 すべて固有値分解が核心。 ディープラーニングでも、 Hessian 行列の固有値で「鞍点 vs 局所最小値」を判定したり、 重み行列の固有値で勾配消失・爆発を診断したりする。
グラフのスペクトル(隣接行列・Laplacian 行列の固有値スペクトル)はグラフの構造を反映。 SSDSE で都道府県の「隣接関係」「人口流動」をグラフ化し、 ラプラシアン固有値で「クラスタ数の推定」(spectral gap method)が可能。
| 関数 | 対象 | バックエンド | 特徴 |
|---|---|---|---|
np.linalg.eig | 一般行列 | LAPACK dgeev | 複素数も可 |
np.linalg.eigh | 対称・エルミート | LAPACK dsyevr | 実数固有値保証・高速 |
np.linalg.eigvals | 一般行列 | LAPACK | 固有値のみ(高速) |
scipy.linalg.eig | 一般行列 | LAPACK | 一般化固有値問題対応 |
scipy.sparse.linalg.eigs | 疎行列 | ARPACK | 上位 k 個のみ計算 |
sklearn.decomposition.PCA | データ行列 | SVD | 数値安定・前処理込 |
torch.linalg.eigh | 対称テンソル | cuSOLVER (GPU) | 微分可能・GPU 加速 |
1 2 3 4 5 | import numpy as np import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] # 2023 年度・47 都道府県 X = df[['A1101','A1303','A1301','A4101','A4103']].values |
Z = (X - X.mean(axis=0)) / X.std(axis=0, ddof=1)
1 2 3 4 5 6 7 8 9 10 11 12 | import numpy as np import pandas as pd from sklearn.preprocessing import StandardScaler # Z は標準化した行列(2023 年の 47 都道府県 × 6 指標) _d = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) _d = _d[_d['SSDSE-B-2026'] == 2023].reset_index(drop=True) Z = StandardScaler().fit_transform( _d[['A1101', 'A1301', 'A1303', 'A4101', 'A4200', 'L3221']].astype(float)) C = np.cov(Z.T) print(f'共分散行列 shape: {C.shape}') |
eigvals, eigvecs = np.linalg.eigh(C) # 降順に並び替え idx = eigvals.argsort()[::-1] eigvals, eigvecs = eigvals[idx], eigvecs[:, idx]
1 2 3 4 5 6 7 8 9 10 11 | import numpy as np # eigvals / eigvecs(固有値・固有ベクトル)はこのあとのブロックで作っている。 # 相関行列から求めておく C = np.corrcoef(Z, rowvar=False) eigvals, eigvecs = np.linalg.eigh(C) _order = np.argsort(eigvals)[::-1] eigvals, eigvecs = eigvals[_order], eigvecs[:, _order] contribution = eigvals / eigvals.sum() print(f'寄与率: {contribution}') |
1 2 3 4 5 6 7 8 9 | import numpy as np from sklearn.decomposition import PCA # contribution(寄与率)はこのあとのブロックで作っているので、ここでも用意しておく _pca = PCA().fit(Z) contribution = _pca.explained_variance_ratio_ cumulative = np.cumsum(contribution) print(f'累積寄与率: {cumulative}') |
1 2 3 4 5 6 7 8 9 10 11 12 | import numpy as np # eigvals / eigvecs(固有値・固有ベクトル)はこのあとのブロックで作っている。 # 相関行列から求めておく C = np.corrcoef(Z, rowvar=False) eigvals, eigvecs = np.linalg.eigh(C) _order = np.argsort(eigvals)[::-1] eigvals, eigvecs = eigvals[_order], eigvecs[:, _order] features = ['A1101','A1303','A1301','A4101','A4103'] for i in range(2): print(f'PC{i+1}: {dict(zip(features, eigvecs[:, i].round(3)))}') |
PC = Z @ eigvecs[:, :2] df['PC1'] = PC[:, 0] df['PC2'] = PC[:, 1]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import os import pandas as pd from sklearn.decomposition import PCA os.makedirs('outputs', exist_ok=True) # PC1 / PC2 を df に持たせる(主成分は Z から求める) _sc = PCA(n_components=2).fit_transform(Z) df = _d.copy() df['PC1'], df['PC2'] = _sc[:, 0], _sc[:, 1] import matplotlib.pyplot as plt plt.scatter(df['PC1'], df['PC2']) for i, row in df.iterrows(): plt.annotate(row['Prefecture'], (row['PC1'], row['PC2']), fontsize=8) plt.xlabel('PC1'); plt.ylabel('PC2') plt.savefig('outputs/pca_scatter.png', dpi=120) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | import numpy as np import pandas as pd from sklearn.preprocessing import StandardScaler # Z は標準化した行列(2023 年の 47 都道府県 × 6 指標) _d = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) _d = _d[_d['SSDSE-B-2026'] == 2023].reset_index(drop=True) Z = StandardScaler().fit_transform( _d[['A1101', 'A1301', 'A1303', 'A4101', 'A4200', 'L3221']].astype(float)) from sklearn.decomposition import PCA pca = PCA(n_components=2).fit(Z) print('sklearn 寄与率:', pca.explained_variance_ratio_) print('numpy 寄与率:', contribution[:2]) |
1 2 3 4 5 6 | v = np.ones(C.shape[0]) for _ in range(100): v = C @ v v /= np.linalg.norm(v) lam_max = v.T @ C @ v print(f'最大固有値(パワー法): {lam_max}') |
np.savez('outputs/pca_results.npz',
eigvals=eigvals, eigvecs=eigvecs, PC=PC, contribution=contribution)
本セクションでは、 固有値分解という抽象的な数学操作を SSDSE-B-2026 の 47 都道府県 × 多変量データに適用したとき、 実際に何が見えてくるかを 3 つの図と 6 つの表で立体的に提示する。 単なる定義の確認ではなく、 「主成分」「分散の集約」「次元削減」「クラスタ構造」「外れ値検出」 という 5 つの応用観点を、 同じ SSDSE-B-2026 を素材に同時並行で観察することで、 固有値が 線形代数の単独トピックではなく データ理解の中核ツールであることを腑に落とす。
下図は、 SSDSE-B-2026(2023 年度)の A1101(総人口)と I5102(一般診療所数)の 2 変数の散布図(相関係数 r = 0.972)。 共分散行列の 第 1 主成分(最大固有値方向)は、 この散布図の長軸方向(回帰直線に近い右上がりの向き)に伸び、 短軸方向が λ₂ に対応する。 47 都道府県のばらつきの大半は長軸方向に集約されている。

この 2 変数(人・施設という生データ単位のまま)の共分散行列を固有値分解した実測結果は、 第 1 固有値 λ₁ ≈ 7.8×10¹²、 第 2 固有値 λ₂ ≈ 3.8×10⁵ となり、 寄与率 λ₁/(λ₁+λ₂) は 99.99% 超が第 1 主成分に集中する(単位の大きい総人口の分散が支配するため、 標準化しない場合の寄与率は極端になる点にも注意)。 つまり「2 変数だが本質的には 1 次元(規模の大小)で大半を説明できる」 と固有値が定量的に告げているのである。
下図は SSDSE-B-2026(2023 年度)の A1101(総人口)のヒストグラムである。 分布は右に大きく歪み、 東京・神奈川・大阪・愛知が長い裾を作る。 この「規模の一極集中」ゆえに規模系変数どうしは強く相関し、 共分散行列の第 1 固有値が突出する。 実測では、 主要 8 変数(標準化後)の固有値は 5.59, 1.62, 0.71, … と減衰し、 第 1 固有値だけで全体分散の 68.3% を占め、 第 2 までで 88.2% に達する。 スクリープロットで「どこで肘 (elbow) が折れるか」を見つけることが、 主成分の本数を決める実践的な手法となる。

実務上は カイザー基準(λ > 1 を採用)、 累積寄与率 80% 基準、 スクリー基準(折れ目を採用)の 3 つを併用する。 SSDSE-B-2026 主要 8 変数では、 これらが概ね「2 主成分採用」で一致する(カイザー基準:λ > 1 は 2 個、 累積 80% 超は第 2 主成分の 88.2% 時点)ため、 結論はロバストである。
下図は、 標準化した規模系指標に KMeans(k=3)を適用して 47 都道府県を 3 クラスタに分割し、 クラスタ別に I5102(一般診療所数)の分布を箱ひげ図として示したものである。 cluster1 は東京都単独、 cluster2 は神奈川・大阪・愛知などの大都市群、 cluster0 はその他の道県群に対応する。 固有値分解(主成分得点)は、 このような クラスタリングの前処理として有効であり、 高次元のまま距離計算するより「規模軸」上での群構造が際立つ。

この図から、 第 1 主成分(人口規模軸)に沿ってクラスタ間の一般診療所数の水準が明瞭に分離しており、 東京都が単独クラスタになるのは PC1 得点の突出(実測 +9.2)と対応する。 固有値分解の結果が 政策的にも意味のある軸を抽出していることが視覚的に確認できる。
| 順位 | 固有値 λᵢ | 寄与率 (%) | 累積寄与率 (%) | 解釈の例 |
|---|---|---|---|---|
| 1 | 5.59 | 68.3 | 68.3 | 人口規模軸(都市 vs 地方) |
| 2 | 1.62 | 19.9 | 88.2 | 気候・出生率軸(温暖・多産 vs 寒冷) |
| 3 | 0.71 | 8.6 | 96.8 | 消費支出軸 |
| 4 | 0.23 | 2.8 | 99.7 | 残差(ノイズ寄り) |
| 5 | 0.02 | 0.3 | 100.0 | 残差(ノイズ寄り) |
| 6 | 0.00 | 0.0 | 100.0 | ほぼ 0(多重共線性由来) |
| 7 | 0.00 | 0.0 | 100.0 | ほぼ 0(多重共線性由来) |
| 8 | 0.00 | 0.0 | 100.0 | ほぼ 0(多重共線性由来) |
数値は 2023 年度・47 都道府県の実測(本ページ末尾の完全実装テンプレートの出力)。 累積寄与率 80% を超えるのが第 2 固有値の時点(88.2%)であるため、 多くの応用ではこの 2 主成分のみを使えば 「8 変数で起きていることの 9 割近くは説明できる」状態になる。 第 6-8 固有値がほぼ 0 なのは、 総人口 ≒ 年少人口 + 生産年齢人口 + 高齢人口 といった人口系変数間の線形従属(多重共線性)を反映している。 これが 固有値による次元削減の威力である。
| 変数 | PC1 (人口規模) | PC2 (気候・出生率) | PC3 (消費支出) |
|---|---|---|---|
| A1101 総人口 | 0.42 | 0.09 | -0.04 |
| A1303 高齢人口 | 0.42 | 0.07 | -0.08 |
| A1301 年少人口 | 0.42 | 0.13 | -0.01 |
| A4101 出生数 | 0.42 | 0.14 | -0.01 |
| A4103 合計特殊出生率 | -0.28 | 0.51 | 0.20 |
| A4200 死亡数 | 0.42 | 0.06 | -0.11 |
| B4101 年平均気温 | 0.02 | 0.71 | 0.41 |
| L3221 消費支出 | 0.18 | -0.43 | 0.88 |
数値は 2023 年度・47 都道府県の実測ローディング。 PC1 は人口系 5 変数(総人口・高齢人口・年少人口・出生数・死亡数)がすべて +0.42 と同じ符号・同じ重みで寄与する「全体の規模感」を示すサイズ成分で、 合計特殊出生率だけが負(-0.28、 大規模な都市圏ほど出生率が低い傾向)となっている。 PC2 では年平均気温が +0.71、 合計特殊出生率が +0.51、 消費支出が -0.43 で、 「温暖・多産(西日本・南方) vs 寒冷・高消費」 の対比軸となっている。 PC3 では消費支出が +0.88 と支配的で、 「家計消費水準」 を表す軸として解釈できる。
| 順位 | 都道府県 | PC1 得点 | PC2 得点 | 解釈 |
|---|---|---|---|---|
| 1 | 東京都 | +9.17 | +0.22 | 超大都市・PC2 は中立 |
| 2 | 神奈川県 | +5.35 | +0.73 | 大都市・温暖寄り |
| 3 | 大阪府 | +4.96 | +1.59 | 大都市・温暖寄り |
| 4 | 埼玉県 | +4.29 | -0.49 | 大都市圏ベッドタウン |
| 5 | 愛知県 | +3.85 | +1.06 | 大都市・温暖寄り |
| … | … | … | … | … |
| 43 | 宮崎県 | -1.90 | +1.72 | 小規模・温暖・出生率高め |
| 44 | 島根県 | -1.94 | +0.20 | 小規模・バランス型 |
| 45 | 佐賀県 | -1.96 | +1.15 | 小規模・出生率高め |
| 46 | 福井県 | -2.02 | +0.43 | 小規模・バランス型 |
| 47 | 鳥取県 | -2.17 | +0.53 | 最小規模・バランス型 |
数値は 2023 年度の実測主成分得点。 第 1 主成分得点が最大の東京都 (+9.17) と最小の鳥取県 (-2.17) では 得点差が約 11 あり、 これは「人口規模軸」 上での実質的なスケール差を表す。 PC2 では沖縄県が +4.27 と突出し、 温暖な気候と高い出生率という特異性が定量的にも観察できる。
| 概念 | 固有値分解での対応 | SSDSE-B-2026 での意味 |
|---|---|---|
| 主成分分析 (PCA) | 共分散行列の固有値分解 | 47 都道府県を低次元で要約 |
| 特異値分解 (SVD) | ATA の固有値の平方根 | データ行列の直接分解 |
| スペクトル分解 | 対称行列を λᵢ vᵢ vᵢT の和に | 相関行列の構造分解 |
| 線形判別 (LDA) | クラス内行列⁻¹×クラス間行列の固有値 | 都道府県群分けの最適軸 |
| スペクトラルクラスタリング | グラフラプラシアンの最小固有値 | 都道府県類似グラフの分割 |
| マハラノビス距離 | 共分散の逆行列(固有値の逆数) | 外れ都道府県の検出 |
| PageRank | 遷移行列の最大固有値・固有ベクトル | 都道府県間人流ネットワーク中心性 |
| アルゴリズム | 適用条件 | 計算量目安 | 推奨ライブラリ |
|---|---|---|---|
| QR 法 | 一般の正方行列 | O(n³) | numpy.linalg.eig |
| Jacobi 法 | 小〜中規模対称行列 | O(n³) | scipy.linalg.eigh |
| Lanczos 法 | 大規模疎対称行列 | O(nk) (k 個のみ) | scipy.sparse.linalg.eigsh |
| べき乗法 | 最大固有値のみ必要 | O(n²) 反復 | 自前実装も容易 |
| Truncated SVD | 上位 k 主成分のみ必要 | O(nk²) | sklearn.decomposition.TruncatedSVD |
| Randomized SVD | 超大規模・近似でよい | O(nk log k) | sklearn.utils.extmath.randomized_svd |
SSDSE-B-2026 のように 47 行 × 数十変数程度の小規模データであれば scipy.linalg.eigh が高速・高精度で十分。 一方、 全国市区町村 (1,700 オーダー) を扱う SSDSE-D では Truncated SVD や Randomized SVD の利点が出始める。
| スペクトル型 | 特徴 | 対応する解釈 | SSDSE での例 |
|---|---|---|---|
| 単峰急降下 | λ₁ ≫ λ₂ で残りは小 | 1 次元で大半説明可能 | 総人口・一般診療所数の 2 変数 |
| 緩やか降下 | λ がなだらかに減少 | 複数の独立軸が共存 | SSDSE-B 主要 8 変数の第 1-3 軸 |
| 階段状 | 大きな塊が複数 | 明確なクラスタ構造 | 産業構造×地理ブロック |
| フラット | λᵢ ≈ 一定 | ノイズ・等方分布 | 無相関な変数群 |
| 0 固有値あり | λᵢ = 0 が混在 | 線形従属・多重共線性 | 割合変数の合計=100 |
| 負固有値 | λᵢ < 0 | 非正定値行列(数値誤差・誤実装) | 標準化前の偏共分散 |
| 重複固有値 | λᵢ = λⱼ | 対応する平面内で軸不定 | 対称な 2 変数(理論上) |
| 複素固有値 | 虚数部 ≠ 0 | 非対称行列(回転成分) | 時系列遷移行列など |
SSDSE-B-2026 の主要 8 変数は、 実測では第 1 固有値 (5.59) が突出しつつ第 2-3 固有値 (1.62, 0.71) にも情報が残る型であるため、 PCA で 2-3 軸を抽出して使う設計が妥当である。 また第 6-8 固有値がほぼ 0 になるのは人口系変数の線形従属によるもので、 割合変数 (例: 産業構成比) を扱う場合も同様に 0 固有値が出やすいため、 1 変数を落としてから固有値分解する必要がある。
ここまでの 3 図 6 表で示したように、 固有値分解は単なる線形代数の演算ではなく、 「データの本質的な軸を発見する装置」 として機能する。 SSDSE-B-2026 の 47 都道府県 × 8 変数を素材にすれば、 第 1 軸は「人口規模」、 第 2 軸は「気候・出生率」、 第 3 軸は「消費支出」 という社会的に意味のあるラベルが自然に浮かび上がる。 これは事前にラベルを与えずに データだけから導かれるため、 「教師なし学習による知識発見」の代表例である。
統計・データ解析コンペ 2026 にこの視点を持ち込むと、 たとえば「都道府県の福祉政策効果を 3 主成分上で比較する」「主成分得点を回帰モデルの特徴量に投入する」「主成分得点の経年変化から地域格差トレンドを抽出する」 といった応用が考えられる。 単独の指標ランキングを並べるよりも、 多変量を同時に圧縮して比較する ことで、 政策含意が立体的になる点に注目したい。
最後に、 固有値分解を使う際の 3 つの倫理・実務的注意を再確認しておく。 (1) 標準化を必ず行うこと(単位の違いで第 1 主成分が単位最大の変数だけに引きずられる)、 (2) 主成分の解釈は ローディング行列を必ず読むこと(数値だけで判断しない)、 (3) 都道府県のような地理単位を扱う場合、 主成分得点を 地図上に塗り分けると空間相関の存在に気づきやすい。 これらを守れば、 固有値分解はあなたのコンペ提出物の骨格を強固にする中核ツールとなる。
固有値(eigenvalue)という概念は、 19 世紀のオーギュスタン=ルイ・コーシーが線形変換の不変量として導入したのが起源とされる。 「eigen」はドイツ語で「固有の・自身の」を意味し、 ヒルベルトが 20 世紀初頭に積分作用素のスペクトル理論を整備した際に英語圏に定着した。 その後、 力学・量子力学・統計力学・電子工学・グラフ理論・最適化・機械学習・ネットワーク科学 など、 現代科学のほぼ全分野で固有値が「系の本質を抽出する道具」 として使われるようになった。 SSDSE-B-2026 を扱うデータサイエンス文脈もその系譜の上にある。
データサイエンスでは、 固有値は 主成分分析の中核として扱われることが多いが、 実は応用範囲はそれをはるかに超える。 (1) レコメンドシステムでは、 ユーザー × アイテムの巨大疎行列を Truncated SVD で分解して潜在因子を抽出する。 (2) 自然言語処理では、 単語共起行列のスペクトル分解で Latent Semantic Analysis を構築する。 (3) 画像処理では、 共分散行列の固有ベクトルが Eigenfaces として顔の主要な変動方向を表す。 (4) グラフネットワーク分析では、 隣接行列やラプラシアン行列の固有値からコミュニティ構造・拡散速度・連結性が読み取れる。 (5) 力学系では、 線形化したヤコビ行列の固有値の実部から安定性が判定される。 これらはすべて「行列を固有値分解する」という共通の操作で実現されている。
SSDSE-B-2026 を題材にすると、 上記の応用のうち (1)(2)(4) が特に親和性が高い。 (1) 都道府県 × 多変量という構造は、 ユーザー × アイテム行列と同じ「2 モード行列」 であり、 SVD で「都道府県の潜在因子」「変数の潜在因子」 を抽出できる。 (2) 経年データを使えば、 「年×都道府県」の行列に LSA 的な分解を適用して、 時間的に共通の地域パターンを抽出できる。 (4) 都道府県間の人流・物流データを隣接行列とみなせば、 スペクトラルクラスタリングや PageRank に直結する。 固有値はこのように、 一見異なる応用を 「行列分解」という共通言語でつなぐ役割を果たす。
| 誤解 | 何が違うか | 正しい理解 |
|---|---|---|
| 固有値は常に実数 | 対称行列に限る話を一般化している | 非対称行列の固有値は複素数になりうる |
| 固有値が大きい=重要 | 単位や標準化の影響を見落としている | 標準化前提でのみ「分散の大きさ」と読める |
| 主成分には実質的な意味がある | 回転は任意で、軸の名前は人が後付けする | ローディング行列を読まないと解釈不能 |
| 固有ベクトルは一意に決まる | 符号反転や定数倍も解 | 単位化+符号慣習で「ほぼ」一意 |
| 固有値分解=SVD | 適用対象と性質が違う | SVD は任意の長方行列に適用可能で、 必ず実数 |
| 固有値分解は遅い | 用途によりアルゴリズム選択肢が豊富 | 上位 k 個なら Lanczos/Randomized SVD が高速 |
| 主成分分析と因子分析は同じ | 背後のモデル仮定が異なる | PCA はデータ分散最大化、FA は潜在因子モデル |
| 主成分数は固有値 1 以上 | カイザー基準は「目安」に過ぎない | スクリー基準・累積寄与率と併用が必須 |
pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])。 SSDSE 形式の 2 行目スキップは定型。 さらに df[df['SSDSE-B-2026'] == 2023] で 2023 年度・47 都道府県に絞る。df.isna().sum() で欠測を点検。 SSDSE-B は基本完備だが念のため。df.describe() および箱ひげ図で東京・大阪・北海道などの異常値を点検。StandardScaler で平均 0・分散 1 化。 単位の異なる変数を比較可能にする必須前処理。np.cov(X.T) または StandardScaler 後の相関行列を使用。scipy.linalg.eigh(C) で固有値・固有ベクトルを取得。 戻り値は昇順なので逆順にする。contribution = eigvals / eigvals.sum()。 累積で 80% を超える主成分数を採用。scores = X @ eigvecs[:, :k]。 都道府県ごとの座標が得られる。この 12 ステップを 1 度こなせば、 SSDSE-B-2026 以外のあらゆる多変量データに同じ流れを適用できる。 学生は 同じ素材で同じ流れを 3 回繰り返すことで、 固有値分解のワークフローを身体化できる。
| # | チェック内容 | 確認方法 |
|---|---|---|
| 1 | 標準化済みか | X.mean(0) が ≈ 0、 X.std(0) が ≈ 1 |
| 2 | 共分散行列が対称か | np.allclose(C, C.T) が True |
| 3 | 固有値が非負か | 対称・半正定値なら eigvals >= 0 |
| 4 | 固有ベクトル直交性 | V.T @ V ≈ I を確認 |
| 5 | 再構成誤差 | V @ diag(λ) @ V.T - C ≈ 0 |
| 6 | 寄与率の合計 | contribution.sum() = 1.0 |
| 7 | 主成分得点の分散 | scores.var(0) ≈ eigvals[:k] |
| 8 | 符号慣習 | 最大絶対値要素を正に揃えると再現性向上 |
| 9 | 外れ値の影響 | 東京除外で再計算し、 結論変化を確認 |
| 10 | scikit-learn 結果と一致 | PCA(n_components=k) と explained_variance を比較 |
この 10 項目をパスすれば、 固有値分解の実装は 「数学的に正しい」と言い切れる。 ただし「正しさ」と「有用性」は別物であり、 ローディングや得点が 実社会の文脈で意味を持つかを別途検証する必要がある。 たとえば PC1 が「人口規模」と読めたとしても、 政策含意を語るためにはさらに「東京と鳥取の格差は何年で何倍に広がったか」 など 時間的・空間的な裏付けが必要となる。
ここでは固有値分解を SSDSE-B-2026 に適用するときに、 学生がそのまま卒業研究・コンペ提出物・授業課題に組み込める 5 つの定型シナリオを紹介する。 各シナリオは「課題設定」「データ準備」「固有値の役割」「期待される結果」「政策・実務含意」 という 5 要素で構成し、 単なる手法解説ではなく 分析の物語として読めるよう設計してある。
課題設定: 「人口規模・人口動態・家計消費」の複数軸で 47 都道府県を 3〜4 群に分けたい。 単純に人口だけで分けると東京と他の差が大きすぎて意味のあるクラスタが作れない。 そこで主成分得点上で k-means クラスタリングを行う。
データ準備: A1101(総人口)、 A1301(年少人口)、 A1303(高齢人口)、 A4101(出生数)、 A4200(死亡数)、 L3221(消費支出)の 6 変数を標準化。
固有値の役割: 6 変数を 2-3 主成分に圧縮し、 PC1(規模)と PC2(人口動態)の平面で k-means を実行する。 高次元のままだと距離計算が「次元の呪い」 で歪むため、 主成分圧縮が決定的に効く。
期待される結果: 「東京単独群」「大都市圏群(神奈川・大阪・愛知)」「中規模県群」「小規模県群」 の 4 クラスタが浮かび上がる。
政策含意: 補助金配分や行政サービスの設計を「都市規模類型」単位で行うことで、 一律施策よりもきめ細かい支援が可能になる。
課題設定: 「高齢人口」「死亡数」 など、 高齢化に関連する複数指標を 1 つの合成スコアに集約したい。
データ準備: A1303(高齢人口)、 A4200(死亡数)、 L3221(消費支出)、 B4101(年平均気温)を標準化。
固有値の役割: 第 1 主成分得点を「高齢化進展度スコア」として採用する。 これは複数指標の 共通分散を抜き出した量であり、 単一指標よりも頑健に「県の高齢化レベル」 を表現できる。
期待される結果: 秋田・島根・高知などが上位、 沖縄・東京周辺が下位に位置付けられる。
政策含意: 単一指標ランキングを並べると順位が指標ごとにバラつくが、 合成指標なら一意の順位が得られ、 介護・医療資源の優先配分の根拠として使える。
課題設定: A4101(出生数)を A1101(総人口)で割った粗出生率を、 経済・社会・年齢構成変数で回帰したい。 ただし変数間相関が高く、 多重共線性が懸念される。
データ準備: 説明変数候補を 12 個ほど用意し、 標準化する。
固有値の役割: 共分散行列の固有値スペクトルを見ると、 上位 4 主成分で 80% を超え、 残りは多重共線性に由来する微小固有値となる。 上位 4 主成分得点を回帰の特徴量に投入することで、 多重共線性を解消しつつ情報損失を最小化できる。
期待される結果: 元の 12 変数で OLS を回したときよりも係数が安定し、 解釈もしやすくなる。
政策含意: 「どの主成分が出生率に効いているか」 を見ることで、 「経済力主成分」「子育て環境主成分」 のどちらが効くかという 政策レバーの優先順位が示唆される。
課題設定: 47 都道府県のうち、 多変量的に「平均から最も離れた県」 を機械的に検出したい。
データ準備: 主要 8 変数を標準化。
固有値の役割: 共分散行列の逆行列はそのまま固有値の逆数を対角に持つ表現に分解できるため、 マハラノビス距離 d²ᵢ = Σⱼ (zᵢⱼ² / λⱼ) として計算できる。 固有値が小さい主成分(多重共線性方向)でのズレは大きく加算され、 「微妙な逸脱」 を捉える感度が高い。
期待される結果: 東京は PC1 が極端で大きな距離、 沖縄や鹿児島は PC3 や PC4 で大きく距離が出るなど、 「どの軸で異常か」 まで分解できる。
政策含意: 「異常」というラベルだけでなく、 「どの側面で異常か」 を主成分単位で示せるため、 重点モニタリングの設計に直結する。
課題設定: SSDSE-B の 2014, 2018, 2022, 2026 各年版を並べ、 主成分構造がどう変化したかを追いたい。
データ準備: 各年版から同じ 8 変数を抜き出し、 同じ標準化規約で揃える。
固有値の役割: 各年版で独立に固有値分解し、 (1) 寄与率の推移、 (2) ローディングベクトルの内積(主成分の安定性)、 (3) 各都道府県の主成分得点の経年トラジェクトリ を比較する。
期待される結果: 第 1 主成分(人口規模軸)は驚くほど安定しているが、 第 2 主成分(人口動態軸)は緩やかに「少子化方向」 にシフトしている、 などのトレンドが見える。
政策含意: 「日本全体の構造変化」を 定量的な主成分の動きとして捉えられ、 中長期戦略立案の基盤になる。
Q1. 固有値が負になることはあるか?
A. 共分散行列・相関行列・カーネル行列など 半正定値性が保証されている場合は λ ≥ 0。 ただし数値誤差で僅かに負になることがあり、 その場合は 0 に丸めるのが実務的処理。
Q2. 主成分数はどう決める?
A. 累積寄与率 80% 基準、 カイザー基準 (λ ≥ 1)、 スクリー基準(折れ目)の 3 つを併用し、 すべてが同じ k を示せばその k を採用する。 ずれた場合は分析目的(圧縮重視か可視化重視か)で判断する。
Q3. PC1 と PC2 を入れ替えてもよいか?
A. 固有値の大きい順にラベル付けする慣習があるため、 入れ替えるべきではない。 入れ替えると寄与率・他人の解釈との整合性が崩れる。
Q4. 標準化前と後で固有値はどう変わる?
A. 標準化前は単位の大きい変数(人口など)に第 1 主成分が引きずられる。 標準化後は全変数が同じ重みで競合し、 真に分散の集約方向が見えるようになる。
Q5. 固有ベクトルの符号反転はバグか?
A. バグではない。 固有方程式 Av = λv は -v も解なので、 ライブラリ・乱数シードによって符号が反転することがある。 「最大絶対値要素を正に揃える」 慣習で再現性を確保するのが定石。
Q6. 主成分得点を回帰の特徴量に使う場合の注意は?
A. (i) 標準化済みであるため切片の解釈が変わる、 (ii) 多重共線性は解消されるが個別変数の係数解釈は失われる、 (iii) 採用する主成分数を「目的変数との相関」 で決めても可(PLS 的発想)。
Q7. PCA と因子分析の違いは?
A. PCA は データ分散最大化の数学的最適化。 因子分析は 潜在因子+誤差項のモデルを仮定する統計モデル。 解釈は似るが、 因子分析は仮説検定・適合度評価が可能で、 PCA は探索的可視化に強い。
Q8. カーネル PCA との関係は?
A. データを非線形写像してから固有値分解するのがカーネル PCA。 「曲がった分布」 をきれいに分解できる。 SSDSE-B の都道府県データは概ね線形 PCA で十分だが、 非線形の例として参考にできる。
Q9. 主成分得点の標準化は必要?
A. PCA の出力得点はすでに無相関で、 分散は固有値に等しい。 さらにクラスタリング等に使うときには、 各主成分の分散を 1 に揃える「白色化」 を行う場合もあるが、 やりすぎると「どの軸が支配的か」 の情報が消える。 目的による。
Q10. 固有値分解結果の再現性は?
A. 符号反転以外は決定論的に再現される。 大規模ランダム化 SVD では乱数シードに依存するため、 random_state を必ず固定する。
以下は本ページの議論を 1 本のスクリプトに統合した完全実装である。 各ブロックは独立に実行でき、 学生はこれを写経しながら 12 ステップを身体化できる。 すべての変数は SSDSE-B-2026 の実列名を直書きしており、 ハードコードのまま実環境で動作する。
このコードでやること: SSDSE-B-2026 の 8 変数を標準化 → 共分散行列の固有値分解 → 主成分得点を可視化し、 寄与率・ローディング・得点ランキングを出力する。
📥 入力データ(SSDSE-B-2026 抜粋):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn.preprocessing import StandardScaler from scipy.linalg import eigh # 1. データ読み込み(2023 年度・47 都道府県に絞る) df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] # 2. 8 変数選択 cols = ['A1101', 'A1303', 'A1301', 'A4101', 'A4103', 'A4200', 'B4101', 'L3221'] X = df[cols].values # 3. 標準化 scaler = StandardScaler() Xs = scaler.fit_transform(X) # 4. 共分散行列(標準化後なので相関行列と同義) C = np.cov(Xs.T) assert np.allclose(C, C.T), '対称性チェック失敗' # 5. 固有値分解(対称行列専用の eigh を使用) eigvals, eigvecs = eigh(C) # eigh は昇順 → 降順に並べ替え order = np.argsort(eigvals)[::-1] eigvals = eigvals[order] eigvecs = eigvecs[:, order] # 6. 寄与率・累積寄与率 contrib = eigvals / eigvals.sum() cum_contrib = np.cumsum(contrib) print('固有値:', np.round(eigvals, 3)) print('寄与率(%):', np.round(contrib * 100, 1)) print('累積寄与率(%):', np.round(cum_contrib * 100, 1)) # 7. 採用主成分数(累積 80% 基準) k = int(np.searchsorted(cum_contrib, 0.80) + 1) print(f'採用主成分数 k = {k}') # 8. 符号慣習(最大絶対値要素を正に揃える) for j in range(eigvecs.shape[1]): if eigvecs[np.argmax(np.abs(eigvecs[:, j])), j] < 0: eigvecs[:, j] *= -1 # 9. ローディング行列の表示 loadings = pd.DataFrame(eigvecs[:, :k], index=cols, columns=[f'PC{i+1}' for i in range(k)]) print('ローディング:') print(loadings.round(2)) # 10. 主成分得点 scores = Xs @ eigvecs[:, :k] score_df = pd.DataFrame(scores, columns=[f'PC{i+1}' for i in range(k)]) score_df.insert(0, 'Prefecture', df['Prefecture'].values) print('PC1 得点ランキング上位 5:') print(score_df.nlargest(5, 'PC1')) print('PC1 得点ランキング下位 5:') print(score_df.nsmallest(5, 'PC1')) # 11. 可視化 fig, ax = plt.subplots(figsize=(10, 7)) ax.scatter(score_df['PC1'], score_df['PC2']) for _, row in score_df.iterrows(): ax.annotate(row['Prefecture'], (row['PC1'], row['PC2']), fontsize=8) ax.set_xlabel(f'PC1 ({contrib[0]*100:.1f}%)') ax.set_ylabel(f'PC2 ({contrib[1]*100:.1f}%)') ax.set_title('SSDSE-B-2026: PC1-PC2 平面の都道府県布置') ax.axhline(0, color='gray', linewidth=0.5) ax.axvline(0, color='gray', linewidth=0.5) plt.tight_layout() plt.savefig('outputs/pca_pc1_pc2.png', dpi=120) plt.close() # 12. 整合性チェック recon = eigvecs @ np.diag(eigvals) @ eigvecs.T print('再構成誤差 (最大):', np.max(np.abs(recon - C))) print('得点分散と固有値の比較:', np.round(score_df.iloc[:, 1:].var(0).values, 3), 'vs', np.round(eigvals[:k], 3)) |
📤 実行例の主要出力:
💬 結果の読み方: 累積 88.2% を 2 主成分で達成 → 「8 変数の情報を 2 軸でほぼ再現可能」。 東京都は PC1 で突出 (+9.17) し、 PC2(気候・出生率軸)ではほぼ中立 (+0.22)。 第 6-8 固有値がほぼ 0 なのは人口系変数の線形従属(多重共線性)の表れ。 再構成誤差が 10⁻¹⁵ オーダーなので数値的にも正確。 得点分散と固有値の一致は理論との整合性を確認するクロスチェックとして機能する。
固有値分解の議論には特有の用語が多く、 初学者にとっては「同じ意味なのに違う呼び方」 が壁になりやすい。 以下、 SSDSE-B-2026 の文脈に揃えて 8 用語を簡潔に再定義する。 これらは本文と相互リンクされており、 都度参照して理解を強化してほしい。
これら 8 用語は 同じ操作の異なる側面を指しており、 「固有値分解は主成分分析と本質的に同じ」 「ローディングは固有ベクトル」 「主成分得点は射影」 という対応関係を一度押さえれば、 以後の議論が一気にクリアになる。
固有値分解が単なる線形代数のテクニックを越えて データ理解の中核と位置付けられる理由は、 同じ操作が「分散の集約」「次元削減」「外れ値検出」「クラスタ前処理」「ネットワーク中心性」「動的システムの安定性」「画像・音声・テキスト圧縮」 など、 一見無関係な分野で同形の役割を果たすからである。 SSDSE-B-2026 を題材にした本ページでは 主成分分析を主軸に説明したが、 SSDSE-B 以外のあらゆるデータに 同じ思考の型を適用できる。 「未知のデータに出会ったら、 まず共分散行列の固有値スペクトルを描く」 ことを習慣にすれば、 そのデータの本質的な次元数と支配的な軸が即座に把握できる。 これがデータサイエンス実務における 固有値分解の最大の価値である。
本ページの末尾に至るまで一貫して扱ってきた SSDSE-B-2026 は、 47 都道府県 × 数十変数という 「小さくて深い」データセットである。 小さいがゆえに固有値分解の計算は瞬時に終わり、 深いがゆえに 3 主成分で「人口規模」「気候・出生率」「消費支出」 という社会的に意味のある軸が確実に抽出できる。 この性質は、 学習用教材としてもコンペ用素材としても理想的であり、 本ページの議論を踏まえて自分でコードを動かすことで、 固有値分解の 感覚値を最短ルートで獲得できる。
最後に、 統計・データ解析コンペ 2026 への応用にあたって意識すべきは、 「固有値分解はゴールではなく出発点」 という点である。 主成分得点を得たら、 そこから (a) 都道府県をクラスタリングして政策タイプを発見する、 (b) 経年で得点の動きを追って格差トレンドを定量化する、 (c) 主成分得点を回帰の説明変数に投入して結果指標(出生率・所得など)の構造的決定要因を明らかにする、 といった次の分析に進む。 固有値が抽出した 意味のある軸の上に、 自分の問いを乗せることで、 提出物の説得力が一段引き上がる。 この一連の流れを SSDSE-B-2026 を題材に体験することが、 本ページの最終目的である。
scipy.linalg.eigh を第一選択とし、 大規模なら TruncatedSVD に切り替える。3 変数(総人口 A1101・一般診療所数 I5102・合計特殊出生率 A4103)の共分散行列 $\Sigma\in\mathbb{R}^{3\times 3}$(標準化済み 47 県、 2023 年度の実測値):
$$ \Sigma \approx \begin{pmatrix} 1.00 & 0.97 & -0.56\\ 0.97 & 1.00 & -0.52\\ -0.56 & -0.52 & 1.00 \end{pmatrix} $$固有値分解の結果(NumPy で計算):
$$ \lambda_1 \approx 2.39,\quad \lambda_2 \approx 0.58,\quad \lambda_3 \approx 0.03 $$ $$ v_1 \approx \begin{pmatrix}0.62\\0.62\\-0.48\end{pmatrix},\; v_2 \approx \begin{pmatrix}0.31\\0.37\\0.87\end{pmatrix},\; v_3 \approx \begin{pmatrix}0.72\\-0.69\\0.04\end{pmatrix} $$解釈:第 1 固有値 $\lambda_1=2.39$ が全分散の $2.39/3.00 \approx 80\%$ を占める。 対応する固有ベクトル $v_1$ は「総人口・一般診療所数(プラス)と出生率(マイナス)」の対比 = 都市規模軸。 第 2 軸は出生率が単独で大きく効く「出生構造軸」。
| 主成分 | 固有値 | 寄与率 | 累積寄与率 |
|---|---|---|---|
| PC1 | 2.39 | 80% | 80% |
| PC2 | 0.58 | 19% | 99% |
| PC3 | 0.03 | 1% | 100% |
3 変数だけで「都道府県の主軸」が 1 本に集約できると分かります。 数値変数 109 個を全部使えば、 上位 5 軸で約 90% の説明が可能になります(実測 90.5%)。
$2\times 2$ 対称行列 $A = \begin{pmatrix}3 & 1\\ 1 & 3\end{pmatrix}$ の固有値・固有ベクトル。
確認:$Av_1 = (4, 4)^\top / \sqrt 2 = 4 v_1$。 一致。 $A = Q \Lambda Q^\top$ となる $Q$ と $\Lambda$ も計算可能。
SSDSE-B 程度(数百次元)なら NumPy が秒で解く。 100 万次元以上ではスパース化と反復法が必須。
具体的な行列での固有値計算を、 段階を追って丁寧に説明。 数式で躓いた学習者向け。
行列 \( A = \begin{pmatrix} 4 & 1 \\ 1 & 3 \end{pmatrix} \) の固有値を求める。
ステップ 1:特性多項式を立てる。 \( \det(A - \lambda I) = (4-\lambda)(3-\lambda) - 1 = \lambda^2 - 7\lambda + 11 = 0 \)。
ステップ 2:解の公式で \( \lambda = \frac{7 \pm \sqrt{49 - 44}}{2} = \frac{7 \pm \sqrt{5}}{2} \approx 4.62, 2.38 \)。
ステップ 3:各固有値に対応する固有ベクトルを求める。 \( \lambda = 4.62 \) のとき \( (A - 4.62I)\mathbf{v} = 0 \) を解く。
ステップ 4:固有ベクトルを単位化(\( \|\mathbf{v}\| = 1 \) に正規化)。 これで固有値・固有ベクトルのペアが完成。
検算:トレース(対角和)4+3=7 = 固有値和 4.62+2.38=7 で一致。 行列式 4×3-1×1=11 = 固有値積 4.62×2.38≈11 で一致。 これらの一致確認は計算ミスを防ぐ良い習慣。
合成 A = [[4,1],[2,3]] で固有値を特性方程式で求める。
1 2 3 4 5 6 | import numpy as np A = np.array([[4, 1], [2, 3]]) eig = np.linalg.eigvals(A) print(f"固有値: {sorted(eig.real, reverse=True)}") print(f"trace: {A.trace()}") print(f"det: {np.linalg.det(A):.0f}") |
💬 手計算 (Step 2) λ=5,2 と Python 出力が完全一致。
例 1: SSDSE-B-2026 で共分散行列の固有分解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import pandas as pd import numpy as np df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] # 2023 年度・47 都道府県 num = df.drop(columns=['SSDSE-B-2026']).select_dtypes(include='number').fillna(0) # 標準化 Xs = (num - num.mean()) / num.std(ddof=0) # 共分散行列の固有値分解 C = np.cov(Xs.values, rowvar=False) vals, vecs = np.linalg.eigh(C) # 対称行列用、 昇順 vals = vals[::-1] # 大きい順に vecs = vecs[:, ::-1] print('上位 5 固有値:', vals[:5].round(3)) print('累積寄与率:', np.cumsum(vals / vals.sum())[:5].round(3)) |
例 2: 都道府県を主軸に射影。
1 2 3 4 5 6 7 8 9 10 | pref = df['Prefecture'].values # 47 x 2 の主成分得点 PC = Xs.values @ vecs[:, :2] # 東京と沖縄の位置 i = list(pref).index('東京都') j = list(pref).index('沖縄県') print('東京:', PC[i].round(2)) print('沖縄:', PC[j].round(2)) |
例 3: 固有ベクトルの中身を「変数寄与」として解釈。
1 2 3 4 | cols = num.columns.tolist() contrib = pd.Series(vecs[:, 0], index=cols).sort_values(key=lambda s: s.abs(), ascending=False) print('第 1 主成分の上位寄与変数:') print(contrib.head(10)) |
例 4: scikit-learn の PCA と比較。
1 2 3 4 5 | from sklearn.decomposition import PCA pca = PCA().fit(Xs.values) print('sklearn 固有値:', pca.explained_variance_[:5].round(3)) print('sklearn 寄与率:', pca.explained_variance_ratio_[:5].round(3)) |
例 5: 固有値分解の可視化。
1 2 3 4 5 6 | import matplotlib.pyplot as plt fig, ax = plt.subplots(figsize=(8, 5)) ax.bar(range(1, 11), vals[:10] / vals.sum()) ax.set_xlabel('主成分番号'); ax.set_ylabel('寄与率') ax.set_title('SSDSE-B 共分散行列の固有値スペクトル') plt.tight_layout(); plt.savefig('eig_scree.png') |
本セクションは SSDSE-B-2026 を使い、 共分散行列の固有値分解 → PCA 主成分抽出までを段階的に確認する。 各ブロックは「やること → 入力 → 実行例 → 結果の読み方」 を必ず併記。
このコードでやること: SSDSE-B-2026 から 4 指標 (総人口 A1101、 出生数 A4101、 死亡数 A4200、 高齢人口 A1303) を抜き、 共分散行列の固有値・固有ベクトルを np.linalg.eig で計算する。
📥 入力データ: data/raw/SSDSE-B-2026.csv (2023 年度、 47 都道府県、 4 指標)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import pandas as pd import numpy as np df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) d = df[df['SSDSE-B-2026'] == 2023][['A1101', 'A4101', 'A4200', 'A1303']] X = d.values.astype(float) # 標準化してから共分散行列を作る X_std = (X - X.mean(axis=0)) / X.std(axis=0, ddof=1) C = np.cov(X_std, rowvar=False) eigvals, eigvecs = np.linalg.eig(C) order = np.argsort(eigvals)[::-1] eigvals, eigvecs = eigvals[order], eigvecs[:, order] print('固有値:', np.round(eigvals, 4)) print('寄与率:', np.round(eigvals / eigvals.sum(), 4)) |
📤 実行例:
💬 結果の読み方: 第 1 固有値が約 3.97、 寄与率 99.2% に達する。 4 指標の情報のほぼ全てが 1 つの軸 (≒「都道府県規模」) で説明できることを意味する。 これが「総人口・出生数・死亡数・高齢人口は相互に強く相関している」 と直感的に対応する。
このコードでやること: 第 1 固有ベクトル v1 を取り、 各都道府県の標準化データに掛け合わせて「規模スコア」 を作り、 上位 5 件を確認する。
📥 入力データ: X_std (47 行 × 4 列)、 eigvecs[:, 0] (shape=(4,))
1 2 3 4 5 6 7 8 9 10 | v1 = eigvecs[:, 0] if v1.sum() < 0: v1 = -v1 # 符号の任意性を固定(規模が正の向きに) score = X_std @ v1 # shape = (47,) pref = df[df['SSDSE-B-2026'] == 2023]['Prefecture'].values order = np.argsort(score)[::-1] for i in order[:5]: print(f'{pref[i]}: スコア = {score[i]:+.3f}') print('固有ベクトル v1:', np.round(v1, 3)) |
📤 実行例:
💬 結果の読み方: v1 の 4 成分はほぼ等しく 0.5 で、 これは「4 指標の単純な合計に近い軸」 を意味する。 東京都が +7.6 と突出し、 続く大阪・神奈川・愛知・埼玉が並ぶ。 「県の総合的な規模」 を 1 つの軸で表すと、 都市圏が高スコアを取る構造が固有ベクトルから直接見える。
このコードでやること: 共分散行列 C と 第 1 固有値 λ₁、 第 1 固有ベクトル v1 を使い、 定義式 C @ v1 == λ1 * v1 が成り立つことを数値的に確認する。
📥 入力データ: C (4×4 共分散行列)、 eigvals[0]、 eigvecs[:, 0]
1 2 3 4 5 | lhs = C @ v1 rhs = eigvals[0] * v1 print('C v1 =', np.round(lhs, 4)) print('lambda1 v1 =', np.round(rhs, 4)) print('最大誤差 :', np.max(np.abs(lhs - rhs))) |
📤 実行例:
💬 結果の読み方: 左辺 C v1 と右辺 λ1 v1 が小数 4 桁まで完全に一致し、 最大誤差は 10⁻¹⁵ (浮動小数点の計算誤差レベル)。 固有値・固有ベクトルの定義式 A v = λ v が 実データに対して厳密に成り立つことを SSDSE-B-2026 で再確認できる。
このコードでやること: 共分散行列のような対称行列には scipy.linalg.eigh を使えば実数解が保証され、 数値的にも高速。 結果が np.linalg.eig と一致することを確認する。
📥 入力データ: C (4×4 対称行列)
1 2 3 4 5 6 7 | from scipy.linalg import eigh eigvals2, eigvecs2 = eigh(C) order2 = np.argsort(eigvals2)[::-1] print('scipy 固有値:', np.round(eigvals2[order2], 4)) print('numpy 固有値:', np.round(eigvals, 4)) print('一致確認 (差の最大):', np.max(np.abs(np.sort(eigvals)[::-1] - np.sort(eigvals2)[::-1]))) |
📤 実行例:
💬 結果の読み方: 一般行列用 np.linalg.eig と対称行列専用 scipy.linalg.eigh の結果が浮動小数点誤差レベル (10⁻¹⁶) で一致。 実務では「共分散行列・相関行列など対称が保証されているものは eigh を使う」 と覚えておけば、 数値安定性と速度の両方を得られる。
np.linalg.eigh は対称行列限定。 一般の行列は np.linalg.eig。 共分散行列なら必ず対称になるので eigh が高速。eigh は固有値を 昇順 で返す。 大きい順に並べ替えないと、 PC1 がノイズ軸になる。「行列の本質的な作用」を一言で。 一般のベクトルに $A$ を掛けると向きも長さも変わりますが、 固有ベクトル $v$ だけは 向きが変わらず 長さが $\lambda$ 倍になるだけ($Av=\lambda v$)。 だから固有ベクトルは「$A$ という変換が最も素直に働く方向=変換の骨格をなす軸」であり、 固有値 $\lambda$ はその軸上の伸縮率です。 $n\times n$ 行列を $n$ 本の固有軸に分解すれば、 複雑な線形変換も「各軸方向に $\lambda_i$ 倍するだけ」という単純な操作の重ね合わせとして理解できます。 これが対角化 $A=Q\Lambda Q^\top$ の直感的な意味です。
符号と大きさの読み方。 $\lambda>1$ ならその軸方向にデータや変位が 拡大、 $0<\lambda<1$ なら 縮小、 $\lambda<0$ なら 反転しつつ伸縮、 $\lambda=0$ ならその軸方向は 完全につぶれる(情報が失われ、 逆行列 が存在しなくなる)。 反復計算(パワー法・マルコフ連鎖)では「絶対値が最大の固有値の軸」に状態が引き寄せられていく、 と読めます。
固有値は「対称・実・非負」というきれいな性質を 共分散行列のような特殊な行列だけ が持ちます。 一般の行列では次のような罠が現れます。 SSDSE-B-2026(2023 年度・47 都道府県)の実測値を添えて整理します。
(A+A.T)/2、 あるいは複素成分をそのまま「振動」として解釈。対称半正定値な 共分散行列 $\Sigma$ は必ず $\Sigma=Q\Lambda Q^\top$ と直交対角化でき、 これがそのまま 主成分分析 です。 $Q$ の各列が主成分の方向、 $\Lambda$ の対角の固有値 $\lambda_k$ がその方向の分散。 寄与率 $c_k=\lambda_k/\sum_i\lambda_i$、 累積寄与率 $C_k=\sum_{i\le k}c_i$。 SSDSE-B の 5 指標(標準化済み)の相関行列の固有値は実測で $\lambda=[4.332,\ 0.649,\ 0.016,\ 0.0021,\ 0.0009]$、 寄与率 $[86.6\%,\ 13.0\%,\ 0.3\%,\ 0.04\%,\ 0.02\%]$、 累積は第 2 主成分で $99.6\%$。 5 次元を 2 次元に落としても情報のほぼ全量を保てる、 という 次元削減 の根拠が固有値そのものです。
$\det A=\prod_i\lambda_i$、 $\mathrm{tr}\,A=\sum_i\lambda_i$。 標準化データの相関行列では対角が全部 1 なので $\mathrm{tr}=n$(5 指標なら固有値の和が 5、 実測 $4.332+0.649+\dots=5.00$)。 これは「全分散の総量は標準化で保存され、 固有値がそれを軸ごとに再配分している」ことを意味します。 $\det$ が 0 に近い=どれかの $\lambda_i$ が 0 に近い=行列がつぶれている、 という判定にも直結します。
実対称行列は必ず直交行列で対角化できる(スペクトル定理)。 これが PCA の主成分が互いに 無相関(直交) になる理由であり、 因子分析・スペクトルクラスタリング(グラフラプラシアン $L=D-W$ の固有分解)・カーネル PCA まで、 対称行列の固有分解を核とする手法群の共通の土台になっています。
条件数 $\kappa(A)=\lambda_{\max}/\lambda_{\min}$ は連立方程式 $Ax=b$ や回帰の解が入力誤差にどれだけ敏感かを測ります。 SSDSE-B 5 指標の相関行列は実測 $\kappa\approx 4.8\times10^{3}$(多重共線性 あり)。 生の共分散行列だと $\kappa\approx 1.4\times10^{15}$ で計算が破綻寸前になるため、 標準化 と リッジ 正則化が実務上の定石です。
固有分解は正方行列専用ですが、 任意の 行列 $X$ には SVD $X=U\Sigma V^\top$ が使えます。 このとき $X^\top X=V\Sigma^2 V^\top$ なので、 特異値 $\sigma_i$ は $X^\top X$ の固有値の平方根($\lambda_i=\sigma_i^2$)。 sklearn の PCA は共分散行列を作らず $X$ を直接 SVD します。 生データ $Z$ を直接 SVD した条件数 $\sqrt{\kappa}\approx 69$ は、 共分散を経由した相関行列の $\kappa\approx 4.8\times10^{3}$ の平方根に一致し、 「SVD の方が数値的に安定」という主張が実測でも裏づけられます。
固有値という 1 つの概念を中心に、 主要な統計・機械学習手法が同心円状に広がっています。 SSDSE-B の都道府県データから出発しても、 道筋が見えやすくなります。
[正方行列 A] │ ├─ 特性方程式 det(A-λI)=0 → 固有値 λ_i ├─ 固有ベクトル v_i → A v_i = λ_i v_i │ ├─ 対称行列 → スペクトル定理 → A = Q Λ Q^T │ │ │ ├─ 共分散行列 → PCA │ ├─ ラプラシアン → スペクトルクラスタ │ └─ ヘッシアン → 凸性判定 │ └─ 非対称 → 固有値は複素数 → 動的システム / 振動解析
学習順序:行列 → 固有値 → PCA → SVD → スペクトル法 → 深層学習の重み解析。 各ステップで「同じ固有値の概念」が違う顔を見せます。 たとえば PCA では「データの分散」、 スペクトルクラスタでは「グラフの連結度」、 マルコフでは「定常分布」と、 文脈が変わっても核は同じです。
linalg.eig / eigh / svd の使い分け。 戻り値の順序と次元に注意。decomposition.PCA、 decomposition.KernelPCA の比較。固有値・固有ベクトルは単独の数学概念ではなく、 PCA ・SVD ・スペクトル分解 ・グラフ解析 ・物理シミュレーションを貫く線形代数の中核である。 行列の「本質的変換」を読み解く視点として、 共分散行列や隣接行列に適用される。
固有値・固有ベクトルは「行列がベクトル空間をどう伸縮させるか」を要約する量で、 上流の共分散行列・グラフラプラシアン構築で値が決まり、 並列の SVD・PCA・スペクトル分解で姿を変え、 下流の次元削減・主成分・固有顔まで応用が広がる。
「固有値・固有ベクトル」を扱う際の手法選択は、 状況に応じて以下のフローで判断すると迷いが減る。
このフローに沿って判断することで、 「固有値・固有ベクトル」を中核とした適切な手法選択ができる。