2011-04-03 02:57:38 +08:00
|
|
|
"""
|
|
|
|
|
===========================================================
|
|
|
|
|
Hierarchical clustering: structured vs unstructured ward
|
|
|
|
|
===========================================================
|
|
|
|
|
|
|
|
|
|
Example builds a swiss roll dataset and runs
|
2013-07-22 21:48:44 +08:00
|
|
|
hierarchical clustering on their position.
|
2011-04-03 02:57:38 +08:00
|
|
|
|
2013-07-24 17:36:46 +08:00
|
|
|
For more information, see :ref:`hierarchical_clustering`.
|
|
|
|
|
|
|
|
|
|
In a first step, the hierarchical clustering is performed without connectivity
|
|
|
|
|
constraints on the structure and is solely based on distance, whereas in
|
|
|
|
|
a second step the clustering is restricted to the k-Nearest Neighbors
|
|
|
|
|
graph: it's a hierarchical clustering with structure prior.
|
2011-04-03 02:57:38 +08:00
|
|
|
|
|
|
|
|
Some of the clusters learned without connectivity constraints do not
|
2011-05-04 23:49:17 +08:00
|
|
|
respect the structure of the swiss roll and extend across different folds of
|
2011-04-03 02:57:38 +08:00
|
|
|
the manifolds. On the opposite, when opposing connectivity constraints,
|
|
|
|
|
the clusters form a nice parcellation of the swiss roll.
|
2021-10-22 21:33:22 +08:00
|
|
|
|
2011-04-03 02:57:38 +08:00
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
# Authors : Vincent Michel, 2010
|
|
|
|
|
# Alexandre Gramfort, 2010
|
|
|
|
|
# Gael Varoquaux, 2010
|
2013-04-30 14:23:46 +08:00
|
|
|
# License: BSD 3 clause
|
2011-04-03 02:57:38 +08:00
|
|
|
|
|
|
|
|
import time as time
|
2022-03-02 17:24:02 +08:00
|
|
|
|
|
|
|
|
# The following import is required
|
|
|
|
|
# for 3D projection to work with matplotlib < 3.2
|
|
|
|
|
import mpl_toolkits.mplot3d # noqa: F401
|
|
|
|
|
import numpy as np
|
|
|
|
|
|
2022-05-01 17:41:18 +08:00
|
|
|
# %%
|
|
|
|
|
# Generate data
|
|
|
|
|
# -------------
|
|
|
|
|
#
|
|
|
|
|
# We start by generating the Swiss Roll dataset.
|
2019-10-28 05:17:23 +08:00
|
|
|
from sklearn.datasets import make_swiss_roll
|
2011-04-03 02:57:38 +08:00
|
|
|
|
2014-02-06 23:55:46 +08:00
|
|
|
n_samples = 1500
|
2011-04-03 02:57:38 +08:00
|
|
|
noise = 0.05
|
2020-05-19 00:35:12 +08:00
|
|
|
X, _ = make_swiss_roll(n_samples, noise=noise)
|
2011-04-03 02:57:38 +08:00
|
|
|
# Make it thinner
|
|
|
|
|
X[:, 1] *= 0.5
|
|
|
|
|
|
2022-05-01 17:41:18 +08:00
|
|
|
# %%
|
2011-04-03 02:57:38 +08:00
|
|
|
# Compute clustering
|
2022-05-01 17:41:18 +08:00
|
|
|
# ------------------
|
|
|
|
|
#
|
|
|
|
|
# We perform AgglomerativeClustering which comes under Hierarchical Clustering
|
|
|
|
|
# without any connectivity constraints.
|
|
|
|
|
|
|
|
|
|
from sklearn.cluster import AgglomerativeClustering
|
|
|
|
|
|
2013-02-01 22:04:03 +08:00
|
|
|
print("Compute unstructured hierarchical clustering...")
|
2011-04-03 02:57:38 +08:00
|
|
|
st = time.time()
|
2014-02-07 16:25:08 +08:00
|
|
|
ward = AgglomerativeClustering(n_clusters=6, linkage="ward").fit(X)
|
2014-02-06 23:55:46 +08:00
|
|
|
elapsed_time = time.time() - st
|
2011-04-03 02:57:38 +08:00
|
|
|
label = ward.labels_
|
2022-05-01 17:41:18 +08:00
|
|
|
print(f"Elapsed time: {elapsed_time:.2f}s")
|
|
|
|
|
print(f"Number of points: {label.size}")
|
2011-04-03 02:57:38 +08:00
|
|
|
|
2022-05-01 17:41:18 +08:00
|
|
|
# %%
|
2011-04-03 02:57:38 +08:00
|
|
|
# Plot result
|
2022-05-01 17:41:18 +08:00
|
|
|
# -----------
|
|
|
|
|
# Plotting the unstructured hierarchical clusters.
|
|
|
|
|
|
|
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
|
|
|
|
|
|
fig1 = plt.figure()
|
|
|
|
|
ax1 = fig1.add_subplot(111, projection="3d", elev=7, azim=-80)
|
|
|
|
|
ax1.set_position([0, 0, 0.95, 1])
|
2011-04-03 02:57:38 +08:00
|
|
|
for l in np.unique(label):
|
2022-05-01 17:41:18 +08:00
|
|
|
ax1.scatter(
|
2017-06-21 22:04:53 +08:00
|
|
|
X[label == l, 0],
|
|
|
|
|
X[label == l, 1],
|
|
|
|
|
X[label == l, 2],
|
2020-06-24 22:51:51 +08:00
|
|
|
color=plt.cm.jet(float(l) / np.max(label + 1)),
|
2017-06-21 22:04:53 +08:00
|
|
|
s=20,
|
|
|
|
|
edgecolor="k",
|
|
|
|
|
)
|
2022-05-01 17:41:18 +08:00
|
|
|
_ = fig1.suptitle(f"Without connectivity constraints (time {elapsed_time:.2f}s)")
|
|
|
|
|
|
|
|
|
|
# %%
|
|
|
|
|
# We are defining k-Nearest Neighbors with 10 neighbors
|
|
|
|
|
# -----------------------------------------------------
|
2011-04-03 02:57:38 +08:00
|
|
|
|
2011-09-02 17:00:02 +08:00
|
|
|
from sklearn.neighbors import kneighbors_graph
|
2021-10-07 16:13:00 +08:00
|
|
|
|
2015-03-17 01:30:22 +08:00
|
|
|
connectivity = kneighbors_graph(X, n_neighbors=10, include_self=False)
|
2011-04-03 02:57:38 +08:00
|
|
|
|
2022-05-01 17:41:18 +08:00
|
|
|
# %%
|
2011-04-03 02:57:38 +08:00
|
|
|
# Compute clustering
|
2022-05-01 17:41:18 +08:00
|
|
|
# ------------------
|
|
|
|
|
#
|
|
|
|
|
# We perform AgglomerativeClustering again with connectivity constraints.
|
|
|
|
|
|
2013-02-01 22:04:03 +08:00
|
|
|
print("Compute structured hierarchical clustering...")
|
2011-04-03 02:57:38 +08:00
|
|
|
st = time.time()
|
2014-02-07 16:25:08 +08:00
|
|
|
ward = AgglomerativeClustering(
|
|
|
|
|
n_clusters=6, connectivity=connectivity, linkage="ward"
|
|
|
|
|
).fit(X)
|
2014-02-06 23:55:46 +08:00
|
|
|
elapsed_time = time.time() - st
|
2011-04-03 02:57:38 +08:00
|
|
|
label = ward.labels_
|
2022-05-01 17:41:18 +08:00
|
|
|
print(f"Elapsed time: {elapsed_time:.2f}s")
|
|
|
|
|
print(f"Number of points: {label.size}")
|
2011-04-03 02:57:38 +08:00
|
|
|
|
2022-05-01 17:41:18 +08:00
|
|
|
# %%
|
2011-04-03 02:57:38 +08:00
|
|
|
# Plot result
|
2022-05-01 17:41:18 +08:00
|
|
|
# -----------
|
|
|
|
|
#
|
|
|
|
|
# Plotting the structured hierarchical clusters.
|
|
|
|
|
|
|
|
|
|
fig2 = plt.figure()
|
|
|
|
|
ax2 = fig2.add_subplot(121, projection="3d", elev=7, azim=-80)
|
|
|
|
|
ax2.set_position([0, 0, 0.95, 1])
|
2011-04-03 02:57:38 +08:00
|
|
|
for l in np.unique(label):
|
2022-05-01 17:41:18 +08:00
|
|
|
ax2.scatter(
|
2017-06-21 22:04:53 +08:00
|
|
|
X[label == l, 0],
|
|
|
|
|
X[label == l, 1],
|
|
|
|
|
X[label == l, 2],
|
|
|
|
|
color=plt.cm.jet(float(l) / np.max(label + 1)),
|
|
|
|
|
s=20,
|
|
|
|
|
edgecolor="k",
|
|
|
|
|
)
|
2022-05-01 17:41:18 +08:00
|
|
|
fig2.suptitle(f"With connectivity constraints (time {elapsed_time:.2f}s)")
|
2011-04-03 02:57:38 +08:00
|
|
|
|
2014-05-15 04:31:03 +08:00
|
|
|
plt.show()
|