我正在写DBSCAN,我遇到了一些奇怪的问题。(2个问题)
这是我的代码:
第一部分存在问题,如果我添加X = StandardScaler().fit_transform(X)
结果的坐标是错误的!但是,如果我没有添加此代码,它将始终是一个聚类(但结果的坐标是正确的!)。我尝试调整esp或min_samples,但它没有改变。
dataSet = []
fileIn = open('data')
for line in fileIn.readlines():
lineArr = line.strip().split('\t')
dataSet.append([float(lineArr[0]), float(lineArr[1])])
numSamples = len(dataSet)
X = np.array(dataSet)
X = StandardScaler().fit_transform(X)
(添加) (无)
db = DBSCAN(eps=0.5, min_samples=10).fit(X)
core_samples_mask = np.zeros_like(db.labels_, dtype=bool)
core_samples_mask[db.core_sample_indices_] = True
labels = db.labels_
print(labels)
counters = {}
for item in labels:
if item in counters:
counters[item] += 1
else:
counters[item] = 1
print ("Count of different cluster:(#r,g,b,a)")#r,g,b,a
print (counters)
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
print('Estimated number of clusters: %d' % n_clusters_)
第二个问题是我试图绘制我计算的坐标,但我不知道为什么它显示结果是错误的!
clusters = [np.mean(X[labels == i],axis=0) for i in range(n_clusters_)]
outliers = X[labels == 0]
print(clusters)
for i in range(n_clusters_):
plt.plot(clusters[i],'*',markersize=20)
unique_labels = set(labels)
colors = [plt.cm.Spectral(each)
for each in np.linspace(0, 1, len(unique_labels))]
for k, col in zip(unique_labels, colors):
if k == -1:
# Black used for noise.
col = [0, 0, 0, 1]
class_member_mask = (labels == k)
xy = X[class_member_mask & core_samples_mask]
plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),markeredgecolor='k', markersize=14)
xy = X[class_member_mask & ~core_samples_mask]
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()
请帮助我谢谢你!
答案 0 :(得分:1)
您显然需要为您的坐标系适当选择epsilon 。如果缩放数据,则epsilon将不再相同。你发现最简单的黑客攻击(但这不是正确的解决方案)就是使用未缩放的数据来计算均值。但无论如何,DBSCAN集群的手段都不可靠。
根据您的轴判断,您可能需要将epsilon降低100倍。
由于您的数据显然是坐标,因此您应使用Haversine距离,因为地球不平坦,并根据对您的问题有意义的距离选择epsilon。确切的缩放可能有点棘手。它可能是弧度,所以你需要将里程转换为弧度来转换距离。