第9回 PCA②:大規模データへの対応とバイプロット解釈¶
本日の到達目標¶
- 固有値分解(EVD)・特異値分解(SVD)の計算量を説明できる
- ランダム化SVDの原理と精度・速度のトレードオフを説明できる
- バイプロットを使って主成分の解釈ができる
- 発展:SVD の特異値と共分散行列の固有値の対応を導き、PCA が座標の回転には影響されないのに変数のスケール変更には影響される理由を説明できる
1. 計算量の問題¶
1.1 標準的な PCA の計算量¶
\(n\) 観測 × \(p\) 変数の行列 \(\mathbf{X}\) に対して標準的なPCAを実行するコスト:
| ステップ | 演算 | 計算量 |
|---|---|---|
| 共分散行列の計算 | \(\mathbf{X}^T\mathbf{X}\) | \(O(np^2)\) |
| 固有値分解(または全SVD) | \(p \times p\) 行列の分解 | \(O(p^3)\) |
| 主成分スコアの計算 | \(\mathbf{X} \mathbf{V}\) | \(O(npk)\) |
問題となる場面: - \(n = 10^7\)(1000万件)、\(p = 100\)(時間窓特徴量100列)の場合 - 共分散行列の計算:\(O(10^7 \times 10^4) = O(10^{11})\) → 数分〜数十分 - 行列の格納だけで \(100 \times 100 \times 8 = 80,000\) バイト(問題ない) - \(n = 10^7\)、\(p = 10^4\) の場合(テキスト特徴等) - 共分散行列の格納:\(10^4 \times 10^4 \times 8 = 800\) MB → メモリ問題 - 固有値分解:\(O(p^3) = O(10^{12})\) → 非現実的
1.2 Truncated SVD¶
全固有値を求めず、上位 \(k\) 個だけを求める Truncated(打ち切り)SVD:
- 計算量:\(O(npk)\)(\(k \ll p\) のとき大幅削減)
- \(\mathbf{V}_k\):上位 \(k\) 個の右特異ベクトル → PCAの主成分方向に対応
- \(\mathbf{\Sigma}_k\):上位 \(k\) 個の特異値 → \(\sigma_j^2/n \approx\) 固有値に対応
導出①:特異値と固有値の対応は近似ではなく等式である
本文で「\(\sigma_j^2/n \approx\) 固有値」と書きましたが、打ち切りをしなければこれは厳密な等式です。
\(\mathbf{X}\) の特異値分解を \(\mathbf{X} = \mathbf{U}\mathbf{\Sigma}\mathbf{V}^T\) とします(\(\mathbf{U}, \mathbf{V}\) は直交行列、\(\mathbf{\Sigma}\) は対角)。これを \(\mathbf{X}^T\mathbf{X}\) に代入します。
途中で \(\mathbf{U}^T\mathbf{U} = \mathbf{I}\) を使いました。最後の式は \(\mathbf{X}^T\mathbf{X}\) の固有値分解そのものです。読み取れることは2つあります。
- \(\mathbf{X}^T\mathbf{X}\) の固有ベクトルは \(\mathbf{V}\) の列(右特異ベクトル)
- \(\mathbf{X}^T\mathbf{X}\) の固有値は \(\sigma_j^2\)
共分散行列は \(\mathbf{S} = \mathbf{X}^T\mathbf{X}/n\) なので、その固有値は \(\sigma_j^2/n\) です。
なぜこれが実務で効くのか。 第8回の道筋では、まず \(\mathbf{S}\)(\(p \times p\))を作ってから固有値分解しました。この式は、\(\mathbf{S}\) を作らずに \(\mathbf{X}\) から直接主成分方向が得られることを示しています。\(p = 10^4\) のとき \(\mathbf{S}\) の格納だけで 800 MB かかりますが、SVD なら \(\mathbf{S}\) を作る必要がありません。近似になるのは上位 \(k\) 個で打ち切ったときだけで、対応関係そのものは厳密です。
使った数学:SVD の定義、直交行列の性質 \(\mathbf{U}^T\mathbf{U} = \mathbf{I}\)(線形代数)。
2. ランダム化SVD(Randomized SVD)¶
2.1 基本的なアイデア¶
直観:高次元行列でも「情報の多くは低次元の部分空間に集中している」
アルゴリズムの概略(Halko et al., 2011)
ステップ1: 乱数行列 Ω ∈ R^{p×(k+p)} を生成
ステップ2: Y = X Ω → 列空間の近似的な基底を構成 (n × (k+p))
ステップ3: QR分解: Y = QR → Q が近似列空間の正規直交基底
ステップ4: 小さな行列 B = Q^T X → (k+p) × p
ステップ5: B の SVD を計算 → X の近似SVDを得る
計算量:\(O(npk)\) に抑えられる(\(n > p\) の場合)
2.2 精度と速度のトレードオフ¶
「オーバーサンプリングパラメータ」\(p\)(上記のアルゴリズムの \(k+p\) 部分):
| 設定 | 精度 | 速度 |
|---|---|---|
| \(k\) のみ(\(p = 0\)) | 低い | 最速 |
| \(k + 10\) | 高い | やや遅い(推奨) |
| \(k + 20\) | さらに高い | 遅い |
電力反復(Power Iteration):\(\mathbf{X}^T\mathbf{X}\) を繰り返しかけることで精度を向上させる追加オプション
2.3 近似誤差の評価¶
フロベニウスノルムによる誤差:
k を大きくすると誤差は減少するが計算時間は増大する。
どこで打ち切るか: - 累積寄与率で決める(第8回の基準) - 実用では \(k = 50 \sim 100\) でほとんどのケースに対応
3. 標準化の重要性¶
3.1 スケールの影響¶
PCA は分散最大化を目指すため、スケールの大きい変数が優位になる。
例: - 売上(万円単位、分散 = 100万) - 気温(°C単位、分散 = 10)
標準化なしでは売上が第1主成分をほぼ一人で支配してしまう。
導出②:単位を変えると結果が変わるのは、分散が単位に依存する量だから
なぜスケールが結果を変えるのかを式で見ます。
変数 \(x_j\) の単位を変えて \(a\) 倍すると(例:円→万円なら \(a = 10^{-4}\))、共分散行列の該当成分は次のように変わります。
対角成分は \(a^2\) 倍、非対角成分は \(a\) 倍と、変わり方が違うのが要点です。行列全体が定数倍されるのではないので、固有ベクトルの向きそのものが変わります。
第8回の導出③より、寄与率の分母は \(\text{tr}(\mathbf{S}) = \sum_j S_{jj}\) です。ある変数の \(S_{jj}\) が突出して大きければ、その変数だけで分母のほとんどを占めます。分散最大化は「いちばん散らばっている方向」を探す操作なので、単に目盛りが細かいだけの変数を最重要と判断してしまいます。
標準化すると全変数の分散が1になり、\(\text{tr}(\mathbf{S}) = p\)、\(\mathbf{S}\) は相関行列と一致します。相関行列ベースの PCA とは、この前処理をした共分散行列ベースの PCA のことです。
注意:標準化は万能の前処理ではありません。同じ単位で測った変数群で、分散の大小そのものに意味がある場合(例:同一センサーの複数チャネル)、標準化はその情報を消してしまいます。本文の表のとおり、単位が混在するときに使う道具です。
使った数学:一次変換に対する分散・共分散の変化則。
導出③:回転では分散の総量も固有値も変わらない
導出②と対比すると、PCA が何に影響され何に影響されないかがはっきりします。
座標系を直交行列 \(\mathbf{R}\) で回すと、共分散行列は \(\mathbf{S} \to \mathbf{R}^T\mathbf{S}\mathbf{R}\) と変わります。ここでトレースの巡回性 \(\text{tr}(\mathbf{AB}) = \text{tr}(\mathbf{BA})\) と \(\mathbf{R}\mathbf{R}^T = \mathbf{I}\) を使うと、
分散の総量は変わりません。固有値も変わりません(固有ベクトルが一緒に回るだけです)。
数値で確かめる:\(\mathbf{S} = \begin{pmatrix} 4.0 & 1.2 \\ 1.2 & 1.0 \end{pmatrix}\) を 0.7 ラジアン回転させると、対角和は \(5.000000\) のまま、固有値も \((4.420937,\ 0.579063)\) のままでした。
2つを並べると:PCA は座標軸の取り方(回転)には影響されないが、変数ごとの目盛りの取り替え(スケール変更)には影響される。前者は分散の総量を保つ変換、後者は保たない変換だからです。「標準化が必要か」という問いは、この区別の上に立っています。
使った数学:トレースの巡回性、直交行列の性質(線形代数)。
3.2 相関行列 vs 共分散行列¶
| 行列 | 前処理 | 推奨場面 |
|---|---|---|
| 共分散行列 | スケール調整なし | 変数が同一単位で意味がある場合 |
| 相関行列 | 各列を標準化(平均0・分散1) | 変数の単位が異なる場合(通常こちら) |
時間窓特徴量の場合:単位が混在(金額・回数・温度等)→ 標準化推奨
4. バイプロット(Biplot)¶
4.1 バイプロットとは¶
主成分スコア(観測点)とローディング(元変数の矢印)を同一プロット上に描く可視化手法。
4.2 読み方¶
観測点(点)の解釈 - 近くにある点 → 似た特性を持つ - 離れた点 → 異なる特性
矢印(ローディング)の解釈 - 矢印の長さ → その変数の第1・第2主成分への寄与の大きさ - 矢印の方向 → その変数が強く関係する主成分の方向 - 同じ方向の矢印 → 正の相関 - 反対方向の矢印 → 負の相関 - 直交する矢印 → 無相関
4.3 解釈の例(時間窓特徴量)¶
第1主成分(PC1)と第2主成分(PC2)のバイプロットで:
- MA7日, MA30日, 直近値 → PC1 方向に揃う
→ PC1 ≈「売上水準の高さ」
- 頻度30日, 頻度7日 → PC2 方向に揃う
→ PC2 ≈「来店頻度の高さ」
5. 近似SVDと精密SVDの比較実験設計¶
5.1 実験の枠組み¶
同一データ X (スナップショット固定: 第3回)
├→ 精密SVD (全成分): 基準
├→ ランダム化SVD (k=10, p=0): 精度低・速い
├→ ランダム化SVD (k=10, p=10): 精度高・やや遅い
└→ ランダム化SVD (k=50, p=10): 精度高・比較的速い
評価指標: - 上位10成分の固有値の差(精密との比較) - 累積寄与率の差 - 実行時間
5.2 DAGによる比較管理¶
6. 基盤リンクの整理¶
| 基盤概念 | 本回での役割 | 具体的な使い方 |
|---|---|---|
| 列指向 | 部分行列抽出・サンプリングの効率化 | 大規模時に必要な列だけ読んでランダム化SVD |
| 整合性 | 比較実験で同条件を維持 | 全手法が同一スナップショットを使う |
| DAG | 近似→評価→解釈を一連の処理として管理 | 各手法の実行をDAGで並列化 |
| 近似 | ランダム化SVDで計算をスケールさせる | \(O(p^3) → O(npk)\) への計算量削減 |
7. 本日のまとめ¶
- 標準的なSVD/EVDは \(O(p^3)\) →大規模・高次元では非現実的
- ランダム化SVD:\(O(npk)\) で上位 \(k\) 成分を近似取得。精度はオーバーサンプリングパラメータで制御
- 変数の単位が異なる場合は相関行列ベースのPCA(標準化後に実行)
- バイプロット:観測点とローディング矢印を同一図で可視化し、主成分の意味を解釈する
次回予告¶
第10回では k-means①:クラスタ内分散最小化の目的関数を理解し、PCA出力を入力としてデータを類型化する方法を学ぶ。
事後課題¶
以下を調べ、A4半枚程度でまとめること:
- scikit-learn の
TruncatedSVDとPCAクラスの違いを調べ、どちらをどの場面で使うべきか説明してください。 - ランダム化SVDは「乱数を使う」のに、なぜ毎回ほぼ同じ結果が得られるのか直観的に説明してください。