forked from amueller/introduction_to_ml_with_python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathplot_nmf.py
87 lines (71 loc) · 3.08 KB
/
plot_nmf.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
from sklearn.decomposition import NMF
import matplotlib.pyplot as plt
import numpy as np
from joblib import Memory
memory = Memory(location="cache")
def plot_nmf_illustration():
rnd = np.random.RandomState(5)
X_ = rnd.normal(size=(300, 2))
# Add 8 to make sure every point lies in the positive part of the space
X_blob = np.dot(X_, rnd.normal(size=(2, 2))) + rnd.normal(size=2) + 8
nmf = NMF(random_state=0)
nmf.fit(X_blob)
X_nmf = nmf.transform(X_blob)
fig, axes = plt.subplots(1, 2, figsize=(15, 5))
axes[0].scatter(X_blob[:, 0], X_blob[:, 1], c=X_nmf[:, 0], linewidths=0,
s=60, cmap='viridis')
axes[0].set_xlabel("feature 1")
axes[0].set_ylabel("feature 2")
axes[0].set_xlim(0, 12)
axes[0].set_ylim(0, 12)
axes[0].arrow(0, 0, nmf.components_[0, 0], nmf.components_[0, 1], width=.1,
head_width=.3, color='k')
axes[0].arrow(0, 0, nmf.components_[1, 0], nmf.components_[1, 1], width=.1,
head_width=.3, color='k')
axes[0].set_aspect('equal')
axes[0].set_title("NMF with two components")
# second plot
nmf = NMF(random_state=0, n_components=1)
nmf.fit(X_blob)
axes[1].scatter(X_blob[:, 0], X_blob[:, 1], c=X_nmf[:, 0], linewidths=0,
s=60, cmap='viridis')
axes[1].set_xlabel("feature 1")
axes[1].set_ylabel("feature 2")
axes[1].set_xlim(0, 12)
axes[1].set_ylim(0, 12)
axes[1].arrow(0, 0, nmf.components_[0, 0], nmf.components_[0, 1], width=.1,
head_width=.3, color='k')
axes[1].set_aspect('equal')
axes[1].set_title("NMF with one component")
@memory.cache
def nmf_faces(X_train, X_test):
# Build NMF models with 10, 50, 100 and 500 components
# this list will hold the back-transformd test-data
reduced_images = []
for n_components in [10, 50, 100, 500]:
# build the NMF model
nmf = NMF(n_components=n_components, random_state=0)
nmf.fit(X_train)
# transform the test data (afterwards has n_components many dimensions)
X_test_nmf = nmf.transform(X_test)
# back-transform the transformed test-data
# (afterwards it's in the original space again)
X_test_back = np.dot(X_test_nmf, nmf.components_)
reduced_images.append(X_test_back)
return reduced_images
def plot_nmf_faces(X_train, X_test, image_shape):
reduced_images = nmf_faces(X_train, X_test)
# plot the first three images in the test set:
fix, axes = plt.subplots(3, 5, figsize=(15, 12),
subplot_kw={'xticks': (), 'yticks': ()})
for i, ax in enumerate(axes):
# plot original image
ax[0].imshow(X_test[i].reshape(image_shape),
vmin=0, vmax=1)
# plot the four back-transformed images
for a, X_test_back in zip(ax[1:], reduced_images):
a.imshow(X_test_back[i].reshape(image_shape), vmin=0, vmax=1)
# label the top row
axes[0, 0].set_title("original image")
for ax, n_components in zip(axes[0, 1:], [10, 50, 100, 500]):
ax.set_title("%d components" % n_components)