本文へスキップ
ひもとくAI

主成分分析と多重共線性:データを少ない軸にまとめる

レッスン 5/7

主成分分析:データが一番広がっている向きを探す

2つの特徴量を、1つにまとめられないか

第10章で作った、200人の身長と体重のデータ(相関係数0.746)を思い出してください。身長が高い人は体重も重い傾向があるので、点は右上がりの帯のように並んでいました。この2つの数を、「体の大きさ」のような1つの数にまとめられないでしょうか。

点の散らばりを見ると、右上がりの向きには大きく広がり、それと直角の向きには少ししか広がっていません。一番大きく広がっている向き に沿った1本の軸を引き、各点をその軸に投影した位置(軸の上の目盛り)を使えば、2つの数を1つにまとめても、点どうしの違いの大部分を残せます。

このように、データが一番広がっている(分散が一番大きい)向きを順に探して、新しい軸を作る方法を 主成分分析(PCA)と呼びます。1番目の軸を 第1主成分、それと直角な向きのうち次に広がっている軸を 第2主成分 と呼びます。

固有ベクトルが、その向き

一番広がっている向きは、前のレッスンの道具で求められます。共分散の表(第10章)の固有ベクトルが主成分の向き、固有値がその向きの分散になります。

第1主成分第2主成分
向き(身長, 体重)(0.642, 0.766)(−0.766, 0.642)
分散(固有値)91.2012.99
寄与率(分散全体に占める割合)0.8750.125

第1主成分は、身長と体重が両方とも増える向き((0.642, 0.766)、ほぼ斜め右上)で、データの分散全体の87.5%を占めていました。第1主成分だけで、2つの特徴量の違いの87.5%を表せる ということです。この割合を 寄与率 と呼びます。

2つの主成分の向きは、直角に交わります(対称な行列の固有ベクトルだから)。scikit-learn の PCA でも、同じ向きと寄与率(0.875・0.125)が得られました(向きは符号が逆になることがありますが、同じ軸です)。

実際の手順

  1. 各特徴量から平均を引く(データの中心を原点に移す)
  2. 共分散の表を作り、固有値・固有ベクトルを求める(実際の計算では、同じ結果になる特異値分解を使うことが多い)
  3. 固有値の大きい順に、必要な数の固有ベクトルを選ぶ
  4. データを、選んだ固有ベクトルの向きに投影する(内積を計算する)

値の大きさがそろっていない特徴量は、k近傍法と同じく、先に標準化します。そうしないと、値の大きい特徴量の向きが「一番広がっている向き」になってしまいます。

手書き数字を、少ない数の特徴量にまとめる

手書き数字の画像は、8×8 = 64個の画素の濃さ(64個の特徴量)でできています。主成分分析で、64個の主成分を求めました。

寄与率と、累積寄与率

主成分0.14910.13620.11830.08440.05850.04960.04370.03780.03490.03110
手書き数字の第1〜第10主成分の寄与率。第1主成分が0.149で最も大きく、第2が0.136、第3が0.118と続き、第10主成分は0.031まで小さくなる

寄与率を大きい順に足していったものを 累積寄与率 と呼びます。「最初の何個の主成分で、元のデータの分散の何割を表せるか」を表します。

使う主成分の数累積寄与率010213040506400.50.91
  • 累積寄与率
  • 0.9
使う主成分の数(横軸、0〜64個)と、累積寄与率(縦軸)。最初は急に増え、10個で0.738、21個で0.903(○)と、0.9の水平な線を超える。その後はゆるやかになり、40個で0.988、50個でほぼ1.0に達する

64個の特徴量のうち、21個の主成分で、分散の90%を表せます。残りの43個は、全部合わせても10%です。このように、主成分分析で少ない数の特徴量にまとめることを 次元圧縮(次元削減)と呼びます。

まとめた特徴量で分類する

主成分分析で次元を減らしてから、k近傍法(k=5)で分類しました。

使う主成分の数25102064(全部)
テストデータの正解率0.5800.9090.9720.9810.981

20個にまとめても、64個全部を使ったときと同じ0.981でした。計算が約3分の1で済み、レッスン1の次元の呪いも和らぎます。一方、2個まで減らすと0.580に下がりました。

2次元にすると、データを「見る」ことができる

2個の主成分では分類には足りませんが、散布図に描ける という大きな利点があります。0・1・4・7の4つの数字について、第1・第2主成分の値を描きました(各25枚)。

第1主成分第2主成分-20-100102030-30-20-1001020
  • 数字の0
  • 数字の4
  • 数字の7
  • 数字の1
