2011-12-20 20:23:03 +08:00
|
|
|
"""
|
|
|
|
|
===========================================
|
|
|
|
|
Sparse coding with a precomputed dictionary
|
|
|
|
|
===========================================
|
|
|
|
|
|
|
|
|
|
Transform a signal as a sparse combination of Ricker wavelets. This example
|
|
|
|
|
visually compares different sparse coding methods using the
|
2011-12-22 23:33:15 +08:00
|
|
|
:class:`sklearn.decomposition.SparseCoder` estimator. The Ricker (also known
|
2014-06-02 05:43:21 +08:00
|
|
|
as Mexican hat or the second derivative of a Gaussian) is not a particularly
|
2011-12-22 23:33:15 +08:00
|
|
|
good kernel to represent piecewise constant signals like this one. It can
|
|
|
|
|
therefore be seen how much adding different widths of atoms matters and it
|
|
|
|
|
therefore motivates learning the dictionary to best fit your type of signals.
|
|
|
|
|
|
|
|
|
|
The richer dictionary on the right is not larger in size, heavier subsampling
|
|
|
|
|
is performed in order to stay on the same order of magnitude.
|
2011-12-20 20:23:03 +08:00
|
|
|
"""
|
2013-02-01 22:04:03 +08:00
|
|
|
print(__doc__)
|
2011-12-20 20:23:03 +08:00
|
|
|
|
|
|
|
|
import numpy as np
|
[MRG+1] Fix: Replace pylab with matplotlib.pyplot #6754 (#6762)
* Fix: Replace pylab with matplotlib.pyplot #6754
- one instance of 22 occurrences of pylab replaced with matplotlib.pyplot
- bench_glm.py now free of pylab references
- code executes properly
* Fix: Replace pylab with matplotlib.pyplot #6754
- one instance of 21 remaining occurrences of pylab replaced with
matplotlib.pyplot
- bench_glmnet.py now free of pylab references
- code does not execute for extraneous reason: ImportError: No module named
glmnet.elastic_net
* Fix: Replace pylab with matplotlib.pyplot #6754
- one instance of 19 occurrences of pylab replaced with matplotlib.pyplot
- bench_lasso.py now free of pylab references
- code executes properly
* Fix: Replace pylab with matplotlib.pyplot #6754
- one instance of 18 occurrences of pylab replaced with matplotlib.pyplot
- bench_plot_neighbors.py now free of pylab references
- code executes properly
* Fix: Replace pylab with matplotlib.pyplot #6754
- one instance of 17 occurrences of pylab replaced with matplotlib.pyplot
- bench_plot_omp_lars.py now free of pylab references
- code does not execute for extraneous reasons:
- File "bench_plot_omp_lars.py", line 111, in <module>
- ax = fig.add_subplot(1, 2, i)
- ValueError: num must be 1 <= num <= 2, not 0
- line 111 should probably be ax = fig.add_subplot(1, 2, i+1)
* Fix: Replace pylab with matplotlib.pyplot #6754
- bench_plot_parallel_pairwise.py now free of pylab references
- code executes properly
* Fix: Replace pylab with matplotlib.pyplot #6754
- bench_plot_ward.py now free of pylab references
- code executes properly
* Fix: Replace pylab with matplotlib.pyplot #6754
- bench_sgd_regression.py now free of pylab references
- code executes properly
* Fix: Replace pylab with matplotlib.pyplot #6754
- bench_tree.py now free of pylab references
- code executes properly
* refactor: Replace pl with plt
- replace instances of pl (as on import pylab as pl)
with plt (as in import matplotlib.pyplot as plt)
- bench_glm.py clean
* refactor: Replace pl with plt
- replace instances of pl (as on import pylab as pl)
with plt (as in import matplotlib.pyplot as plt)
- bench_glm.py clean of pl
- code does not execute for extraneous reasons
* refactor: Replace pl with plt
- replace instances of pl (as on import pylab as pl)
with plt (as in import matplotlib.pyplot as plt)
- bench_lasso.py clean of pl
- code executes properly
* refactor: Replace pl with plt
- replace instances of pl (as on import pylab as pl)
with plt (as in import matplotlib.pyplot as plt)
- bench_plot_neighbors.py clean of pl
- code executes properly
* refactor: Replace pl with plt
- replace instances of pl (as on import pylab as pl)
with plt (as in import matplotlib.pyplot as plt)
- bench_plot_omp_lars.py clean of pl
- code does not execute for extraneous reasons
* fix: Fix bug that prevented graphs from displaying
* refactor: Replace pl with plt
- replace instances of pl (as on import pylab as pl)
with plt (as in import matplotlib.pyplot as plt)
- bench_plot_parallel_pairwise.py clean of pl
- code executes properly
* refactor: Replace pl with plt
- replace instances of pl (as on import pylab as pl)
with plt (as in import matplotlib.pyplot as plt)
- bench_plot_ward.py clean of pl
- code executes properly
* refactor: Replace pl with plt
- replace instances of pl (as on import pylab as pl)
with plt (as in import matplotlib.pyplot as plt)
- bench_sgd_regression.py clean of pl
- code executes properly
* refactor: Replace pl with plt
- replace instances of pl (as on import pylab as pl)
with plt (as in import matplotlib.pyplot as plt)
- bench_tree.py clean of pl
- code executes properly
* docs: removed pylab references from comments
* docs: removed all pylab references
- replaced with matplotlib.pyplot
- pl --> plt
* docs: removed pylab references from comments
- replaced with matplotlib.pyplot
- pl --> plt
* docs: removed all pylab references
- replaced with matplotlib.pyplot
- pl --> plt
* refactor: Replace pl with plt
- replace instances of pl (as on import pylab as pl)
with plt (as in import matplotlib.pyplot as plt)
- mlcomp_sparse_document_classification.py clean of pl
* refactor: Replace pl with plt
- replace instances of pl (as on import pylab as pl)
with plt (as in import matplotlib.pyplot as plt)
- plot_gpr_noisy_targets.py clean of pl
- code does not execute for extraneous reasons
- File "examples/gaussian_process/plot_gpr_noisy_targets.py", line 31, in
<module>
- from sklearn.gaussian_process import GaussianProcessRegressor
- ImportError: cannot import name GaussianProcessRegressor
* refactor: Replace pl with plt
- replace instances of pl (as on import pylab as pl)
with plt (as in import matplotlib.pyplot as plt)
- plot_gpc_isoprobability.py clean of pl
- code does not execute for extraneous reasons
- File "examples/gaussian_process/plot_gpc_isoprobability.py", line 24, in
<module>
- from sklearn.gaussian_process import GaussianProcessClassifier
- ImportError: cannot import name GaussianProcessClassifier
* docs: removed all pylab references
- replaced with matplotlib.pyplot
- pl --> plt
* docs: removed all pylab references
- replaced with matplotlib.pyplot
* refactor: Replace pl with plt
- replace instances of pl (as on import pylab as pl)
with plt (as in import matplotlib.pyplot as plt)
- plot_sparse_coding.py clean of pl
- code executes properly
* docs: removed all pylab references
- replaced with matplotlib.pyplot
* docs: removed all pylab references
- replaced with matplotlib.pyplot
* style: Indent properly
* style: indent properly
* style: Indent properly
* docs: Add missing .pyplot
* docs: Fix typo
* style: Indent properly
2016-05-10 17:34:33 +08:00
|
|
|
import matplotlib.pyplot as plt
|
2011-12-20 20:23:03 +08:00
|
|
|
|
|
|
|
|
from sklearn.decomposition import SparseCoder
|
|
|
|
|
|
2011-12-20 21:17:11 +08:00
|
|
|
|
2011-12-20 20:23:03 +08:00
|
|
|
def ricker_function(resolution, center, width):
|
2014-06-02 05:43:21 +08:00
|
|
|
"""Discrete sub-sampled Ricker (Mexican hat) wavelet"""
|
2011-12-20 20:23:03 +08:00
|
|
|
x = np.linspace(0, resolution - 1, resolution)
|
2012-12-25 20:16:05 +08:00
|
|
|
x = ((2 / ((np.sqrt(3 * width) * np.pi ** 1 / 4)))
|
|
|
|
|
* (1 - ((x - center) ** 2 / width ** 2))
|
|
|
|
|
* np.exp((-(x - center) ** 2) / (2 * width ** 2)))
|
2011-12-20 20:23:03 +08:00
|
|
|
return x
|
|
|
|
|
|
|
|
|
|
|
2012-11-03 19:35:12 +08:00
|
|
|
def ricker_matrix(width, resolution, n_components):
|
2014-06-02 05:43:21 +08:00
|
|
|
"""Dictionary of Ricker (Mexican hat) wavelets"""
|
2012-11-03 19:35:12 +08:00
|
|
|
centers = np.linspace(0, resolution - 1, n_components)
|
|
|
|
|
D = np.empty((n_components, resolution))
|
2011-12-20 20:23:03 +08:00
|
|
|
for i, center in enumerate(centers):
|
|
|
|
|
D[i] = ricker_function(resolution, center, width)
|
2011-12-20 21:17:11 +08:00
|
|
|
D /= np.sqrt(np.sum(D ** 2, axis=1))[:, np.newaxis]
|
2011-12-20 20:23:03 +08:00
|
|
|
return D
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
resolution = 1024
|
|
|
|
|
subsampling = 3 # subsampling factor
|
2011-12-22 23:33:15 +08:00
|
|
|
width = 100
|
2017-02-03 22:21:03 +08:00
|
|
|
n_components = resolution // subsampling
|
2011-12-20 20:23:03 +08:00
|
|
|
|
|
|
|
|
# Compute a wavelet dictionary
|
2012-12-25 20:16:05 +08:00
|
|
|
D_fixed = ricker_matrix(width=width, resolution=resolution,
|
|
|
|
|
n_components=n_components)
|
2011-12-22 23:33:15 +08:00
|
|
|
D_multi = np.r_[tuple(ricker_matrix(width=w, resolution=resolution,
|
2017-02-03 22:21:03 +08:00
|
|
|
n_components=n_components // 5)
|
2012-12-25 20:16:05 +08:00
|
|
|
for w in (10, 50, 100, 500, 1000))]
|
2011-12-20 20:23:03 +08:00
|
|
|
|
|
|
|
|
# Generate a signal
|
|
|
|
|
y = np.linspace(0, resolution - 1, resolution)
|
2011-12-21 00:09:15 +08:00
|
|
|
first_quarter = y < resolution / 4
|
2011-12-22 23:33:15 +08:00
|
|
|
y[first_quarter] = 3.
|
|
|
|
|
y[np.logical_not(first_quarter)] = -1.
|
2011-12-20 20:23:03 +08:00
|
|
|
|
|
|
|
|
# List the different sparse coding methods in the following format:
|
|
|
|
|
# (title, transform_algorithm, transform_alpha, transform_n_nozero_coefs)
|
2015-10-24 01:05:30 +08:00
|
|
|
estimators = [('OMP', 'omp', None, 15, 'navy'),
|
|
|
|
|
('Lasso', 'lasso_cd', 2, None, 'turquoise'), ]
|
|
|
|
|
lw = 2
|
2011-12-20 20:23:03 +08:00
|
|
|
|
2015-10-24 01:05:30 +08:00
|
|
|
plt.figure(figsize=(13, 6))
|
2011-12-22 23:33:15 +08:00
|
|
|
for subplot, (D, title) in enumerate(zip((D_fixed, D_multi),
|
|
|
|
|
('fixed width', 'multiple widths'))):
|
2015-10-24 01:05:30 +08:00
|
|
|
plt.subplot(1, 2, subplot + 1)
|
|
|
|
|
plt.title('Sparse coding against %s dictionary' % title)
|
|
|
|
|
plt.plot(y, lw=lw, linestyle='--', label='Original signal')
|
2011-12-22 23:33:15 +08:00
|
|
|
# Do a wavelet approximation
|
2015-10-24 01:05:30 +08:00
|
|
|
for title, algo, alpha, n_nonzero, color in estimators:
|
2011-12-22 23:33:15 +08:00
|
|
|
coder = SparseCoder(dictionary=D, transform_n_nonzero_coefs=n_nonzero,
|
|
|
|
|
transform_alpha=alpha, transform_algorithm=algo)
|
2015-11-05 06:11:25 +08:00
|
|
|
x = coder.transform(y.reshape(1, -1))
|
2011-12-22 23:33:15 +08:00
|
|
|
density = len(np.flatnonzero(x))
|
|
|
|
|
x = np.ravel(np.dot(x, D))
|
|
|
|
|
squared_error = np.sum((y - x) ** 2)
|
2015-10-24 01:05:30 +08:00
|
|
|
plt.plot(x, color=color, lw=lw,
|
|
|
|
|
label='%s: %s nonzero coefs,\n%.2f error'
|
|
|
|
|
% (title, density, squared_error))
|
2011-12-20 20:23:03 +08:00
|
|
|
|
2011-12-22 23:33:15 +08:00
|
|
|
# Soft thresholding debiasing
|
|
|
|
|
coder = SparseCoder(dictionary=D, transform_algorithm='threshold',
|
|
|
|
|
transform_alpha=20)
|
2015-11-05 06:11:25 +08:00
|
|
|
x = coder.transform(y.reshape(1, -1))
|
2011-12-22 23:33:15 +08:00
|
|
|
_, idx = np.where(x != 0)
|
|
|
|
|
x[0, idx], _, _, _ = np.linalg.lstsq(D[idx, :].T, y)
|
|
|
|
|
x = np.ravel(np.dot(x, D))
|
|
|
|
|
squared_error = np.sum((y - x) ** 2)
|
2015-10-24 01:05:30 +08:00
|
|
|
plt.plot(x, color='darkorange', lw=lw,
|
|
|
|
|
label='Thresholding w/ debiasing:\n%d nonzero coefs, %.2f error'
|
|
|
|
|
% (len(idx), squared_error))
|
|
|
|
|
plt.axis('tight')
|
|
|
|
|
plt.legend(shadow=False, loc='best')
|
|
|
|
|
plt.subplots_adjust(.04, .07, .97, .90, .09, .2)
|
|
|
|
|
plt.show()
|