ケイエルブイは、ハイパースペクトルカメラ・光学部品・光源など世界中の光学機器を取り扱う専門商社です。

03-3258-1238

お問い合わせ
KLV大学 ハイパースペクトルカメラコース
spectral-analysis-python-top.jpg

[2.2] Pythonで主成分分析(PCA)を行う
②Pythonコマンド編

[2.2] Pythonで主成分分析(PCA)を行う ①基礎知識編では、主成分分析(PCA)の基本的な考え方や、スコア・ローディングの意味について説明しました。
②Pythonコマンド編では、これらの知識をベースに、Pythonの機械学習ライブラリである「scikit-learn」を使って実際にPCAを行う方法を解説していきます。

本記事では、PCA解析のサンプルプログラムを紹介する前に、PCAの実行に使用する主なコマンドと、その役割について説明します。

1. PCAの基礎知識

PythonでPCAを実行する前に、PCAから得られる主な結果についての理解が重要です。

PCAでは、多数の変数を持つデータから、データのばらつきをよく表す新しい軸として第一主成分(PC1)、第二主成分(PC2)などを求めます。

そして、解析結果を理解するうえで特に重要なのが、「どの試料が、どのように違うのか」を示す「スコア」と、「その違いに、どの波長が関係しているのか」を示す「ローディング」の2つです。

PCAの主成分やスコア・ローディングについては、前の記事で詳しく解説しています。
基礎知識を復習する方は、[2.2] Pythonで主成分分析(PCA)を行う ①基礎知識編」を確認してください。

2. PythonでPCAを実行する準備

2.1 使用ライブラリの種類

PythonでPCAを実行する際に便利なライブラリを準備します。
今回使用するのは、NumPy、Matplotlib、scikit-learnです。

ライブラリ 主な役割
NumPy 数値計算を行うためのライブラリ
複数の数値を行列(配列)として扱うことができ、
PCAに入力するデータの作成や加工などに便利
Matplotlib グラフを作成するためのライブラリ
折れ線グラフや散布図など、さまざまなグラフを作成でき、
PCAのスコアプロットやローディングプロットを描くのに便利
scikit-learn 機械学習、データ解析のための機能を搭載したライブラリ
分類、回帰、次元削減など、さまざまな解析手法が用意されており、
sklearn.decompositionに含まれるPCAクラスでPCAを実行可能

2.2 使用ライブラリのインストール

ライブラリをインストールする場合は、以下のコマンドを実行します。

pip install numpy matplotlib scikit-learn

※すでにインストール済みの場合は、この操作は不要です。

2.3 使用ライブラリのインポート

これらライブラリを使用する場合には、プログラムの先頭で必要なライブラリをインポートします。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA

特に、PCAを行ううえで中心となるのが「scikit-learn」です。
具体的なコマンドの前に、scikit-learnがどのようなライブラリなのかを簡単に解説します。

scikit-learnとは

scikit-learnには、データの分類や予測、特徴の抽出などに必要なさまざまなアルゴリズムが用意されており、複雑な計算を一からプログラムすることなく、シンプルなコードでデータ解析を実行できます。

PCA_scikit-learn

→ scikit-learn 公式サイト

scikit-learnは、「分類」「回帰」「クラスタリング」「次元削減」「モデル選択」「前処理」など、データ解析に必要となる機能が提供されています。

①分類

データがどのカテゴリーに属するのかを判定するための機能です。
例えば、スペクトルデータから「物質A」「物質B」といった種類を判別する場合に利用できます。

②回帰

データから連続した数値を予測するための機能です。
例えば、スペクトルデータから水分量や成分濃度などを推定する場合に利用できます。

③クラスタリング

特徴が似ているデータを自動的にグループ化するための機能です。
例えば、多数のスペクトルデータから、似た特徴を持つ試料がどのようなグループを形成しているのかを調べる場合に利用できます。
クラスタリングと分類は、どちらもデータをグループに分けるため、一見すると似ていますが、分類が、「物質A」「物質B」のような正解ラベルを与えてモデルを学習させるのに対して、クラスタリングでは正解ラベルを与えず、データそのものの特徴や類似性をもとにグループ化します。

④次元削減

多数の変数が持つ情報を、より少ない変数で表現するための機能です。
例えば、数十~数百の波長を持つスペクトルデータを少数の特徴にまとめることで、データ全体の傾向を把握しやすくできます。

