PCAとUMAPの組み合わせ(次元削減)

高次元データを扱う場合、UMAPのみで次元削減するのではなくPCAの結果をさらにUMAPで次元削減することでよりよい結果になることがあります。

PCA実行

前回と同様にMNISTのデータセットを使って、PCAで次元削減してみます。

[Google Colaboratory]

1
2
3
4
5
6
pca = PCA(n_components=0.99, random_state=0)
X_pc = pca.fit_transform(digits.data)
df_pca = pd.DataFrame(X_pc, columns=["PC{}".format(i + 1) for i in range(len(X_pc[0]))])
print("主成分の数: ", pca.n_components_)
print("保たれている情報: ", np.sum(pca.explained_variance_ratio_))
display(df_pca.head())

[実行結果(一部略)]

n_componentsに0.99を指定している(1行目)ので、累積寄与率が99%になるPC41までが結果として表示されました。

もともとは64次元でしたので23次元が削減されたことになります。

UMAPとPCA+UMAPの比較

PCAの結果に対してさらにUMAPを実行します。(2行目)

また比較のためにUMAPのみを実行した場合の結果も合わせて表示します。(1行目)

n_neighborsには5, 10, 15を指定します。

[Google Colaboratory]

1
2
create_2d_umap(digits.data, digits.target, digits.target_names, [5,10,15])
create_2d_umap(df_pca, digits.target, digits.target_names, [5,10,15])

[実行結果]

上図がUMAPのみの結果、下図がPCA+UMAPの結果となります。

明確にどちらの分類がよいか判断が難しいところですが、分類結果が変わっていることは確認できます。

PCAとUMAPを組み合わせた手法があるということも覚えておくと検証の幅が広がるかと思います。

Python × AI - 主成分と元データの相関(PCA)

前回作成した主成分を解析します。

PCAの結果

PCAの結果から取得できる値は次の通りです。

  • 固有ベクトル : components_
    PCAでデータのばらつきが大きい方向に軸を取り直した結果のベクトル。
    各主成分と元データとの相関関係(-1~1)を意味し、元のデータと主成分の影響度合いを表す。
  • 主成分得点 : explained_variance
    固有ベクトルと元データをかけ合わせた値。
     主成分得点 = 元データ × 固有ベクトル
  • 固有値 : explained_variance_
    固有ベクトルの方向に沿ったデータの分散の大きさ。
    固有値が大きい固有ベクトルほど、データの分散をよく説明しており、データの重要な特徴を捉えている。
    データを標準化している場合、各PCは1以上あれば元データより情報をもっていることになり、4次元データであれば全ての合計は4になる。
  • 寄与率 : explained_variance_ratio_
    固有値から算出した、データ特徴の捉え度合い。
     寄与率 = 固有値 ÷ 固有値の合計

相関図

元データとの関係を固有ベクトル(components)から確認します。

固有ベクトルのヒートマップを表示します。(4~12行目)

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
import seaborn as sns
fig = plt.figure(figsize=(8,6))
ax = fig.add_subplot(111)
sns.heatmap(pca.components_,
cmap="Blues",
annot=True,
annot_kws={"size": 14},
fmt=".2f",
xticklabels=["SepalLength", "SepalWidth", "PetalLength", "PetalLength"],
yticklabels=["PC1", "PC2", "PC3", "PC4"],
ax=ax)
plt.show()

[実行結果]

上図は、各主成分(縦軸)と元データ(横軸)との相関関係を表しています。

PC1をみると、SepalLength、PetalLength、PetalWidthの3つが平均として大きな値となっています。

PC2については、SepalWidthが強く影響しています。

このように主成分がどんな内容の軸になったのかは、PCAの結果を見て判断する必要があります。

Python × AI - 主成分分析(PCA)

主成分分析(PCA:Principal Component Analysis)は、多次元データのもつ情報をできるだけ損なわずに低次元とする方法です。

次元削減で最も簡単な方法であり、広い分野で使われています。

アイリスデータの読み込み

まずアイリスデータを読み込みます。

結果の確認用にtarget_nameに正解の花の名称を追加しています。(5~8行目)

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
import pandas as pd
from sklearn.datasets import load_iris
iris = load_iris()
df=pd.DataFrame(iris.data, columns=iris.feature_names)
df["target"] = iris.target
df.loc[df["target"]==0, "target_name"] = "setosa"
df.loc[df["target"]==1, "target_name"] = "versicolor"
df.loc[df["target"]==2, "target_name"] = "virginica"
df.head()

[実行結果]

アイリスデータの散布図行列

読み込んだアイリスデータを散布図行列で可視化します。

hueパラメータに名称”target_name”を設定することで色をつけています。(2行目)

[Google Colaboratory]

1
2
import seaborn as sns
sns.pairplot(df, vars=df.columns[:4], hue="target_name")

[実行結果]

品種ごとに色分けされていて分類されていることは把握できますが、次元が多いため解釈するのが大変です。

アイリスの3次元立体図

花の品種ごとにpetal_width以外の情報を取得します。(5~6行目)

その後、3次元での可視化を行います。(7~12行目)

[Google Colaboratory]

1
2
3
4
5
6
7
8
9
10
11
12
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(8,6))
ax = fig.add_subplot(1, 1, 1, projection="3d")
for c in df["target_name"].unique():
ax.scatter(df.iloc[:, 0][df["target_name"]==c], df.iloc[:, 1][df["target_name"]==c] , df.iloc[:, 2][df["target_name"]==c], label=c)
ax.set_title("iris 3D")
ax.set_xlabel("sepal_length")
ax.set_ylabel("sepal_width")
ax.set_zlabel("petal_length")
ax.legend(loc=2, title="legend", shadow=True)
plt.show()

[実行結果]

3品種に分かれているように見えますが、petal_widthの情報は全く無視してしまっています。

この情報が特徴量のある重要なデータだったという可能性もあります。

PCAを使用すれば、この4次元データを2次元データで表現することが可能になります。

PCA実行

PCAを実行し(3~4行目)、結果である主成分得点を表示します(5~8行目)。

[Google Colaboratory]

1
2
3
4
5
6
7
8
from sklearn.decomposition import PCA
import numpy as np
pca = PCA(random_state=0)
X_pc = pca.fit_transform(df.iloc[:, 0:4])
df_pca = pd.DataFrame(X_pc, columns=["PC{}".format(i + 1) for i in range(len(X_pc[0]))])
print("主成分の数: ", pca.n_components_)
print("保たれている情報: ", np.sum(pca.explained_variance_ratio_))
display(df_pca.head())

[実行結果]

横軸が主成分(PC:Principal Component)で、縦軸が各サンプルを表します。

主成分(PC)とは、データを要約(縮小)したあとの新しい合成変数で、第1主成分(PC1)に最も多くの情報が集まっていて第2主成分(PC2)以降にだんだんと情報が小さくなります。

PC1とPC2を可視化

多くの情報が集まっているPC1PC2を可視化します。

[Google Colaboratory]

1
sns.scatterplot(x="PC1", y="PC2", data=df_pca, hue=df["target_name"])

[実行結果]

4次元あったデータを2次元で可視化することができました。

うまく3種類に分類されています。

PCAの用途はいくつかあるのですが、多次元データの特徴を低次元に次元削減し可視化する手段としてとても有効です。


Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×