次元削減をマスターしよう!【主成分分析編】
データ分析の前処理としてよく用いられる次元削減手法のひとつである主成分分析をご紹介します。
次元削減とは?
次元削減とは、データセット内の特徴量の数や次元を削減するプロセスのことです。モデル作成の前処理のひとつとしてよく行われます。次元削減のメリットとしては次のようなことが挙げられます。
- 特徴量選択: 機械学習モデルに寄与しない特徴量を特定し、これらを削除することで、モデルの性能を向上させられます。
- 計算効率の向上: 多くの特徴量がある場合、計算コストが高く、アルゴリズムの実行が遅くなってしまいますが、次元削減により計算効率を向上させることが可能です。
- 可視化: 高次元のデータを2次元または3次元に削減することで、データの可視化ができるようになり、データの構造が理解しやすくなります。
次元削減と聞くと、主成分分析(PCA)を思い浮かべる方が多いと思いますが、次元削減の手法にはさまざまなものがあります。各手法の特性を理解して、分析用途にあったものを使い分けることができるといいですね。
- 主成分分析(PCA)
- 独立主成分分析(ICA)
- t-分布型確率的隣接埋め込み(t-SNE)
- 線形判別分析(LDA)
- 非負値行列因子分解(NMF)
- 自己符号化器(Autoencoder)
今回は、主成分分析について取り上げます。他の手法についても、また別の記事で紹介したいと考えています。
次元削減のイメージ
「平面上(2次元)に広がるデータを、1本の直線(1次元)で表したい・・・」
→主成分分析では、この直線の”方向”を計算で求める。
主成分分析(PCA)とは?
まず、主成分分析(PCA)、学習データにおいて**「分散」=「情報」**ととらえ、情報をできるだけ残す(分散が大きくなる)ような方向にデータを圧縮します。
具体的には、最初の主成分(これを第1主成分といいます)は学習データの中で最も分散が大きい方向にとります。これは元のデータセットの情報を最大限に保持している方向です。
第1主成分が決まった後、第2主成分は第1主成分と直交し、かつ第1主成分に対して分散が最大となるように取ります。つまり、第2主成分は残りのデータの中で最も分散が大きい方向となります。このプロセスを元のデータの次元数まで繰り返します。
主成分分析のアルゴリズム
STEP 1:標準化 : 異なるスケールの変数を、同じスケールに揃えます。
STEP 2:共分散行列の計算: 標準化されたデータの共分散行列を計算します。
STEP 3:固有値分解: 共分散行列を固有値分解します。これにより、固有値とそれに対応する固有ベクトルが得られます。
STEP 4:固有値の降順でソート: 固有値を大きい順に並べます。これにより、分散が最も大きい方向(主成分)から順に取り出すことができます。
STEP5:主成分の選択: 上位k個の主成分を選択します。
ここで、各主成分が元データの分散のうち、どれだけを説明できるかを示す割合を
**寄与率(Explained Variance Ratio)**といいます。これは、その主成分の固有値を元データの全体の固有値の総和で割ったものです。寄与率が高い主成分ほど、元データの情報をよく表現しています。
次に、寄与率を主成分ごとに足し上げたものを**累積寄与率(Cumulative Explained Variance Ratio)といいます。**累積寄与率は、データのどれくらいの情報を維持したいかを決定するのに役立ちます。ある閾値(例: 0.95など)を決めて、その値を超えるように主成分を選ぶことが一般的です。
※主成分分析の細かな導出は、こちらの記事
https://www.hello-statisticians.com/explain-terms-cat/pca1.html
を参考にしてみてください。(大学1年生レベルの線形代数と微積分の知識が仮定されています。紙とペンを持ってじっくりと式を追うことをおすすめします!)
pythonで実装してみよう!
共分散行列、固有値分解・・・と小難しい単語が出てきましたね。しかしpythonでは、
from sklearn.decomposition import PCA
を用いて、非常に簡単に実装することができます。今回は、Wineデータセットを使います。これは、以下の13個の特徴量と、3種類のワインのいずれかを示すラベルで構成されるデータセットです。こちらは、scikit-learnのサンプルデータセットに含まれています。
- alcohol: アルコール度数
- malic_acid: リンゴ酸
- ash: 灰分(かいぶん)
- alcalinity_of_ash: 灰分のアルカリ度
- magnesium: マグネシウム
- total_phenols: 全フェノール含量
- flavanoids: フラボノイド
- nonflavanoid_phenols: 非フラボノイドフェノール
- proanthocyanins: プロアントシアニン
- color_intensity: 色の濃さ
- hue: 色相
- od280/od315_of_diluted_wines: 希釈ワイン溶液のOD280/OD315(=280nmと315nmの吸光度の比)
- proline: プロリン
PCAを実行するコードは次のとおりです。
import numpy as np
from sklearn.datasets import load_wine
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
wine = load_wine()
X_wine = wine.data
scaler = StandardScaler()
X= scaler.fit_transform(X_wine)
pca = PCA()
X_pca = pca.fit(X)
主成分分析の結果を解釈
先のコードを実行した結果、以下の結果が得られます。
1つ目のグラフは各種主成分の寄与率を表すものです。このグラフより、第1主成分ではデータの36%を説明し、続く第2主成分ではデータの11%を説明していることがわかります。
2つ目のグラフは累積寄与率を表しています。第6主成分までで全体の85%を説明していることが読み取れます。もし、元データの情報を90%以上残したいのであれば、第8主成分まで取れば良いですね。
では、第1主成分特徴ベクトルからどのようなことが分かるでしょうか?
その特徴を見るためには、第1主成分の特徴ベクトルの要素を確認します。
この特徴ベクトルの各要素は第1主成分における影響度合いを表します。今回の例では、flavanoidとtotal_phenolsの値が大きくなっていますね。これより、ワインを特徴づけるものとして、「フラボノイド」と「全フェノール量」が大きな要因なのでは?と考察できます。
# 第1主成分の特徴ベクトル
first_principal_component = pca.components_[0]
# 結果を表示
df = pd.DataFrame(first_principal_component, index=wine.feature_names, columns=['First Principal Component'])
print(df)
以上、主成分分析についての解説でした。
普段何となく使っている手法も、より詳しく見てみると理解が深まりますね!