2011-07-12 20:45:20 +08:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
"""
|
|
|
|
|
===================================
|
|
|
|
|
Demo of DBSCAN clustering algorithm
|
|
|
|
|
===================================
|
|
|
|
|
|
2011-08-06 16:11:57 +08:00
|
|
|
Finds core samples of high density and expands clusters from them.
|
2011-07-12 20:45:20 +08:00
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
print __doc__
|
|
|
|
|
|
|
|
|
|
import numpy as np
|
|
|
|
|
from scipy.spatial import distance
|
2011-09-02 17:00:02 +08:00
|
|
|
from sklearn.cluster import DBSCAN
|
|
|
|
|
from sklearn import metrics
|
|
|
|
|
from sklearn.datasets.samples_generator import make_blobs
|
2011-07-12 20:45:20 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
##############################################################################
|
|
|
|
|
# Generate sample data
|
|
|
|
|
centers = [[1, 1], [-1, -1], [1, -1]]
|
2011-07-26 07:53:31 +08:00
|
|
|
X, labels_true = make_blobs(n_samples=750, centers=centers, cluster_std=0.4)
|
2011-07-12 20:45:20 +08:00
|
|
|
|
|
|
|
|
##############################################################################
|
|
|
|
|
# Compute similarities
|
|
|
|
|
D = distance.squareform(distance.pdist(X))
|
|
|
|
|
S = 1 - (D / np.max(D))
|
|
|
|
|
|
|
|
|
|
##############################################################################
|
|
|
|
|
# Compute DBSCAN
|
2012-05-16 03:37:33 +08:00
|
|
|
db = DBSCAN(eps=0.95, min_samples=10).fit(S)
|
2011-08-06 16:11:57 +08:00
|
|
|
core_samples = db.core_sample_indices_
|
2011-07-12 20:45:20 +08:00
|
|
|
labels = db.labels_
|
|
|
|
|
|
|
|
|
|
# Number of clusters in labels, ignoring noise if present.
|
|
|
|
|
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
|
|
|
|
|
|
|
|
|
|
print 'Estimated number of clusters: %d' % n_clusters_
|
|
|
|
|
print "Homogeneity: %0.3f" % metrics.homogeneity_score(labels_true, labels)
|
|
|
|
|
print "Completeness: %0.3f" % metrics.completeness_score(labels_true, labels)
|
|
|
|
|
print "V-measure: %0.3f" % metrics.v_measure_score(labels_true, labels)
|
2011-09-13 22:50:30 +08:00
|
|
|
print "Adjusted Rand Index: %0.3f" % \
|
|
|
|
|
metrics.adjusted_rand_score(labels_true, labels)
|
2011-10-21 07:52:42 +08:00
|
|
|
print "Adjusted Mutual Information: %0.3f" % \
|
2011-11-07 19:46:11 +08:00
|
|
|
metrics.adjusted_mutual_info_score(labels_true, labels)
|
2011-10-04 08:23:14 +08:00
|
|
|
print ("Silhouette Coefficient: %0.3f" %
|
|
|
|
|
metrics.silhouette_score(D, labels, metric='precomputed'))
|
2011-07-12 20:45:20 +08:00
|
|
|
|
|
|
|
|
##############################################################################
|
|
|
|
|
# Plot result
|
|
|
|
|
import pylab as pl
|
|
|
|
|
from itertools import cycle
|
|
|
|
|
|
|
|
|
|
pl.close('all')
|
|
|
|
|
pl.figure(1)
|
|
|
|
|
pl.clf()
|
|
|
|
|
|
|
|
|
|
# Black removed and is used for noise instead.
|
|
|
|
|
colors = cycle('bgrcmybgrcmybgrcmybgrcmy')
|
|
|
|
|
for k, col in zip(set(labels), colors):
|
|
|
|
|
if k == -1:
|
|
|
|
|
# Black used for noise.
|
|
|
|
|
col = 'k'
|
|
|
|
|
markersize = 6
|
|
|
|
|
class_members = [index[0] for index in np.argwhere(labels == k)]
|
2011-08-03 20:10:30 +08:00
|
|
|
cluster_core_samples = [index for index in core_samples
|
|
|
|
|
if labels[index] == k]
|
2011-07-12 20:45:20 +08:00
|
|
|
for index in class_members:
|
|
|
|
|
x = X[index]
|
2011-08-03 20:10:30 +08:00
|
|
|
if index in core_samples and k != -1:
|
2011-07-12 20:45:20 +08:00
|
|
|
markersize = 14
|
|
|
|
|
else:
|
|
|
|
|
markersize = 6
|
|
|
|
|
pl.plot(x[0], x[1], 'o', markerfacecolor=col,
|
|
|
|
|
markeredgecolor='k', markersize=markersize)
|
|
|
|
|
|
|
|
|
|
pl.title('Estimated number of clusters: %d' % n_clusters_)
|
|
|
|
|
pl.show()
|