導入
このコードチャレンジでは、教師なし次元削減手法である PCA を実装します。PCA は、データ分析とデータ視覚化に関して非常に幅広い用途があります。したがって、PCA を自分でゼロから実装できれば、さらなるメリットが得られると考えています。コード チャレンジの前に、重要な注意事項が 1 つあります。コード チャレンジ中は最小限の実装のみをお願いします。これが業界での PCA の実装方法であるとは限りません。ご興味がございましたら、sklearn 公式オープンソース コードをご覧ください。
主成分分析
PCA では、データの最大限の情報が保存されるように、元の高次元データを低次元空間に投影するための線形マッピングを見つけたいと考えています。講義で説明したように、最大限の情報を保存するという目標は、数学の言語に翻訳すると、次の 2 つのルールで表されることを思い出してください。
-
次元は互いに独立しています。
-
投影されたデータには最大の分散があります。
最適化問題を解くことで、PCA の変換行列が、対応する固有値が最大から最小の順にソートされた共分散行列の固有ベクトルで構成されていることがわかります。
講義ですでに説明した PCA の疑似コードは次のとおりです。
命令
実装する必要がある関数のリストは次のとおりです。
-
PCA.fit(X) : データXを近似し、変換行列self.eig_vecsを学習します。
-
PCA.transform(X, n_components=1) :学習した変換行列self.eig_vecsを使用してデータXを変換します。
-
PCA.fit_transform(X, n_components=1) : データXを近似し、 Xの変換結果を返します。
以下は、実装されたPCAクラスが実際のアプリケーションでどのように使用されるかを示す短い例です。
ここでは、最初に LinearReg オブジェクトを作成し、次にそれをトレーニング データに適合させ、トレーニング データとテスト データの損失値を計算します。
import numpy as np
class PCA(object):
def __init__(self):
# Initialize the eigenvectors and eigenvalues
self.eig_vals, self.eig_vecs = None, None
def fit(self, X):
# implement the .fit() following the algorithm described during the lecture.
# HINT (PCA pseudo code):
# 1. zero-mean the input X;
# 2. compute the covariance matrix
# 3. compute the eigen values and eigen vectors using function **np.linalg.eig()**
# 4. sort the eigen values and eigenvectors using function **np.argsort()**.
# 5. store the eigen vectors
# zero-mean the input X
X_centered = X - np.mean(X, axis=0)
# compute the covariance matrix
cov_matrix = np.cov(X_centered.T)
# compute the eigen values and eigen vectors using np.linalg.eig()
eig_vals, eig_vecs = np.linalg.eig(cov_matrix)
# sort the eigen values and eigenvectors in descending order
sorted_idx = np.argsort(eig_vals)[::-1]
self.eig_vals = eig_vals[sorted_idx]
self.eig_vecs = eig_vecs[:, sorted_idx]
pass
def transform(self, X, n_components=1):
# implement the .transform() using the parameters learned by .fit()
# NOTE: don't forget to 0-mean the input X first.
# Check that we have learned eigenvectors and eigenvalues
assert self.eig_vecs is not None and self.eig_vals is not None, "Fit the model first!"
# 0-mean the input X
X_centered = X - np.mean(X, axis=0)
# Project the centered data onto the principal components
P = self.eig_vecs[:, :n_components]
X_pca = np.dot(X_centered, P)
return X_pca
pass
def fit_transform(self, X, n_components=1):
# implement the PCA transformation based on the .fit() and .transform()
self.fit(X)
return self.transform(X, n_components)
pass