I am attempting to demonstrate how DBSCAN can cluster data of arbitrary 2D shapes. I've created two toy datasets in Scikit-Learn using the
make_classification functions -- one dataset being easily separable, spherical data while the other has clusters of more nebulous shapes:
import matplotlib.pyplot as plt from sklearn import datasets %matplotlib inline centers_neat = [(-10, 10), (0, -5), (10, 5)] x_neat, y_neat = datasets.make_blobs(n_samples=3500, centers=centers_neat, cluster_std=2, random_state=2) x_messy, y_messy = datasets.make_classification(n_samples=3500, n_informative=2, n_classes=3, n_clusters_per_class=1, class_sep=1, shuffle=False, random_state=734) plt.figure(figsize=(15,8)) plt.subplot(121, title='"Neat" Clusters') plt.scatter(x_neat[:,0], x_neat[:,1]) plt.subplot(122, title='"Messy" Clusters') plt.scatter(x_messy[:,0], x_messy[:,1])
When attempting to cluster with DBSCAN on the right-side dataset, all points are returned as "noise" by the algorithm (i.e. they're labeled as "-1"). This seems to stay consistent no matter what parameters I use for
min_samples leaving all others as their default. I understand how DBSCAN works (at least I thought I did as I've successfully used it on other datasets) and this data should not present a problem for the algorithm. Here is the code and resulting output:
dbscan = DBSCAN().fit_predict(x_messy) plt.figure(figsize=(15,10)) plt.scatter(x_messy[:,0], x_messy[:,1], c=dbscan) plt.savefig('dbscan')
I also tried to run DBSCAN on the left-side data set with the same results -- all points labeled as noise.
Does the nature of how I'm creating the toy datasets impact the effectiveness of this algorithm? Is there just an issue with my code? I've also noticed that some of Scikit-Learn's other clustering algorithms fail on this data (Mean Shift and Spectral Clustering)