線形分離判別 (Linear Discriminant Analysis : LDA)

Posted on 2021/01/18 in 機械学習 , Updated on: 2021/01/18

はじめに

線形判別分析 (Linear Discriminant Analysis : LDA) で、次元削減の目的で使用される。 LDA は PCA と似ているが、LDA は既知のカテゴリ間の分離性を最大化するところに重きを置いている。よって、データの分散が最大となるような軸を探す PCA とは異なり、LDA はカテゴリの正解ラベルが必要になる。

本記事では、sklearnwineデータセット に対して、PCA, LDA を適用して可視化し、その結果を比較する。

インポート

In [55]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
sns.set_style('darkgrid')

from sklearn.datasets import load_wine

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.decomposition import PCA

データセット

wineデータセット を読み出す。全ての特徴量は数値データであるため、このまま LDA, PCA 処理を実行する。

In [56]:
from sklearn import datasets
import pandas as pd

wine = datasets.load_wine()

# 特徴量 データ
df = pd.DataFrame(wine.data, columns=wine.feature_names)
# label データ
y = wine.target
df.head()
Out[56]:
alcohol malic_acid ash alcalinity_of_ash magnesium total_phenols flavanoids nonflavanoid_phenols proanthocyanins color_intensity hue od280/od315_of_diluted_wines proline
0 14.23 1.71 2.43 15.6 127.0 2.80 3.06 0.28 2.29 5.64 1.04 3.92 1065.0
1 13.20 1.78 2.14 11.2 100.0 2.65 2.76 0.26 1.28 4.38 1.05 3.40 1050.0
2 13.16 2.36 2.67 18.6 101.0 2.80 3.24 0.30 2.81 5.68 1.03 3.17 1185.0
3 14.37 1.95 2.50 16.8 113.0 3.85 3.49 0.24 2.18 7.80 0.86 3.45 1480.0
4 13.24 2.59 2.87 21.0 118.0 2.80 2.69 0.39 1.82 4.32 1.04 2.93 735.0

また、label データは 0, 1, 2 の 3つのカテゴリを持つ。つまり、LDA, PCA により 13次元のデータを 2次元データへ次元削減し、それらを軸として可視化した際に、3つのクラスターとしてキレイに分離したい。

In [57]:
np.unique(y)
Out[57]:
array([0, 1, 2])

LDA & PCA

In [64]:
# LDA : label データが必要
lda = LinearDiscriminantAnalysis(n_components=2)
X_lda_reduced = lda.fit(df.values, y).transform(df.values)

# PCA : label データ不要
pca = PCA(n_components=2)
X_pca_reduced = pca.fit_transform(df.values)

# 可視化
plt.figure(figsize=(13, 4))
plt.subplot(121)
plt.scatter(X_lda_reduced[:, 0], X_lda_reduced[:, 1],
            c=y, cmap='viridis', edgecolor='blacK')
plt.title('LDA', fontsize=20)

plt.subplot(122)
plt.scatter(X_pca_reduced[:, 0], X_pca_reduced[:, 1],
            c=y, cmap='viridis', edgecolor='black')
plt.title('PCA', fontsize=20)
plt.show()

PCA の結果と比較して、LDA ではキレイに 3つのクラスターに分離できていることがわかる。PCAは教師なし学習(labelデータを使用しない)であり、本wineデータでは、2次元まで圧縮するとうまく分離できなかった。しかし、LDA はラベルデータを使って、それぞれのカテゴリの分散が小さくなるように(=同じラベルのデータが密集するように)、また、各ラベルの平均値がそれぞれより遠くに配置されるように(=各クラスタがより遠くになるように)計算されるため、上記のようにキレイなクラスタ分離が可能になった。