2011-07-16 20:07:20 +08:00
|
|
|
"""
|
2011-07-17 07:59:50 +08:00
|
|
|
============================
|
|
|
|
|
Faces dataset decompositions
|
|
|
|
|
============================
|
2011-07-16 20:07:20 +08:00
|
|
|
|
2019-09-23 23:49:08 +08:00
|
|
|
This example applies to :ref:`olivetti_faces_dataset` different unsupervised
|
2012-04-02 01:05:56 +08:00
|
|
|
matrix decomposition (dimension reduction) methods from the module
|
|
|
|
|
:py:mod:`sklearn.decomposition` (see the documentation chapter
|
|
|
|
|
:ref:`decompositions`) .
|
2011-07-16 20:07:20 +08:00
|
|
|
|
|
|
|
|
"""
|
2013-02-01 22:04:03 +08:00
|
|
|
print(__doc__)
|
2011-07-16 20:07:20 +08:00
|
|
|
|
|
|
|
|
# Authors: Vlad Niculae, Alexandre Gramfort
|
2013-04-30 14:23:46 +08:00
|
|
|
# License: BSD 3 clause
|
2011-07-16 20:07:20 +08:00
|
|
|
|
2011-07-17 07:59:50 +08:00
|
|
|
import logging
|
2011-07-16 20:07:20 +08:00
|
|
|
from time import time
|
|
|
|
|
|
2011-09-19 18:51:23 +08:00
|
|
|
from numpy.random import RandomState
|
2014-05-15 04:31:03 +08:00
|
|
|
import matplotlib.pyplot as plt
|
2011-07-16 20:07:20 +08:00
|
|
|
|
2011-09-02 17:00:02 +08:00
|
|
|
from sklearn.datasets import fetch_olivetti_faces
|
|
|
|
|
from sklearn.cluster import MiniBatchKMeans
|
|
|
|
|
from sklearn import decomposition
|
2011-07-17 07:59:50 +08:00
|
|
|
|
|
|
|
|
# Display progress logs on stdout
|
|
|
|
|
logging.basicConfig(level=logging.INFO,
|
|
|
|
|
format='%(asctime)s %(levelname)s %(message)s')
|
2011-07-31 20:59:30 +08:00
|
|
|
n_row, n_col = 2, 3
|
2011-07-16 20:07:20 +08:00
|
|
|
n_components = n_row * n_col
|
2011-07-17 07:59:50 +08:00
|
|
|
image_shape = (64, 64)
|
2011-09-19 18:51:23 +08:00
|
|
|
rng = RandomState(0)
|
2011-07-16 20:07:20 +08:00
|
|
|
|
2017-06-20 20:48:57 +08:00
|
|
|
# #############################################################################
|
2011-07-27 00:59:31 +08:00
|
|
|
# Load faces data
|
2019-07-20 10:30:09 +08:00
|
|
|
faces, _ = fetch_olivetti_faces(return_X_y=True, shuffle=True,
|
|
|
|
|
random_state=rng)
|
2011-07-27 01:21:34 +08:00
|
|
|
n_samples, n_features = faces.shape
|
|
|
|
|
|
|
|
|
|
# global centering
|
2011-07-17 07:59:50 +08:00
|
|
|
faces_centered = faces - faces.mean(axis=0)
|
2011-07-27 01:21:34 +08:00
|
|
|
|
|
|
|
|
# local centering
|
|
|
|
|
faces_centered -= faces_centered.mean(axis=1).reshape(n_samples, -1)
|
|
|
|
|
|
2013-02-01 22:04:03 +08:00
|
|
|
print("Dataset consists of %d faces" % n_samples)
|
2011-07-16 20:07:20 +08:00
|
|
|
|
2011-07-16 22:15:04 +08:00
|
|
|
|
2018-06-21 22:36:48 +08:00
|
|
|
def plot_gallery(title, images, n_col=n_col, n_row=n_row, cmap=plt.cm.gray):
|
2014-05-15 04:31:03 +08:00
|
|
|
plt.figure(figsize=(2. * n_col, 2.26 * n_row))
|
|
|
|
|
plt.suptitle(title, size=16)
|
2011-07-16 20:07:20 +08:00
|
|
|
for i, comp in enumerate(images):
|
2014-05-15 04:31:03 +08:00
|
|
|
plt.subplot(n_row, n_col, i + 1)
|
2011-08-04 14:15:39 +08:00
|
|
|
vmax = max(comp.max(), -comp.min())
|
2018-06-21 22:36:48 +08:00
|
|
|
plt.imshow(comp.reshape(image_shape), cmap=cmap,
|
2014-05-15 10:35:13 +08:00
|
|
|
interpolation='nearest',
|
|
|
|
|
vmin=-vmax, vmax=vmax)
|
2014-05-15 04:31:03 +08:00
|
|
|
plt.xticks(())
|
|
|
|
|
plt.yticks(())
|
|
|
|
|
plt.subplots_adjust(0.01, 0.05, 0.99, 0.93, 0.04, 0.)
|
2011-07-16 20:07:20 +08:00
|
|
|
|
2017-06-20 20:48:57 +08:00
|
|
|
# #############################################################################
|
2011-07-16 23:30:54 +08:00
|
|
|
# List of the different estimators, whether to center and transpose the
|
|
|
|
|
# problem, and whether the transformer uses the clustering API.
|
|
|
|
|
estimators = [
|
2016-09-19 16:55:05 +08:00
|
|
|
('Eigenfaces - PCA using randomized SVD',
|
2016-09-18 02:53:08 +08:00
|
|
|
decomposition.PCA(n_components=n_components, svd_solver='randomized',
|
|
|
|
|
whiten=True),
|
2012-06-05 04:27:34 +08:00
|
|
|
True),
|
2011-07-27 00:59:31 +08:00
|
|
|
|
2011-07-27 02:27:03 +08:00
|
|
|
('Non-negative components - NMF',
|
2015-06-11 00:46:53 +08:00
|
|
|
decomposition.NMF(n_components=n_components, init='nndsvda', tol=5e-3),
|
2012-06-05 04:27:34 +08:00
|
|
|
False),
|
2011-07-27 00:59:31 +08:00
|
|
|
|
2011-07-27 02:27:03 +08:00
|
|
|
('Independent components - FastICA',
|
2013-07-28 21:01:15 +08:00
|
|
|
decomposition.FastICA(n_components=n_components, whiten=True),
|
2012-06-05 04:27:34 +08:00
|
|
|
True),
|
2011-07-27 00:59:31 +08:00
|
|
|
|
2011-07-27 02:27:03 +08:00
|
|
|
('Sparse comp. - MiniBatchSparsePCA',
|
2011-12-20 18:17:38 +08:00
|
|
|
decomposition.MiniBatchSparsePCA(n_components=n_components, alpha=0.8,
|
2012-12-08 05:09:01 +08:00
|
|
|
n_iter=100, batch_size=3,
|
2019-05-29 18:06:50 +08:00
|
|
|
random_state=rng),
|
2012-06-05 04:27:34 +08:00
|
|
|
True),
|
2011-07-27 00:59:31 +08:00
|
|
|
|
2011-09-18 01:20:58 +08:00
|
|
|
('MiniBatchDictionaryLearning',
|
2012-12-25 20:16:05 +08:00
|
|
|
decomposition.MiniBatchDictionaryLearning(n_components=15, alpha=0.1,
|
|
|
|
|
n_iter=50, batch_size=3,
|
|
|
|
|
random_state=rng),
|
2012-06-05 04:27:34 +08:00
|
|
|
True),
|
2011-09-13 00:44:29 +08:00
|
|
|
|
2011-07-27 02:27:03 +08:00
|
|
|
('Cluster centers - MiniBatchKMeans',
|
2012-12-25 20:16:05 +08:00
|
|
|
MiniBatchKMeans(n_clusters=n_components, tol=1e-3, batch_size=20,
|
|
|
|
|
max_iter=50, random_state=rng),
|
2012-10-12 04:15:00 +08:00
|
|
|
True),
|
|
|
|
|
|
|
|
|
|
('Factor Analysis components - FA',
|
2019-01-17 18:41:13 +08:00
|
|
|
decomposition.FactorAnalysis(n_components=n_components, max_iter=20),
|
2012-12-25 20:16:05 +08:00
|
|
|
True),
|
2011-07-27 00:59:31 +08:00
|
|
|
]
|
2011-07-16 20:07:20 +08:00
|
|
|
|
2012-10-12 04:15:00 +08:00
|
|
|
|
2017-06-20 20:48:57 +08:00
|
|
|
# #############################################################################
|
2011-07-27 01:21:34 +08:00
|
|
|
# Plot a sample of the input data
|
|
|
|
|
|
2011-07-27 02:27:03 +08:00
|
|
|
plot_gallery("First centered Olivetti faces", faces_centered[:n_components])
|
2011-07-27 01:21:34 +08:00
|
|
|
|
2017-06-20 20:48:57 +08:00
|
|
|
# #############################################################################
|
2011-07-16 21:16:19 +08:00
|
|
|
# Do the estimation and plot it
|
2011-07-27 01:21:34 +08:00
|
|
|
|
2012-06-05 04:27:34 +08:00
|
|
|
for name, estimator, center in estimators:
|
2013-02-01 22:04:03 +08:00
|
|
|
print("Extracting the top %d %s..." % (n_components, name))
|
2011-07-16 21:16:19 +08:00
|
|
|
t0 = time()
|
2011-07-17 07:59:50 +08:00
|
|
|
data = faces
|
2011-07-16 21:16:19 +08:00
|
|
|
if center:
|
2011-07-17 07:59:50 +08:00
|
|
|
data = faces_centered
|
2011-07-16 21:16:19 +08:00
|
|
|
estimator.fit(data)
|
2011-08-04 14:15:39 +08:00
|
|
|
train_time = (time() - t0)
|
2013-02-01 22:04:03 +08:00
|
|
|
print("done in %0.3fs" % train_time)
|
2011-07-27 02:11:55 +08:00
|
|
|
if hasattr(estimator, 'cluster_centers_'):
|
2011-07-16 23:30:54 +08:00
|
|
|
components_ = estimator.cluster_centers_
|
|
|
|
|
else:
|
|
|
|
|
components_ = estimator.components_
|
2016-09-19 20:27:07 +08:00
|
|
|
|
|
|
|
|
# Plot an image representing the pixelwise variance provided by the
|
|
|
|
|
# estimator e.g its noise_variance_ attribute. The Eigenfaces estimator,
|
|
|
|
|
# via the PCA decomposition, also provides a scalar noise_variance_
|
|
|
|
|
# (the mean of pixelwise variance) that cannot be displayed as an image
|
|
|
|
|
# so we skip it.
|
2016-09-19 16:55:05 +08:00
|
|
|
if (hasattr(estimator, 'noise_variance_') and
|
2016-09-19 20:27:07 +08:00
|
|
|
estimator.noise_variance_.ndim > 0): # Skip the Eigenfaces case
|
2012-10-12 04:15:00 +08:00
|
|
|
plot_gallery("Pixelwise variance",
|
2012-12-25 20:16:05 +08:00
|
|
|
estimator.noise_variance_.reshape(1, -1), n_col=1,
|
|
|
|
|
n_row=1)
|
2011-09-19 18:51:23 +08:00
|
|
|
plot_gallery('%s - Train time %.1fs' % (name, train_time),
|
|
|
|
|
components_[:n_components])
|
2011-07-16 20:07:20 +08:00
|
|
|
|
2014-05-15 04:31:03 +08:00
|
|
|
plt.show()
|
2018-06-21 22:36:48 +08:00
|
|
|
|
|
|
|
|
# #############################################################################
|
|
|
|
|
# Various positivity constraints applied to dictionary learning.
|
|
|
|
|
estimators = [
|
|
|
|
|
('Dictionary learning',
|
|
|
|
|
decomposition.MiniBatchDictionaryLearning(n_components=15, alpha=0.1,
|
|
|
|
|
n_iter=50, batch_size=3,
|
|
|
|
|
random_state=rng),
|
|
|
|
|
True),
|
|
|
|
|
('Dictionary learning - positive dictionary',
|
|
|
|
|
decomposition.MiniBatchDictionaryLearning(n_components=15, alpha=0.1,
|
|
|
|
|
n_iter=50, batch_size=3,
|
|
|
|
|
random_state=rng,
|
|
|
|
|
positive_dict=True),
|
|
|
|
|
True),
|
|
|
|
|
('Dictionary learning - positive code',
|
|
|
|
|
decomposition.MiniBatchDictionaryLearning(n_components=15, alpha=0.1,
|
|
|
|
|
n_iter=50, batch_size=3,
|
2019-05-29 21:05:02 +08:00
|
|
|
fit_algorithm='cd',
|
2018-06-21 22:36:48 +08:00
|
|
|
random_state=rng,
|
|
|
|
|
positive_code=True),
|
|
|
|
|
True),
|
|
|
|
|
('Dictionary learning - positive dictionary & code',
|
|
|
|
|
decomposition.MiniBatchDictionaryLearning(n_components=15, alpha=0.1,
|
|
|
|
|
n_iter=50, batch_size=3,
|
2019-05-29 21:05:02 +08:00
|
|
|
fit_algorithm='cd',
|
2018-06-21 22:36:48 +08:00
|
|
|
random_state=rng,
|
|
|
|
|
positive_dict=True,
|
|
|
|
|
positive_code=True),
|
|
|
|
|
True),
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# #############################################################################
|
|
|
|
|
# Plot a sample of the input data
|
|
|
|
|
|
|
|
|
|
plot_gallery("First centered Olivetti faces", faces_centered[:n_components],
|
|
|
|
|
cmap=plt.cm.RdBu)
|
|
|
|
|
|
|
|
|
|
# #############################################################################
|
|
|
|
|
# Do the estimation and plot it
|
|
|
|
|
|
|
|
|
|
for name, estimator, center in estimators:
|
|
|
|
|
print("Extracting the top %d %s..." % (n_components, name))
|
|
|
|
|
t0 = time()
|
|
|
|
|
data = faces
|
|
|
|
|
if center:
|
|
|
|
|
data = faces_centered
|
|
|
|
|
estimator.fit(data)
|
|
|
|
|
train_time = (time() - t0)
|
|
|
|
|
print("done in %0.3fs" % train_time)
|
|
|
|
|
components_ = estimator.components_
|
|
|
|
|
plot_gallery(name, components_[:n_components], cmap=plt.cm.RdBu)
|
|
|
|
|
|
|
|
|
|
plt.show()
|