顔データセットの分解

Machine LearningMachine LearningBeginner
今すぐ練習

This tutorial is from open-source community. Access the source code

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

この実験では、モジュール sklearn.decomposition からのさまざまな非監督学的行列分解(次元削減)手法を、オリベッティ顔データセットに適用します。オリベッティ顔データセットは、40人の人物の64x64ピクセルのサイズの400枚の顔から構成されており、それぞれが異なる表情と照明条件で撮影されています。

VMのヒント

VMの起動が完了したら、左上隅をクリックして ノートブック タブに切り替え、Jupyter Notebookを使って練習しましょう。

時々、Jupyter Notebookが読み込み終了するまで数秒待つ必要がある場合があります。Jupyter Notebookの制限により、操作の検証は自動化できません。

学習中に問題に遭遇した場合は、Labbyにお問い合わせください。セッション後にフィードバックを提供してください。すぐに問題を解決いたします。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL sklearn(("Sklearn")) -.-> sklearn/UtilitiesandDatasetsGroup(["Utilities and Datasets"]) ml(("Machine Learning")) -.-> ml/FrameworkandSoftwareGroup(["Framework and Software"]) sklearn/UtilitiesandDatasetsGroup -.-> sklearn/datasets("Datasets") ml/FrameworkandSoftwareGroup -.-> ml/sklearn("scikit-learn") subgraph Lab Skills sklearn/datasets -.-> lab-49124{{"顔データセットの分解"}} ml/sklearn -.-> lab-49124{{"顔データセットの分解"}} end

データセットの準備

まず、オリベッティ顔データセットを読み込み、前処理を行います。データをゼロ平均にするために、グローバル(1つの特徴に焦点を当ててすべてのサンプルを中心化)とローカル(1つのサンプルに焦点を当ててすべての特徴を中心化)の両方で中心化します。また、顔のギャラリーを描画するための基本関数も定義します。

## オリベッティ顔データセットを読み込み、前処理を行う。

import logging

from numpy.random import RandomState
import matplotlib.pyplot as plt

from sklearn.datasets import fetch_olivetti_faces
from sklearn import cluster
from sklearn import decomposition

rng = RandomState(0)

## 標準出力に進捗ログを表示する
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")

faces, _ = fetch_olivetti_faces(return_X_y=True, shuffle=True, random_state=rng)
n_samples, n_features = faces.shape

## グローバル中心化(1つの特徴に焦点を当ててすべてのサンプルを中心化)
faces_centered = faces - faces.mean(axis=0)

## ローカル中心化(1つのサンプルに焦点を当ててすべての特徴を中心化)
faces_centered -= faces_centered.mean(axis=1).reshape(n_samples, -1)

print("Dataset consists of %d faces" % n_samples)

## 顔のギャラリーを描画するための基本関数を定義する。

n_row, n_col = 2, 3
n_components = n_row * n_col
image_shape = (64, 64)


def plot_gallery(title, images, n_col=n_col, n_row=n_row, cmap=plt.cm.gray):
    fig, axs = plt.subplots(
        nrows=n_row,
        ncols=n_col,
        figsize=(2.0 * n_col, 2.3 * n_row),
        facecolor="white",
        constrained_layout=True,
    )
    fig.set_constrained_layout_pads(w_pad=0.01, h_pad=0.02, hspace=0, wspace=0)
    fig.set_edgecolor("black")
    fig.suptitle(title, size=16)
    for ax, vec in zip(axs.flat, images):
        vmax = max(vec.max(), -vec.min())
        im = ax.imshow(
            vec.reshape(image_shape),
            cmap=cmap,
            interpolation="nearest",
            vmin=-vmax,
            vmax=vmax,
        )
        ax.axis("off")

    fig.colorbar(im, ax=axs, orientation="horizontal", shrink=0.99, aspect=40, pad=0.01)
    plt.show()


## データを見てみましょう。灰色が負の値を、
## 白色が正の値を示します。

plot_gallery("Faces from dataset", faces_centered[:n_components])

固有顔 - ランダム化SVDを用いた主成分分析

適用する最初の手法は主成分分析(PCA)で、これは線形次元削減手法で、データの特異値分解(SVD)を使ってデータを低次元空間に射影します。標準SVDアルゴリズムの高速近似であるランダム化SVDを使用します。最初の6つの主成分(固有顔と呼ばれる)を描画します。

## 固有顔 - ランダム化SVDを用いた主成分分析
pca_estimator = decomposition.PCA(
    n_components=n_components, svd_solver="randomized", whiten=True
)
pca_estimator.fit(faces_centered)
plot_gallery(
    "Eigenfaces - PCA using randomized SVD", pca_estimator.components_[:n_components]
)

非負成分 - NMF

次に、非負行列分解(NMF)を適用します。これは、データ行列を2つの非負行列に分解します。1つは基底ベクトルを含み、もう1つは係数を含みます。これにより、データの部分ベースの表現が得られます。

## 非負成分 - NMF
nmf_estimator = decomposition.NMF(n_components=n_components, tol=5e-3)
nmf_estimator.fit(faces)  ## 元の非負データセット
plot_gallery("Non-negative components - NMF", nmf_estimator.components_[:n_components])

独立成分 - FastICA

独立成分分析(ICA)は、多変量信号を最大限独立した加算サブコンポーネントに分離する方法です。私たちは、ICAに対する高速で頑健なアルゴリズムであるFastICAを適用します。

## 独立成分 - FastICA
ica_estimator = decomposition.FastICA(
    n_components=n_components, max_iter=400, whiten="arbitrary-variance", tol=15e-5
)
ica_estimator.fit(faces_centered)
plot_gallery(
    "Independent components - FastICA", ica_estimator.components_[:n_components]
)