この記事で説明する主成分分析(PCA)は、この「次元削減」に分類される代表的な手法です。

⑤モデル選択

作成したモデルの性能を評価したり、適切なパラメータを検討するための機能です。
例えば、交差検証によってモデルの性能を確認したり、複数の条件を比較して適切なパラメータを探す場合に利用できます。

⑥前処理

機械学習やデータ解析を行いやすいように、入力するデータを整えるための機能です。
例えば、データの標準化や正規化などを行い、解析に適した状態へ変換することができます。

3. PCAで使用するscikit-learnの基本コマンド

PCAを実行するときに使用する4つのコマンドを紹介します。

分類 コマンド 役割
PCAを実行 PCA() PCAモデルを作成。
求める主成分数などの条件を設定する
fit_transform() データから主成分を求め、各サンプルを主成分空間へ変換する
PCAの結果を分析 explained_variance_ratio_ 各主成分の寄与率を取得する
components_ 各主成分を構成する係数を取得する

それぞれの詳細について紹介します。

3.1 PCA()コマンド:PCAモデルを作成

まず、以下のようにPCA()を使用してPCAモデルを作成します。

pca = PCA(n_components=2)

PCAのコマンドに設定しているn_componentsは、解析に使用する主成分の数を指定するパラメータです。

例えば、n_components=2とすると、PC1とPC2の2つの主成分を求めます。
このコマンドの実行時点ではまだデータの解析は行われておらず、PCAを実行するための条件を設定した段階です。

PCA()コマンドの詳細

PCA()には、n_components以外にも、PCAの計算方法やデータの処理方法を指定するためのオプションが用意されています。
ここでは、その中から代表的なオプションについて簡単に解説します。

参考:PCAオプションのOffitial Siteの解説

class sklearn.decomposition.PCA(
    n_components=None,
    copy=True,
    whiten=False,
    svd_solver='auto',
    tol=0.0,
    iterated_power='auto',
    n_oversamples=10,
    power_iteration_normalizer='auto',
    random_state=None
)
・whitenオプション

PCAによって変換された主成分に対して「白色化(Whitening)」を行うかを指定するオプションです。

初期値はFalseで、各主成分が持つ分散の大きさを維持したままデータを主成分空間へ変換します。

「白色化」を有効にすると、PC1やPC2などの各主成分のばらつきの大きさが同じになるように調整します。これにより、各主成分を同じスケールで扱えるようになり、機械学習モデルへ入力する場合などに有効なことがあります。
ただし、各主成分がもともと持っていた相対的な分散の大きさに関する情報は失われるため、スコアや寄与率などからPCAの結果を確認・解釈したい場合は初期値(False)のまま使用してください。

・svd_solverオプション

PCAで主成分を求める際に使用する計算方法を指定するオプションです。

初期値は'auto'で、入力データの大きさやn_componentsの設定に応じて計算方法が自動的に選択されます。
通常は'auto'のままで問題ありませんが、計算方法を固定することで、データのや条件が変わっても同じ方法でPCAを実行できます。
また、大規模なデータを扱う場合は、データの特徴に適した計算方法を指定することで、計算時間やメモリ使用量を抑えられる場合があります。

設定値 概要
'full' データ全体を使って主成分を計算する方法です。 計算量は多くなりますが、主成分を正確に求めたい場合に使用します。
'covariance_eigh' データのばらつきや変数同士の関係を表す「共分散行列」を作成して、主成分を求める方法です。 サンプル数が多く、変数の数が比較的少ないデータに適しています。
'arpack' すべての主成分を計算するのではなく、必要な一部の主成分だけを求める方法です。 使用する主成分数が少ない場合などに利用できます。
'randomized' ランダム化された計算方法を利用して、必要な主成分を効率よく求める方法です。 データ量が多く、計算時間を短縮したい場合などに適しています。
・random_stateオプション

PCAの計算で使用される乱数を制御するためのオプションです。
初期値はNoneで、乱数の生成条件を固定しないため、乱数を使用する計算方法では、実行するたびに結果がわずかに異なる場合があります。

svd_solver='arpack', 'randomized'など、一部の計算方法では計算過程で乱数を使用します。
そのため、同じデータを処理しても、設定によっては実行ごとに計算結果にわずかな違いが生じる場合があります。

比較評価を行う場合などは、random_stateに整数を指定して、乱数の生成条件を固定することで、計算結果の再現性を高めることが可能です。

