2013-07-24 05:05:01 +08:00
|
|
|
"""
|
2013-07-24 05:15:15 +08:00
|
|
|
Agglomerative clustering with and without structure
|
2013-07-24 05:05:01 +08:00
|
|
|
===================================================
|
|
|
|
|
|
2014-02-07 01:03:18 +08:00
|
|
|
This example shows the effect of imposing a connectivity graph to capture
|
|
|
|
|
local structure in the data. The graph is simply the graph of 20 nearest
|
|
|
|
|
neighbors.
|
|
|
|
|
|
|
|
|
|
Two consequences of imposing a connectivity can be seen. First clustering
|
|
|
|
|
with a connectivity matrix is much faster.
|
|
|
|
|
|
2018-01-22 21:58:17 +08:00
|
|
|
Second, when using a connectivity matrix, single, average and complete
|
|
|
|
|
linkage are unstable and tend to create a few clusters that grow very
|
|
|
|
|
quickly. Indeed, average and complete linkage fight this percolation behavior
|
|
|
|
|
by considering all the distances between two clusters when merging them (
|
|
|
|
|
while single linkage exaggerates the behaviour by considering only the
|
|
|
|
|
shortest distance between clusters). The connectivity graph breaks this
|
|
|
|
|
mechanism for average and complete linkage, making them resemble the more
|
|
|
|
|
brittle single linkage. This effect is more pronounced for very sparse graphs
|
|
|
|
|
(try decreasing the number of neighbors in kneighbors_graph) and with
|
|
|
|
|
complete linkage. In particular, having a very small number of neighbors in
|
|
|
|
|
the graph, imposes a geometry that is close to that of single linkage,
|
|
|
|
|
which is well known to have this percolation instability. """
|
2014-02-06 23:55:46 +08:00
|
|
|
# Authors: Gael Varoquaux, Nelle Varoquaux
|
2014-02-17 15:34:25 +08:00
|
|
|
# License: BSD 3 clause
|
2013-07-24 05:05:01 +08:00
|
|
|
|
2013-07-24 00:21:06 +08:00
|
|
|
import time
|
2013-07-24 16:04:58 +08:00
|
|
|
import matplotlib.pyplot as plt
|
2013-07-24 05:05:01 +08:00
|
|
|
import numpy as np
|
2013-07-24 00:21:06 +08:00
|
|
|
|
2013-07-24 16:04:58 +08:00
|
|
|
from sklearn.cluster import AgglomerativeClustering
|
2013-07-24 05:05:01 +08:00
|
|
|
from sklearn.neighbors import kneighbors_graph
|
2013-07-24 00:21:06 +08:00
|
|
|
|
|
|
|
|
# Generate sample data
|
2013-07-24 05:05:01 +08:00
|
|
|
n_samples = 1500
|
|
|
|
|
np.random.seed(0)
|
|
|
|
|
t = 1.5 * np.pi * (1 + 3 * np.random.rand(1, n_samples))
|
|
|
|
|
x = t * np.cos(t)
|
|
|
|
|
y = t * np.sin(t)
|
|
|
|
|
|
2014-02-06 19:51:42 +08:00
|
|
|
|
2013-07-24 05:05:01 +08:00
|
|
|
X = np.concatenate((x, y))
|
2014-02-06 19:51:42 +08:00
|
|
|
X += .7 * np.random.randn(2, n_samples)
|
2013-07-24 05:05:01 +08:00
|
|
|
X = X.T
|
|
|
|
|
|
|
|
|
|
# Create a graph capturing local connectivity. Larger number of neighbors
|
|
|
|
|
# will give more homogeneous clusters to the cost of computation
|
2014-02-07 01:03:18 +08:00
|
|
|
# time. A very large number of neighbors gives more evenly distributed
|
|
|
|
|
# cluster sizes, but may not impose the local manifold structure of
|
|
|
|
|
# the data
|
2015-03-03 01:50:53 +08:00
|
|
|
knn_graph = kneighbors_graph(X, 30, include_self=False)
|
2013-07-24 05:05:01 +08:00
|
|
|
|
2014-02-06 19:51:42 +08:00
|
|
|
for connectivity in (None, knn_graph):
|
|
|
|
|
for n_clusters in (30, 3):
|
2014-02-06 23:55:46 +08:00
|
|
|
plt.figure(figsize=(10, 4))
|
2018-01-22 21:58:17 +08:00
|
|
|
for index, linkage in enumerate(('average',
|
|
|
|
|
'complete',
|
|
|
|
|
'ward',
|
|
|
|
|
'single')):
|
|
|
|
|
plt.subplot(1, 4, index + 1)
|
2013-07-24 05:15:15 +08:00
|
|
|
model = AgglomerativeClustering(linkage=linkage,
|
2013-07-24 16:04:58 +08:00
|
|
|
connectivity=connectivity,
|
|
|
|
|
n_clusters=n_clusters)
|
2013-07-24 00:21:06 +08:00
|
|
|
t0 = time.time()
|
|
|
|
|
model.fit(X)
|
|
|
|
|
elapsed_time = time.time() - t0
|
2013-07-24 16:04:58 +08:00
|
|
|
plt.scatter(X[:, 0], X[:, 1], c=model.labels_,
|
2018-03-07 13:49:45 +08:00
|
|
|
cmap=plt.cm.nipy_spectral)
|
2018-01-22 21:58:17 +08:00
|
|
|
plt.title('linkage=%s\n(time %.2fs)' % (linkage, elapsed_time),
|
2013-07-24 16:04:58 +08:00
|
|
|
fontdict=dict(verticalalignment='top'))
|
2014-02-06 19:51:42 +08:00
|
|
|
plt.axis('equal')
|
2013-07-24 16:04:58 +08:00
|
|
|
plt.axis('off')
|
2013-07-24 00:21:06 +08:00
|
|
|
|
2014-02-06 23:55:46 +08:00
|
|
|
plt.subplots_adjust(bottom=0, top=.89, wspace=0,
|
2014-02-06 19:51:42 +08:00
|
|
|
left=0, right=1)
|
2014-02-06 23:55:46 +08:00
|
|
|
plt.suptitle('n_cluster=%i, connectivity=%r' %
|
|
|
|
|
(n_clusters, connectivity is not None), size=17)
|
2013-07-24 00:21:06 +08:00
|
|
|
|
|
|
|
|
|
2013-07-24 16:04:58 +08:00
|
|
|
plt.show()
|