为什么使用 DBSCAN 将我的大部分点归类为噪声?

机器算法验证 聚类 scikit-学习 文本挖掘 数据库扫描
2022-03-30 02:22:12

我正在使用 sklearn 中的几种聚类算法来聚类一些数据,但似乎无法弄清楚 DBSCAN 发生了什么。我的数据是来自 TfidfVectorizer 的文档术语矩阵,包含数百个预处理文档。

代码:

tfv = TfidfVectorizer(stop_words=STOP_WORDS, tokenizer=StemTokenizer())
data = tfv.fit_transform(dataset)

db = DBSCAN(eps=eps, min_samples=min_samples)
result = db.fit_predict(data)
svd = TruncatedSVD(n_components=2).fit_transform(data)
// Set the colour of noise pts to black
for i in range(0,len(result)):
        if result[i] == -1:
            result[i] = 7
colors = [LABELS[l] for l in result]
pl.scatter(svd[:,0], svd[:,1], c=colors, s=50, linewidths=0.5, alpha=0.7)

这是 eps=0.5, min_samples=5 得到的结果:

基本上,除非我将 min_samples 设置为 3,否则我根本无法获得任何集群,这给出了:

我尝试了 eps/min_samples 值的各种组合并得到了类似的结果。它似乎总是首先聚集低密度区域。为什么会这样聚集?我可能错误地使用了 TruncatedSVD 吗?

1个回答

原始TFIDF数据的SVD 投影分数的散点图确实表明确实应该检测到一些密度结构。然而,这些数据并不是 DBSCAN 提供的输入。看来您正在使用原始 TFIDF数据作为输入。

原始 TFIDF 数据集是稀疏且高维的,这是非常合理的。在这样的域中检测基于密度的集群将非常苛刻。高维密度估计是一个相当困难的问题;这是维度诅咒开始的典型场景。我们只是看到了这个问题的表现(“诅咒”);DBSCAN 返回的结果聚类本身相当稀疏,并且假设(可能错误地)手头的数据充满了异常值。

我建议,至少在第一个实例中,DBSCAN 提供了用于创建显示为输入的散点图的投影分数。这种方法将有效地成为潜在语义分析(LSA)。在 LSA 中,我们使用包含所分析文本语料库字数的矩阵的 SVD 分解(或 TFIDF 返回的标准化术语文档矩阵)来研究手头语料库的文本单元之间的关系。