はじめに
この実験では、線形判別分析(LDA:Linear Discriminant Analysis)とそれを分類にどのように使用できるかを紹介します。Python の人気のある機械学習ライブラリである scikit - learn を使用して LDA を実装します。また、共分散の Ledoit - Wolf 推定器とオラクル収縮近似(OAS:Oracle Shrinkage Approximating)推定器が分類をどのように改善できるかを検討します。
VM のヒント
VM の起動が完了した後、左上隅をクリックしてノートブックタブに切り替え、Jupyter Notebook を使って練習しましょう。
時々、Jupyter Notebook が読み込み終了するまで数秒待つ必要がある場合があります。Jupyter Notebook の制限により、操作の検証を自動化することはできません。
学習中に問題に直面した場合は、Labby にお問い合わせください。セッション後にフィードバックを提供してください。すぐに問題を解決いたします。
ランダムなデータを生成する
まず、識別的な特徴とノイズのある特徴を持つランダムなデータを生成する必要があります。識別的な特徴 1 つで 2 つのクラスターのデータを生成するために、scikit - learn のmake_blobs関数を使用します。その後、他の特徴にランダムなノイズを追加します。
import numpy as np
from sklearn.datasets import make_blobs
def generate_data(n_samples, n_features):
"""ノイズのある特徴を持つランダムなブロブ状のデータを生成する。
これは形状`(n_samples, n_features)`の入力データの配列と
`n_samples` のターゲットラベルの配列を返す。
識別的な情報を含むのは 1 つの特徴だけで、他の特徴はノイズのみを含む。
"""
X, y = make_blobs(n_samples=n_samples, n_features=1, centers=[[-2], [2]])
## 識別的でない特徴を追加する
if n_features > 1:
X = np.hstack([X, np.random.randn(n_samples, n_features - 1)])
return X, y
LDA を実装する
次に、scikit - learn のLinearDiscriminantAnalysisクラスを使用して LDA を実装します。3 つの分類器を作成します。
- 収縮なしの LDA
- Ledoit - Wolf 収縮を伴う LDA
- OAS 収縮を伴う LDA
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.covariance import OAS
clf1 = LinearDiscriminantAnalysis(solver="lsqr", shrinkage=None)
clf2 = LinearDiscriminantAnalysis(solver="lsqr", shrinkage="auto")
oa = OAS(store_precision=False, assume_centered=False)
clf3 = LinearDiscriminantAnalysis(solver="lsqr", covariance_estimator=oa)
分類器を学習と評価する
生成したデータで各分類器の性能を確認するため、それぞれの分類器を学習と評価します。このプロセスを複数回繰り返して平均的な正解率を得ます。
n_train = 20 ## 学習用のサンプル数
n_test = 200 ## 評価用のサンプル数
n_averages = 50 ## 分類を繰り返す回数
n_features_max = 75 ## 最大の特徴数
step = 4 ## 計算の刻み幅
acc_clf1, acc_clf2, acc_clf3 = [], [], []
n_features_range = range(1, n_features_max + 1, step)
for n_features in n_features_range:
score_clf1, score_clf2, score_clf3 = 0, 0, 0
for _ in range(n_averages):
X, y = generate_data(n_train, n_features)
clf1.fit(X, y)
clf2.fit(X, y)
clf3.fit(X, y)
X, y = generate_data(n_test, n_features)
score_clf1 += clf1.score(X, y)
score_clf2 += clf2.score(X, y)
score_clf3 += clf3.score(X, y)
acc_clf1.append(score_clf1 / n_averages)
acc_clf2.append(score_clf2 / n_averages)
acc_clf3.append(score_clf3 / n_averages)
結果を可視化する
最後に、各分類器の分類精度を特徴数の関数としてプロットします。このプロットを作成するために matplotlib を使用します。
import matplotlib.pyplot as plt
features_samples_ratio = np.array(n_features_range) / n_train
plt.plot(
features_samples_ratio,
acc_clf1,
linewidth=2,
label="LDA",
color="gold",
linestyle="solid",
)
plt.plot(
features_samples_ratio,
acc_clf2,
linewidth=2,
label="LDA with Ledoit Wolf",
color="navy",
linestyle="dashed",
)
plt.plot(
features_samples_ratio,
acc_clf3,
linewidth=2,
label="LDA with OAS",
color="red",
linestyle="dotted",
)
plt.xlabel("n_features / n_samples")
plt.ylabel("Classification accuracy")
plt.legend(loc="lower left")
plt.ylim((0.65, 1.0))
plt.suptitle(
"LDA (Linear Discriminant Analysis) vs. "
+ "\n"
+ "LDA with Ledoit Wolf vs. "
+ "\n"
+ "LDA with OAS (1 discriminative feature)"
)
plt.show()
まとめ
この実験では、scikit - learn を使って線形判別分析(LDA:Linear Discriminant Analysis)を実装する方法を学びました。共分散の Ledoit - Wolf 推定器とオラクル収縮近似(OAS:Oracle Shrinkage Approximating)推定器が分類精度をどのように向上させるかを検討しました。また、識別的な特徴を持つランダムなデータを生成し、このデータで分類器をテストしました。最後に、分類精度を特徴数の関数として可視化しました。