疎成分 - MiniBatchSparsePCA

疎主成分分析(Sparse PCA)は、主成分分析(PCA)のバリアントで、ロードベクトルに疎性を促すことで、より解釈可能な分解をもたらします。私たちは、大規模なデータセットにより適した、SparsePCAの高速バージョンであるMiniBatchSparsePCAを使用します。

## 疎成分 - MiniBatchSparsePCA
batch_pca_estimator = decomposition.MiniBatchSparsePCA(
    n_components=n_components, alpha=0.1, max_iter=100, batch_size=3, random_state=rng
)
batch_pca_estimator.fit(faces_centered)
plot_gallery(
    "Sparse components - MiniBatchSparsePCA",
    batch_pca_estimator.components_[:n_components],
)

辞書学習

辞書学習は、単純な要素の組み合わせとして入力データの疎表現を見つける方法であり、それらの要素が辞書を形成します。私たちは、大規模なデータセットにより適した、DictionaryLearningの高速バージョンであるMiniBatchDictionaryLearningを適用します。

## 辞書学習
batch_dict_estimator = decomposition.MiniBatchDictionaryLearning(
    n_components=n_components, alpha=0.1, max_iter=50, batch_size=3, random_state=rng
)
batch_dict_estimator.fit(faces_centered)
plot_gallery("Dictionary learning", batch_dict_estimator.components_[:n_components])

クラスタ中心 - MiniBatchKMeans

K-meansクラスタリングは、各点とその割り当てられたクラスタの重心との間の二乗距離の和を最小化することにより、データセットをクラスタに分割する方法です。私たちは、大規模なデータセットにより適した、KMeansの高速バージョンであるMiniBatchKMeansを適用します。

## クラスタ中心 - MiniBatchKMeans
kmeans_estimator = cluster.MiniBatchKMeans(
    n_clusters=n_components,
    tol=1e-3,
    batch_size=20,
    max_iter=50,
    random_state=rng,
    n_init="auto",
)
kmeans_estimator.fit(faces_centered)
plot_gallery(
    "Cluster centers - MiniBatchKMeans",
    kmeans_estimator.cluster_centers_[:n_components],
)

因子分析成分 - FA

因子分析は、入力空間の各方向の分散を独立にモデリングする方法(ヘテロスケダスティックノイズ)であり、PCAに似ていますが、この利点があります。私たちは、scikit-learnにおける因子分析の実装であるFactorAnalysisを適用します。

## 因子分析成分 - FA
fa_estimator = decomposition.FactorAnalysis(n_components=n_components, max_iter=20)
fa_estimator.fit(faces_centered)
plot_gallery("Factor Analysis (FA)", fa_estimator.components_[:n_components])

## --- 画素ごとの分散
plt.figure(figsize=(3.2, 3.6), facecolor="white", tight_layout=True)
vec = fa_estimator.noise_variance_
vmax = max(vec.max(), -vec.min())
plt.imshow(
    vec.reshape(image_shape),
    cmap=plt.cm.gray,
    interpolation="nearest",
    vmin=-vmax,
    vmax=vmax,
)
plt.axis("off")
plt.title("画素ごとの分散 from \n 因子分析 (FA)", size=16, wrap=True)
plt.colorbar(orientation="horizontal", shrink=0.8, pad=0.03)
plt.show()

分解: 辞書学習

ここでは、再びMiniBatchDictionaryLearningを適用しますが、今回は辞書や符号化係数を見つける際に正の値を強制します。

辞書学習 - 正の辞書

dict_pos_dict_estimator = decomposition.MiniBatchDictionaryLearning(
    n_components=n_components,
    alpha=0.1,
    max_iter=50,
    batch_size=3,
    random_state=rng,
    positive_dict=True,
)
dict_pos_dict_estimator.fit(faces_centered)
plot_gallery(
    "辞書学習 - 正の辞書",
    dict_pos_dict_estimator.components_[:n_components],
    cmap=plt.cm.RdBu,
)

辞書学習 - 正の符号化

dict_pos_code_estimator = decomposition.MiniBatchDictionaryLearning(
    n_components=n_components,
    alpha=0.1,
    max_iter=50,
    batch_size=3,
    fit_algorithm="cd",
    random_state=rng,
    positive_code=True,
)
dict_pos_code_estimator.fit(faces_centered)
plot_gallery(
    "辞書学習 - 正の符号化",
    dict_pos_code_estimator.components_[:n_components],
    cmap=plt.cm.RdBu,
)

辞書学習 - 正の辞書と符号化

dict_pos_estimator = decomposition.MiniBatchDictionaryLearning(
    n_components=n_components,
    alpha=0.1,
    max_iter=50,
    batch_size=3,
    fit_algorithm="cd",
    random_state=rng,
    positive_dict=True,
    positive_code=True,
)
dict_pos_estimator.fit(faces_centered)
plot_gallery(
    "辞書学習 - 正の辞書と符号化",
    dict_pos_estimator.components_[:n_components],
    cmap=plt.cm.RdBu,
)

まとめ

この実験では、オリベッティ顔データセットに対して様々な非監督的行列分解手法を適用しました。PCA、NMF、ICA、スパースPCA、辞書学習、K-平均クラスタリング、因子分析を用いて、データから異なる種類の特徴を抽出しました。また、辞書学習手法において辞書や符号化係数を見つける際に正の値を強制しました。全体的に、これらの手法は、高次元データセットの次元削減や、分類やクラスタリングなどの下流のタスクにとって意味のある特徴を抽出するのに役立つ可能性があります。