random_stateが計算結果に影響するかどうかは、使用するsolverによって異なります。svd_solver='auto'の場合は、データの条件によってsolverが変わるためその点にも注意してください。

3.2 fit_transform()コマンド:主成分の計算と変換

fit_transform()は、入力したデータから主成分を求めるfit()と、求めた主成分を使って元のデータを主成分空間へ変換するtransform()を、まとめて実行するコマンドです。

scores = pca.fit_transform(X)

スペクトル解析でfit_transform()を使用する場合、Xには「行=サンプル、列=波長」となる2次元のスペクトルデータを入力します。

例えば、50個の試料を300波長で測定した場合、Xには「50 × 300」の、各要素にそれぞれの波長で測定された吸光度や反射率などの値が入った行列を指定します。

細かな設定は、fit_transform()ではなく、その前のPCA()で指定するという関係になるため、基本的にPCA解析で設定が必要となるオプションはありません。

3.3 explained_variance_ratio_コマンド:寄与率を確認

PCAを実行した後に、各主成分の寄与率を取得するために使用します。

pca.explained_variance_ratio_

実行すると、PC1、PC2、PC3……の順に、それぞれの寄与率が配列として返されます。 例えば、PC1とPC2の2つの主成分を求めた場合、以下のような結果が得られます。

array([0.80, 0.15])

この場合、最初の0.80がPC1、次の0.15がPC2の寄与率を表しています。 寄与率は、それぞれの主成分が元データのばらつきをどの程度説明しているかを表す値です。

また、PC1の寄与率を取得する場合は[0]、PC2の場合は[1]を指定することで、特定の主成分の寄与率だけを取得することもできます。

pca.explained_variance_ratio_[0]  # PC1の寄与率
pca.explained_variance_ratio_[1]  # PC2の寄与率

寄与率は0~1の値で取得されるため、パーセント(%)表示したい場合は、100をかける必要があります。

3.4 components_コマンド:ローディングを確認

components_は、PCAを実行した後に、各主成分を構成する係数を取得するために使用します。

pca.components_

実行すると、PC1、PC2、PC3……の順に、それぞれの主成分を構成する係数が2次元の配列として返されます。 例えば、4つの波長からなるスペクトルデータに対して、PC1とPC2の2つの主成分を求めた場合、以下のような結果が得られます。

array([
    [ 0.52,  0.61, -0.42, -0.43],
    [-0.35,  0.21,  0.68, -0.60]
])

この場合、1行目がPC1、2行目がPC2を構成する係数です。 また、それぞれの列は、入力したスペクトルデータの各波長に対応しています。

特定の主成分の係数だけを取得することもできます。 PC1の場合は[0]、PC2の場合は[1]を指定します。

pca.components_[0]  # PC1の係数
pca.components_[1]  # PC2の係数

スペクトルデータの場合は、取得した係数を波長に対してプロットすることで、どの波長が各主成分に強く関係しているのかを確認できます。 一般的には、係数の絶対値が大きい波長ほど、その主成分を構成するうえで強く関係していると考えます。

plt.plot(wavelengths, pca.components_[0])
plt.xlabel("Wavelength")
plt.ylabel("Loading")
plt.show()

なお、components_は厳密にはscikit-learnにおける各主成分軸の係数です。 「ローディング」という言葉には定義の違いがありますが、ここでは各主成分を構成する波長ごとの係数として扱います。

4. スペクトルデータにPCAを適用するプログラム

ここまで、scikit-learnを使ってPCAを行うための基本的なコマンドについて説明しました。

実際にスペクトルデータを解析する場合は、データを読み込んでPCAを実行するだけでなく、得られた結果を確認して分析していきます。

次の記事では、ここまで説明したコマンドを用いて、以下の流れのPCA解析を行うプログラムをPythonで実行する方法を解説します。

PCA解析フロー図
次の記事

サンプルのスペクトルデータを使用して、PythonプログラムでPCAの実行から、寄与率、スコアプロット、ローディングプロットの確認までを解説。

→[2.2] Pythonで主成分分析(PCA)を行う ③Pythonサンプルプログラム編

ハイパースペクトルカメラコース

ご質問・ご相談お気軽にお問い合せください

お電話でのお問合せ 03-3258-1238 受付時間 平日9:00-18:00(土日祝日除く)
Webでのお問い合わせ