8

sklearn.clustering.DBSCAN 的输入是否应该被预处理?

在示例http://scikit-learn.org/stable/auto_examples/cluster/plot_dbscan.html#example-cluster-plot-dbscan-py中,输入样本 X 之间的距离被计算并归一化:

D = distance.squareform(distance.pdist(X))
S = 1 - (D / np.max(D))
db = DBSCAN(eps=0.95, min_samples=10).fit(S)

在 v0.14 ( http://jaquesgrobler.github.io/online-sklearn-build/auto_examples/cluster/plot_dbscan.html ) 的另一个示例中,完成了一些缩放:

X = StandardScaler().fit_transform(X)
db = DBSCAN(eps=0.3, min_samples=10).fit(X)

我将我的代码基于后一个示例,并让印象聚类在这种缩放下效果更好。然而,这种缩放“通过去除均值和缩放到单位方差来标准化特征”。我试图找到二维集群。如果我的集群分布在一个正方形区域中 - 比如说 100x100,我认为缩放没有问题。但是,如果它们分布在一个矩形区域中,例如 800x200,则缩放会“挤压”我的样本并在一维中改变它们之间的相对距离。这会恶化聚类,不是吗?还是我理解某事。错误的?我是否需要进行一些预处理,或者我可以简单地输入我的“原始”数据吗?

4

1 回答 1

15

这取决于你想要做什么。

如果您在地理数据上运行 DBSCAN,并且距离以米为单位,您可能不想标准化任何内容,但也要以米为单位设置您的 epsilon 阈值。

是的,特别是非均匀缩放确实会扭曲距离。而非扭曲缩放相当于只使用不同的 epsilon 值!

请注意,在第一个示例中,显然处理的是相似性而不是距离矩阵。S = (1 - D / np.max(D))是将相似矩阵转换为相异矩阵的启发式方法。Epsilon 0.95 则实际上意味着最多“观察到的最大差异的 0.05”。应该产生相同结果的替代版本是:

D = distance.squareform(distance.pdist(X))
S = np.max(D) - D
db = DBSCAN(eps=0.95 * np.max(D), min_samples=10).fit(S)

而在第二个示例中,fit(X)实际上处理的是原始输入数据,而不是距离矩阵。恕我直言,这是一个丑陋的黑客,以这种方式重载方法。这很方便,但有时会导致误解甚至不正确的使用。

总的来说,我不会将 sklearn 的 DBSCAN 作为参考。整个 API 似乎很大程度上受分类驱动,而不是集群驱动。通常,您不fit进行聚类,仅对监督方法执行此操作。另外,sklearn 目前不使用索引来加速,并且需要O(n^2)内存(DBSCAN 通常不需要)。

一般来说,您需要确保您的距离有效。如果您的距离函数不起作用,则基于距离的算法将不会产生所需的结果。在某些数据集上,当您首次规范化数据时,欧几里得距离等朴素距离效果更好。在其他数据集上,您对距离是什么有很好的理解(例如地理数据。对此进行标准化显然没有意义,欧几里得距离也没有!)

于 2013-07-04T07:38:17.337 回答