手書き数字の0・4・7・1(各25枚)を、第1主成分(横軸)と第2主成分(縦軸)で描いた散布図。0(○)は主に下の方(縦軸−30〜−12)に、4(■)は主に右の方(横軸15〜32)に、それぞれまとまっている。7(△)は主に左上(横軸−13〜10、縦軸10〜22)に集まる。1(◆)は主にその右側の上の方(横軸0〜18、縦軸10〜23)に広がるが、一部は左の方(縦軸−11〜6)にも散らばっている。7と1は一部が重なっている

正解を使わずに求めた2つの軸なのに、0・4・7はそれぞれまとまって分かれています。一方、7と1は重なっていて、2次元では見分けにくいことが分かります(2次元の正解率が0.580だった理由の1つです)。64次元のデータを目で見る方法として、主成分分析はよく使われます。

主成分分析は、データを「まっすぐな軸」に投影するので、曲がった形の構造は表しきれません。2次元で見ることだけが目的なら、t-SNE のように、「元の空間で近い点どうしが、2次元でも近くなるように」配置する方法もよく使われます。t-SNE は見るための方法で、軸そのものには意味がなく、新しいデータにそのまま使うこともできません。

多重共線性、Pythonで主成分分析、振り返り

多重共線性:ほとんど同じ特徴量が2つあると、係数がでたらめになる

主成分分析が役に立つ、もう1つの場面を見ます。特徴量 x1 と、x1 にごく小さな誤差を足しただけの x2(相関係数0.99995)を作り、正解を y = 3 × x1 + 誤差 として、線形回帰(第4章)の係数を求めました。データを作る乱数を変えて、5回試しています。

回12345
x1 と x2 の両方を使ったときの係数(−9.3, 12.3)(1.1, 1.7)(1.4, 1.9)(−8.4, 11.5)(−4.3, 7.5)
x1 だけを使ったときの係数3.012.833.233.093.24

x1 だけなら、係数は本当の値3の近くに安定しています。ところが、ほとんど同じ x2 も入れると、係数は (−9.3, 12.3) のように、大きなプラスとマイナスに振り回されました。2つの係数の 合計 はどれも3くらいで、予測の値はほとんど同じです。x1 と x2 がほぼ同じなので、「x1 に3」でも「x1 に−9.3、x2 に12.3」でも、同じ予測になってしまい、どちらか1つに決められないのです。

このように、特徴量どうしが強く相関していて、係数が不安定になる問題を 多重共線性 と呼びます。予測の精度は落ちにくいのですが、「どの特徴量がどれだけ効いているか」を係数から読み取ることができなくなります(第9章の、似た特徴量で重要度が分かれる問題と同じ根っこです)。

対策には、次のようなものがあります。

  • 強く相関する特徴量の一方を取り除く
  • 主成分分析で、相関する特徴量を1つの主成分にまとめる(主成分どうしは相関しない)
  • 第8章のL2正則化(Ridge)で、係数が大きくなりすぎるのを防ぐ

Pythonで主成分分析を使う

from sklearn.decomposition import PCA

pca = PCA(n_components=21)          # 21個の主成分を使う
Z = pca.fit_transform(X)            # 64個の特徴量 → 21個の主成分の値
print(pca.explained_variance_ratio_.sum())   # 累積寄与率 → 0.903

pca90 = PCA(n_components=0.9)       # 0から1の数を渡すと、「累積寄与率がその値を超える数」を自動で選ぶ
pca90.fit(X)
print(pca90.n_components_)          # → 21

分類の前に使うときは、make_pipeline(StandardScaler(), PCA(20), KNeighborsClassifier()) のようにつなげ、主成分の向きを訓練データだけから求めます(第9章のデータリーク対策)。

よくある誤解

  • 「主成分分析は、正解を使って、分類に役立つ向きを探す」: 主成分分析は正解を使わない、教師なし学習 です。「一番広がっている向き」が、分類に役立つ向きとは限りません
  • 「寄与率の小さい主成分は、捨てても必ず問題ない」: 分散が小さくても、分類に大切な違いが含まれていることがあります。まとめた後の正解率で確かめます
  • 「多重共線性があると、予測が大きく外れる」: 予測はあまり悪くなりません。困るのは、係数の大きさや向き(プラスかマイナスか)が信用できなくなることです

振り返り

  • 主成分分析は、データが一番広がっている向き(共分散の表の固有ベクトル)を順に探し、少ない数の軸にまとめる。寄与率は、その軸が表す分散の割合
  • 手書き数字は、64個の特徴量を21個の主成分にまとめても、分散の90%が残る。2次元にまとめると、散布図で見られる
  • 多重共線性は、強く相関する特徴量のせいで係数が不安定になる問題。特徴量を減らす、主成分分析、正則化で和らげる

演習

演習を読み込んでいます…