【发布时间】:2017-01-28 22:50:54
【问题描述】:
我在一个二维 numpy 数组中有一组大约 34,000 个数据标签及其各自的特征(状态概率),可视化为散点图,看起来像 。
很容易看出,大部分 b 数据点位于底部且非常密集。我想使用聚类算法来提取底部区域。我不追求完美的结果。这只是关于提取大部分 b 点。
到目前为止,我已经尝试了 DBSCAN 算法:
import sklearn.cluster as sklc
data1, data2 = zip(*dist_list[1])
data = np.array([data1, data2]).T
core_samples, labels_db = sklc.dbscan(
data, # array has to be (n_samples, n_features)
eps=2.0,
min_samples=5,
metric='euclidean',
algorithm='auto'
)
core_samples_mask = np.zeros_like(labels_db, dtype=bool)
core_samples_mask[core_samples] = True
unique_labels = set(labels_db)
n_clusters_ = len(unique_labels) - (1 if -1 in labels_db else 0)
colors = plt.cm.Spectral(np.linspace(0, 1, len(unique_labels)))
for k, col in zip(unique_labels, colors):
if k == -1:
# Black used for noise.
col = 'k'
class_member_mask = (labels_db == k)
xy = data[class_member_mask & core_samples_mask]
plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=col, markeredgecolor='k', markersize=6)
xy = data[class_member_mask & ~core_samples_mask]
plt.plot(xy[:, 0], xy[:, 1], 'x', markerfacecolor=col, markeredgecolor='k', markersize=4)
plt.rcParams["figure.figsize"] = (15, 15)
plt.title('Estimated number of clusters: %d' % n_clusters_)
plt.show()
产生。
增加最小样本量只会导致更小的垂直线被归类为噪声,而更长(和更密集)的垂直线会保留下来。
我还尝试使用scipy.cluster.hierarchy 进行聚类:
thresh = 2
clusters = hcluster.fclusterdata(data, thresh, criterion="distance")
plt.scatter(*data.T, c=clusters)
title = "t=%f, n=%d" % (thresh, len(set(clusters)))
plt.title(title)
plt.show()
这导致了类似的垂直分类。请查看该情节的评论。以我的名声,我还不能发布两个以上的链接。
现在我的问题是,我在校准算法时犯了错误吗?还是我选择的算法一开始就错了?如何提取b个数据点的密集区域?
【问题讨论】:
-
This 是我使用 scipy 层次算法后得到的类似分类。
-
尝试扩展您的数据。 x 轴的范围从 0 到 35,000,而 y 轴的范围从 0 到 1。垂直距离远小于水平距离,这就是算法将数据点垂直聚类的原因。查看 Scikit-learn (scikit-learn.org/stable/modules/preprocessing.html) 的预处理实用程序。
-
也许你想多了。看起来您只需对 y 值应用阈值就可以做得很好,例如中位数 +/- 0.01。
-
一维(线性)数组怎么样,例如有事件(或没有事件)的时间线?我们如何在没有预先指定的情况下找到密度,聚类为最高密度(1 个点是无限密度,2 个接近点非常高,但也许有 5 或 15 个点的聚类接近高密度)?这是一个简单的过程,还是必须反复进行?在 SAS(我选择的语言)中,可以使用滞后代码找到 n 点的平均值 link
标签: python scipy scikit-learn cluster-analysis dbscan