非IT企業に勤める中年サラリーマンのIT日記

非IT企業でしかもITとは全く関係ない部署にいる中年エンジニア。唯一の趣味がプログラミングという”自称”プログラマー。

【Python】分類可視化をやってみた:PCAとLDAでデータを見やすくする

   

データ解析では、特徴量を視覚的に理解することが重要ですが、高次元データではそれが難しい場合があります。今回は、Irisデータセットを使って、次元削減なしでの可視化の限界を確認し、PCA(主成分分析)とLDA(線形判別分析)を用いてどのように改善できるかを試してみます。それぞれの特徴や実装例、そして可視化結果をわかりやすく解説していきます。

次元削減なしで特徴量を可視化

まずは、次元削減を行わず、sepal length(がく片の長さ)とsepal width(がく片の幅)の2つの特徴量を使って可視化してみます。

import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
import pandas as pd

# Irisデータセットをロード
iris = load_iris()
data = pd.DataFrame(iris.data, columns=iris.feature_names)
data['target'] = iris.target
data['species'] = data['target'].map({0: 'setosa', 1: 'versicolor', 2: 'virginica'})

# 特徴量を2つ選択(sepal length と sepal width)
x_feature = 'sepal length (cm)'
y_feature = 'sepal width (cm)'

# グラフを作成
plt.figure(figsize=(8, 6))
for species, color in zip(['setosa', 'versicolor', 'virginica'], ['red', 'green', 'blue']):
    subset = data[data['species'] == species]
    plt.scatter(subset[x_feature], subset[y_feature], label=species, color=color)

# グラフの設定
plt.title(f'Iris Dataset: {x_feature} vs {y_feature}')
plt.xlabel(x_feature)
plt.ylabel(y_feature)
plt.legend()
plt.grid(True)
plt.show()
 

 

結果と問題点

このプロットでは、setosa(赤)は分離されていますが、versicolor(緑)とvirginica(青)の間に重なりが見られます。これは、2つの特徴量だけではクラス間の差異を十分に表現できないためです。高次元データを次元削減なしで可視化すると、データの本質を捉えづらいことがわかります。

 

PCA(主成分分析)による次元削減

PCAは、データの分散を最大化する方向を見つけることで次元削減を行います。クラス情報を考慮せず、全体の構造を把握するのに適しています。

以下は、IrisデータセットにPCAを適用し、次元を2つに削減した実装例です。

import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
import pandas as pd
from sklearn.decomposition import PCA

# Irisデータセットをロード
iris = load_iris()

# PCAを適用
pca = PCA(n_components=2)
principal_components = pca.fit_transform(iris.data)

# 結果をプロット
plt.figure(figsize=(8, 6))
colors = ['red', 'green', 'blue']
for target, color in zip([0, 1, 2], colors):
    subset = principal_components[iris.target == target]
    plt.scatter(subset[:, 0], subset[:, 1], label=iris.target_names[target], color=color)

plt.title('PCA on Iris Dataset')
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.legend()
plt.grid(True)
plt.show()
 

 

グラフの解説

このグラフでは、PCAによって全体の分散がよく表現されています。ただし、クラス情報を考慮しないため、versicolor(緑)とvirginica(青)の間に重なりが残ります。それでも、次元削減なしのグラフよりもクラスの分布が明確になっているのがわかります。

 

DA(線形判別分析)による次元削減

LDAは、クラス間の分離を最大化する方向を見つける次元削減手法です。分類タスクにおいては、PCAよりも適している場合があります。

以下は、IrisデータセットにLDAを適用した例です。

import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
import pandas as pd
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA

# Irisデータセットをロード
iris = load_iris()

# LDAを適用
lda = LDA(n_components=2)
lda_components = lda.fit_transform(iris.data, iris.target)

# 結果をプロット
plt.figure(figsize=(8, 6))
colors = ['red', 'green', 'blue']
for target, color in zip([0, 1, 2], colors):
    subset = lda_components[iris.target == target]
    plt.scatter(subset[:, 0], subset[:, 1], label=iris.target_names[target], color=color)

plt.title('LDA on Iris Dataset')
plt.xlabel('Linear Discriminant 1')
plt.ylabel('Linear Discriminant 2')
plt.legend()
plt.grid(True)
plt.show()
 

 

グラフの解説

LDAを用いることで、setosa(赤)は完全に分離されました。一方で、versicolor(緑)とvirginica(青)は、重なりが減少したものの、完全には分離しきれていない箇所が残っています。これは、特徴量間の分布の違いがまだ十分に反映されていないためです。ただし、次元削減なしの結果と比較すると、分類のしやすさが向上していることが分かります。

まとめ

特徴量をそのまま可視化するだけでは、高次元データの本質を掴むことが難しい場合があります。PCAとLDAを用いることで、データの重要な特徴を抽出しながら次元削減を行い、可視化や分析の精度を向上させることができます。

  • PCA: クラス情報を考慮せず、データ全体の分散を表現するのに適している。
  • LDA: クラス間の分離を最大化し、分類タスクで非常に効果的。

データ解析の目的に応じて、PCAとLDAをうまく使い分けましょう!

 

スポンサーリンク

 - Python