3種類のワインがあります。
wine.target_names
特徴とクラス両方を含むDataFrameを作成します。
df = X.join(pd.Series(y, name='class'))
線形判別分析は、以下のステップに分けることができる。
- クラス内およびクラス間の散布図
- 散布図の固有ベクトルと対応する固有値
- 固有値をソートして、上位k個
- k個の固有値に対応する固有ベクトルを含む新しい行列
- 新しい特徴(=特徴)を取得する。e. LDA成分)を求める。
Within Class Scatter Matrix
クラス内散布行列を以下の式で計算する。
ここでcは異なるクラスの総数、
まず、最初の二つの固有ベクトルで行列Wを作ります。
w_matrix = np.hstack((pairs.reshape(13,1), pairs.reshape(13,1))).real
そしてXとWのドットプロダクトで新しい行列Yに保存します。
ここでXはnサンプル、d次元のn×d行列、Yはnサンプル、k(k<6307>n)次元のn×k行列である。 言い換えれば、YはLDAの成分で構成され、別の言い方をすれば、新しい特徴空間である。
X_lda = np.array(X.dot(w_matrix))
matplotlib
はカテゴリ変数を直接扱うことができない。
le = LabelEncoder()y = le.fit_transform(df)
次に、2つのLDA成分の関数としてデータをプロットし、各クラスに異なる色を使用します。
plt.xlabel('LD1')
plt.ylabel('LD2')plt.scatter(
X_lda,
X_lda,
c=y,
cmap='rainbow',
alpha=0.7,
edgecolors='b'
)
毎回ゼロから線形判別アルゴリズムを実装するより、scikit-learn
ライブラリで利用できる定義済みLinearDiscriminantAnalysis
クラスを使用することができるのです。
次のプロパティにアクセスして、各成分によって説明される分散を得ることができます。
lda.explained_variance_ratio_
ちょうど前のように、2 つの LDA 成分をプロットします。
plt.xlabel('LD1')
plt.ylabel('LD2')plt.scatter(
X_lda,
X_lda,
c=y,
cmap='rainbow',
alpha=0.7,
edgecolors='b'
)
次に、LDAと主成分分析(PCA)の比較を見ていきましょう。
from sklearn.decomposition import PCApca = PCA(n_components=2)X_pca = pca.fit_transform(X, y)
explained_variance_ratio_
プロパティにアクセスして、各成分によって説明される分散の割合を見ることができます。
pca.explained_variance_ratio_
見てわかるように、PCAでは最も拡散する(最も情報を保つ)成分が選ばれ、必ずしもクラス間の分離を最大化する成分ではありません。
plt.xlabel('PC1')
plt.ylabel('PC2')plt.scatter(
X_pca,
X_pca,
c=y,
cmap='rainbow',
alpha=0.7,
edgecolors='b'
)
次に、LDA成分を特徴として使って分類するモデルが作れるかどうか見てみましょう。 まず、データをトレーニングセットとテストセットに分割します。
X_train, X_test, y_train, y_test = train_test_split(X_lda, y, random_state=1)
次に、決定木を構築してトレーニングします。 テストセットの各サンプルのカテゴリを予測した後、モデルの性能を評価するために混同行列を作成する。
dt = DecisionTreeClassifier()dt.fit(X_train, y_train)y_pred = dt.predict(X_test)confusion_matrix(y_test, y_pred)
見てわかるように、決定木の分類器はテストセットのすべてを正しく分類している。