我有一组大约34,000个数据标签及其各自的特征(状态概率)在2D numpy数组中,可视化为散点图,看起来。
很容易看出大多数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数据点的密集区域?
答案 0 :(得分:0)
不要包含ID属性。据推测,你的“节点索引”不应该用于相似性计算吗?
当属性具有不同的单位和比例时,您需要非常小心。流行的启发式算法是StandardScaler
,即将每个属性标准化以具有单位方差。但是考虑到你的数据的分布(在x上统一,在y上倾斜),我认为理论很好地支持标准化的使用 - 它假设高斯分布。
这两者的结合就是你得到这个结果的原因:你的x轴完全支配着结果。它实际上比你的y轴有超过10000倍的影响你实际上只是根据节点ID ...
进行聚类永远不要假设群集“只是工作”。所有这些方法都非常对预处理敏感,因此需要谨慎应用。