1
$\begingroup$

I was trying to plot the cluster result of DBSCAN clustering. I cluster data into two cluster and when i write code to plot those it shows 'name error'. But I couldn't understand whats the problem. Here's my code with error

for i in range(0, reduced_data.shape[0]):
    if dbscan.labels_[i] == 0:
        c1 = plt.scatter(reduced_data[i,0],reduced_data[i,1],c='r',marker='+')
    elif dbscan.labels_[i] == 1:
        c2 = plt.scatter(reduced_data[i,0],reduced_data[i,1],c='g',marker='o')
    elif dbscan.labels_[i] == -1:
        c3 = plt.scatter(reduced_data[i,0],reduced_data[i,1],c='b',marker='*')
    plt.legend([c1, c2, c3], ['Cluster 1', 'Cluster 2','Noise'])
    plt.title('DBSCAN finds 2 clusters and noise')
    plt.show()

enter image description here

Edited:

Rest of my code:

feature_cols = ['age','workclass','fnlwgt','education','education num','marital-status','occupation','relationship','race','sex','capital-gain','capital-loss','hours-per-week','native-country']
X = train[feature_cols]
y = train['label']

# split X and y into training and testing sets
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.30,random_state=10)

X_train_scale = scale(X_train)
X_test_scale = scale(X_test)

reduced_data = PCA(n_components=2).fit_transform(X_train_scale)
reduced_data_test = PCA(n_components=2).fit_transform(X_test_scale)

from pylab import *
xx, yy = zip(*reduced_data)
scatter(xx,yy)
show()

enter image description here

dbscan = DBSCAN(eps=0.3, min_samples=10).fit(reduced_data)
labels=dbscan.labels_
print(labels)

enter image description here

n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
print (n_clusters_)

The result of n_cluster is 2

and the main data before PCA reducing is like these: enter image description here

$\endgroup$
  • $\begingroup$ Says c2 was never defined. Seems that dbscan.labels_[i] is never 1. $\endgroup$ – JahKnows Feb 14 '18 at 6:31
  • $\begingroup$ Yeah I understand. But I have 22792 data and I divide those data into 2 cluster. I need to plot those data with noise. How can I do it ? $\endgroup$ – IS2057 Feb 14 '18 at 6:42
  • $\begingroup$ Can i see an example of the data, and also can i see the rest of the code please? $\endgroup$ – JahKnows Feb 14 '18 at 6:43
  • $\begingroup$ Ok. I'm uploading $\endgroup$ – IS2057 Feb 14 '18 at 6:45
  • $\begingroup$ You want different colors for each of your labels right instead of them all being blue? $\endgroup$ – JahKnows Feb 14 '18 at 7:16
3
$\begingroup$

In your specific case you only have 2 clusters, however this is not necessarily always going to be the case. I would allow for more flexibility.

I assume from your sample code that you are following what is shown in the docs. Following from what they are doing you should have the following

feature_cols = ['age','workclass','fnlwgt','education','education num','marital-status','occupation','relationship','race','sex','capital-gain','capital-loss','hours-per-week','native-country']
X = train[feature_cols]
y = train['label']

# split X and y into training and testing sets
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.30,random_state=10)

X_train_scale = scale(X_train)
X_test_scale = scale(X_test)

reduced_data = PCA(n_components=2).fit_transform(X_train_scale)
reduced_data_test = PCA(n_components=2).fit_transform(X_test_scale)

from pylab import *
xx, yy = zip(*reduced_data)
scatter(xx,yy)
show()

# Compute DBSCAN
db = DBSCAN(eps=0.3, min_samples=10).fit(reduced_data)
core_samples_mask = np.zeros_like(db.labels_, dtype=bool)
core_samples_mask[db.core_sample_indices_] = True
labels = db.labels_

# Number of clusters in labels, ignoring noise if present.
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)

I just changed your variable name dbscan to db to make it easier to go through the code from the source. From here you can plot all the different clusters that were identified by the DBSCAN method. You should also keep the mask which retains the labels as a list in order for us to access them easily when we plot.

We will identify what are the unique labels which DBSCAN identified and we will map a color to each of these labels.

# Plot result
import matplotlib.pyplot as plt

# Black removed and is used for noise instead.
unique_labels = set(labels)
colors = [plt.cm.Spectral(each)
          for each in np.linspace(0, 1, len(unique_labels))]

For each cluster as determined by the unique labels we will plot all the values associated with it as

for k, col in zip(unique_labels, colors):
    # -1 is an identifier for noise
    if k == -1:
        # Black used for noise.
        col = [0, 0, 0, 1]

    # Find out what instances belong to this cluster, k
    class_member_mask = (labels == k)

    # Pull out these instances
    xy = X[class_member_mask]

    # Plot all of these instances
    plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),
             markeredgecolor='k', markersize=6)

plt.title('Estimated number of clusters: %d' % n_clusters_)
plt.show()
$\endgroup$

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.