Decomposição de Dados de Rostos Olivetti

Beginner

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

Introdução

Este laboratório aplica diferentes métodos de decomposição de matriz não supervisionada (redução de dimensionalidade) do módulo sklearn.decomposition ao conjunto de dados de rostos Olivetti. O conjunto de dados de rostos Olivetti consiste em 400 rostos de tamanho 64x64 pixels de 40 indivíduos, cada um capturado com diferentes expressões faciais e condições de iluminação.

Dicas da Máquina Virtual

Após o arranque da máquina virtual, clique no canto superior esquerdo para mudar para a aba Notebook para aceder ao Jupyter Notebook para a prática.

Por vezes, pode ser necessário esperar alguns segundos para o Jupyter Notebook terminar de carregar. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.

Se tiver problemas durante a aprendizagem, não hesite em contactar o Labby. Forneça feedback após a sessão e resolveremos prontamente o problema para si.

Preparação do Conjunto de Dados

Primeiro, carregamos e pré-processamos o conjunto de dados de rostos Olivetti. Centralizamos os dados para ter média zero, tanto globalmente (foco em um recurso, centralizando todas as amostras) quanto localmente (foco em uma amostra, centralizando todos os recursos). Também definimos uma função base para plotar a galeria de rostos.

## Carregamento e pré-processamento do conjunto de dados de rostos Olivetti.

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)

## Exibir logs de progresso no stdout
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

## Centralização global (foco em um recurso, centralizando todas as amostras)
faces_centered = faces - faces.mean(axis=0)

## Centralização local (foco em uma amostra, centralizando todos os recursos)
faces_centered -= faces_centered.mean(axis=1).reshape(n_samples, -1)

print("O conjunto de dados consiste em %d rostos" % n_samples)

## Definir uma função base para plotar a galeria de rostos.

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()


## Vamos dar uma olhada nos nossos dados. A cor cinza indica valores negativos,
## branco indica valores positivos.

plot_gallery("Rostos do conjunto de dados", faces_centered[:n_components])

Eigenfaces - PCA usando SVD aleatorizado

O primeiro método que aplicamos é a PCA, que é uma técnica de redução de dimensionalidade linear que utiliza a Decomposição em Valores Singulares (SVD) dos dados para projetá-los em um espaço de menor dimensão. Usamos SVD aleatorizado, que é uma aproximação mais rápida do algoritmo SVD padrão. Plotamos os seis primeiros componentes principais, que são chamados de eigenfaces.

## Eigenfaces - PCA usando SVD aleatorizado
pca_estimator = decomposition.PCA(
    n_components=n_components, svd_solver="randomized", whiten=True
)
pca_estimator.fit(faces_centered)
plot_gallery(
    "Eigenfaces - PCA usando SVD aleatorizado", pca_estimator.components_[:n_components]
)

Componentes Não-Negativos - NMF

Em seguida, aplicamos a Fatoração de Matriz Não-Negativa (NMF), que fatoriza a matriz de dados em duas matrizes não-negativas, uma contendo os vetores base e a outra contendo os coeficientes. Isso resulta em uma representação baseada em partes dos dados.

## Componentes Não-Negativos - NMF
nmf_estimator = decomposition.NMF(n_components=n_components, tol=5e-3)
nmf_estimator.fit(faces)  ## conjunto de dados original não-negativo
plot_gallery("Componentes Não-Negativos - NMF", nmf_estimator.components_[:n_components])

Componentes Independentes - FastICA

A Análise de Componentes Independentes (ICA) é um método para separar sinais multivariados em subcomponentes aditivos que são maximamente independentes. Aplicamos o FastICA, que é um algoritmo rápido e robusto para ICA.

## Componentes Independentes - 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(
    "Componentes Independentes - FastICA", ica_estimator.components_[:n_components]
)

Componentes Esparsos - MiniBatchSparsePCA

A PCA esparsa é uma variante da PCA que incentiva a esparcidade nos vetores de carregamento, resultando numa decomposição mais interpretável. Usamos o MiniBatchSparsePCA, uma versão mais rápida do SparsePCA, mais adequada para conjuntos de dados grandes.

## Componentes Esparsos - 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(
    "Componentes Esparsos - MiniBatchSparsePCA",
    batch_pca_estimator.components_[:n_components],
)

Aprendizagem de Dicionário

A aprendizagem de dicionário é um método para encontrar uma representação esparsa dos dados de entrada como uma combinação de elementos simples, que formam um dicionário. Aplicamos o MiniBatchDictionaryLearning, uma versão mais rápida do DictionaryLearning, mais adequada para conjuntos de dados grandes.

## Aprendizagem de Dicionário
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("Aprendizagem de Dicionário", batch_dict_estimator.components_[:n_components])

Centros de Clusters - MiniBatchKMeans

O agrupamento K-means é um método para particionar um conjunto de dados em clusters, minimizando a soma dos quadrados das distâncias entre cada ponto e o centroide do cluster atribuído. Aplicamos o MiniBatchKMeans, uma versão mais rápida do KMeans, mais adequada para conjuntos de dados grandes.

## Centros de Clusters - 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(
    "Centros de Clusters - MiniBatchKMeans",
    kmeans_estimator.cluster_centers_[:n_components],
)

Componentes da Análise Fatorial - FA

A Análise Fatorial é um método para modelar a variância em cada direção do espaço de entrada de forma independente (ruído heterocedástico), semelhante à PCA, mas com esta vantagem. Aplicamos o FactorAnalysis, que é uma implementação da Análise Fatorial no scikit-learn.

## Componentes da Análise Fatorial - FA
fa_estimator = decomposition.FactorAnalysis(n_components=n_components, max_iter=20)
fa_estimator.fit(faces_centered)
plot_gallery("Análise Fatorial (FA)", fa_estimator.components_[:n_components])

## --- Variância pixel a pixel
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("Variância pixel a pixel a partir de \n Análise Fatorial (FA)", size=16, wrap=True)
plt.colorbar(orientation="horizontal", shrink=0.8, pad=0.03)
plt.show()

Decomposição: Aprendizagem de Dicionário

Aplicamos novamente o MiniBatchDictionaryLearning, mas desta vez impomos positividade ao encontrar o dicionário e/ou coeficientes de codificação.

Aprendizagem de Dicionário - Dicionário Positivo

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(
    "Aprendizagem de Dicionário - Dicionário Positivo",
    dict_pos_dict_estimator.components_[:n_components],
    cmap=plt.cm.RdBu,
)

Aprendizagem de Dicionário - Código Positivo

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(
    "Aprendizagem de Dicionário - Código Positivo",
    dict_pos_code_estimator.components_[:n_components],
    cmap=plt.cm.RdBu,
)

Aprendizagem de Dicionário - Dicionário e Código Positivos

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(
    "Aprendizagem de Dicionário - Dicionário e Código Positivos",
    dict_pos_estimator.components_[:n_components],
    cmap=plt.cm.RdBu,
)

Resumo

Neste laboratório, aplicamos vários métodos de decomposição de matrizes não supervisionadas ao conjunto de dados de rostos Olivetti. Utilizamos PCA, NMF, ICA, PCA esparso, Aprendizagem de Dicionário, agrupamento K-means e Análise Fatorial para extrair diferentes tipos de características dos dados. Também impusemos positividade ao encontrar os coeficientes do dicionário e/ou de codificação no método de Aprendizagem de Dicionário. Em geral, estes métodos podem ser úteis para reduzir a dimensionalidade de conjuntos de dados de alta dimensionalidade e extrair características significativas para tarefas subsequentes, como classificação e agrupamento.