主成分分析をPythonで実装しよう

2023/08/15

PCA
Python

はじめに

主成分分析をPythonで実装する方法をまとめます。

主成分分析とは

主成分分析(Principal Component Analysis、PCA)は、データの次元削減や特徴量の抽出などに用いられる統計的な手法です。

データの次元削減とは?

データは、さまざまな特徴量(属性)から構成されています。たとえば、身長や体重、趣味の数などがそれぞれの特徴量です。しかし、データが多くの特徴量を持っていると、分析や可視化が難しくなることがあります。
現に、データが膨大になりやすい機械学習において、データの特徴量を減らすことは計算の高速化という点において非常に有用です。
このデータの特徴量を減らす作業を次元削減と言い、次元削減の手法の一つが主成分分析です。

主成分の求め方

主成分分析では、まずデータを平均を中心に配置します。そして、データのバリエーションが最も大きい方向(第1主成分)を見つけます。次に、それに直交する方向で、次にバリエーションが大きい方向(第2主成分)を見つけます。これを繰り返し、元の特徴量の数だけ主成分を見つけます。

バリエーションの保持

主成分分析では、できるだけ多くの元のデータのバリエーションを保持するように主成分を選びます。つまり、元のデータのばらつきをなるべく損なわずに、少ない主成分でデータを表現しようとします。

主成分分析の利用例

主成分分析は、例えば顔認識や経済データ解析など、さまざまな分野で活用されています。また、可視化の面でも効果的であり、高次元のデータを低次元で表現することで、データの特徴を理解しやすくします。

手順の要約

主成分分析の手順を簡単にまとめると以下の通りです。

  1. データを平均を中心に配置する。
  2. データの分散・バリエーションを最大化する方向を求め、第1主成分を得る。
  3. 第1主成分に直交する方向で、次に分散が最大化する方向を求め、第2主成分を得る。
  4. 必要なだけ主成分を繰り返し求める。
  5. 得られた主成分によって元のデータを新しい特徴空間に射影することで、次元削減を達成する。

Pythonで主成分分析をやってみよう

Google Driveをマウントし、CSVファイルからデータを読み込み、主成分分析(PCA)を用いて次元削減とデータの可視化を行うコードを準備しました。
データの標準化、PCAによる主成分の計算と寄与率の表示、PCA空間上でのデータプロット等を実行しています。

# Google ColabでGoogle Driveをマウントするためのライブラリをインポート
from google.colab import drive

# Google Driveをマウント(認証が必要)
drive.mount('/content/drive')

# ファイルパスを指定
## マイドライブの場合
file_path = '/content/drive/MyDrive/foo.csv'
## 共有ドライブの場合
file_path = '/content/drive/Shared drives/bar.csv'

# pandasライブラリをインポート
import pandas as pd

# CSVファイルを読み込んでDataFrameを作成
df = pd.read_csv(file_path)

# DataFrameの先頭部分を表示
print(df.head())

# matplotlib.pyplotとpandasのplottingモジュールをインポート
import matplotlib.pyplot as plt
from pandas import plotting

# 散布図行列を描画(1列目は色分けに使用)
plotting.scatter_matrix(df.iloc[:, 1:], figsize=(8, 8), c=list(df.iloc[:, 0]), alpha=0.5)

# プロットを表示
plt.show()

# 各列のデータを平均0、標準偏差1に標準化したDataFrameを作成
dfs = df.iloc[:, 1:].apply(lambda x: (x - x.mean()) / x.std(), axis=0)

# 標準化されたDataFrameの先頭部分を表示
print(dfs.head())

# sklearnのdatasetsとPCAモジュールをインポート
from sklearn.decomposition import PCA

# PCA(主成分分析)のインスタンスを作成
pca = PCA()

# 標準化されたデータにPCAを適用してモデルを学習
pca.fit(dfs)

# PCAによる次元削減された特徴量を取得
feature = pca.transform(dfs)

# 主成分の特徴量を持つDataFrameを作成
pc_df = pd.DataFrame(feature, columns=["PC{}".format(x + 1) for x in range(len(dfs.columns))])

# 主成分の特徴量を表示
print(pc_df.head())

# 主成分の寄与率を持つDataFrameを作成
explained_variance_df = pd.DataFrame(pca.explained_variance_ratio_, columns=["Explained Variance"])
explained_variance_df.index = ["PC{}".format(x + 1) for x in range(len(dfs.columns))]

# 主成分の寄与率を表示
print(explained_variance_df)

# 主成分の寄与率を棒グラフで表示
plt.figure(figsize=(10, 6))
plt.bar(explained_variance_df.index, explained_variance_df["Explained Variance"])
plt.xlabel("Principal Components")
plt.ylabel("Explained Variance Ratio")
plt.title("Explained Variance Ratio by Principal Component")
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

# PCAによって得られた主成分空間上での散布図を描画(PC1とPC2の関係、1列目は色分けに使用)
plt.figure(figsize=(10, 10))
plt.scatter(feature[:, 0], feature[:, 1], alpha=0.8, c=list(df.iloc[:, 0]))
plt.grid()
plt.xlabel("PC1")
plt.ylabel("PC2")
plt.title("Scatter Plot in PCA Space (PC1 vs PC2)")
plt.show()

今回はここまでです。