【问题标题】:How to explain text clustering result by feature importance? (DBSCAN)如何按特征重要性解释文本聚类结果? (DBSCAN)
【发布时间】:2023-03-26 21:00:01
【问题描述】:

有类似的questionsELI5LIME 等库。但我找不到解决我的问题的方法。我有一组文档,我正在尝试使用 scikit-learn 的DBSCAN 对它们进行聚类。首先,我使用TfidfVectorizer 对文档进行矢量化处理。然后,我简单地对数据进行聚类并接收预测的标签。我的问题是:如何解释集群形成的原因?我的意思是,假设有 2 个预测集群(集群 1 和集群 2)。 哪些特征(因为我们的输入数据是矢量化文档,所以我们的特征是矢量化“词”)对于创建集群 1(或集群 2)很重要?

您可以在下面找到我目前正在研究的一个最小示例。这不是我试图实现的最小工作示例(因为我不知道如何实现)。

import numpy as np
import pandas as pd
from sklearn.cluster import DBSCAN
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer

categories = ['alt.atheism', 'soc.religion.christian',
              'comp.graphics', 'sci.med']
twenty_train = fetch_20newsgroups(
    subset='train',
    categories=categories,
    shuffle=True,
    random_state=42,
    remove=('headers', 'footers'),
)

visualize_train_data = pd.DataFrame(data=np.c_[twenty_train
                                                      ['data'], twenty_train
                                                      ['target']])
print(visualize_train_data.head())

vec = TfidfVectorizer(min_df=3, stop_words='english',
                      ngram_range=(1, 2))
vectorized_train_data = vec.fit_transform(twenty_train.data)

clustering = DBSCAN(eps=0.6, min_samples=2).fit(vectorized_train_data)
print(f"Unique labels are {np.unique(clustering.labels_)}")

旁注:我提供的问题专门针对 k-Means 算法,而答案不是很直观(对我而言)。 ELI5 和 LIME 是很棒的库,但它们提供的示例要么与回归相关,要么与分类相关(不是聚类),并且它们的回归器和分类器直接支持“预测”。 DBSCAN 不...

【问题讨论】:

  • 可能与您的问题无关,但我认为在回答您的问题之前,主要问题是您为什么使用 DBSCAN?有什么特殊原因吗?你认为你的数据的几何结构意味着什么,所以不是 K-means,而是 DBSCAN?还是其他原因?
  • @alift 因为我的数据集可能包含异常值。 DBSCAN 非常擅长寻找它们。
  • 我明白你的意思,但是,对于克服异常值,DBSCAN 不是一个通用的解决方案恕我直言。当您使用 DBSCAN 时,您有一些预先假设,即数据之间的连接意味着某些东西,例如多种示例。无论如何,我认为对于集群的推理,这是集群之后的一个常见问题。一个随机的猜测是检查集群,看看对于某些人来说,文档正在谈论的概念是否接近?就像在一个集群中,都有政治主题,而在另一个集群中,都是关于体育的
  • @alift 这就是我想要的。我想知道“集群 1”和“集群 2”的特征排名(重要的“单词”或主题)。
  • 如果我们假设您确定聚类的质量,并且您只想解释到达 cluster1 和 cluster2 的含义,为什么不从每个聚类内的单词分布开始呢?假设你有 5 个词,cluster1 的 dist 像 100,0,0,200,0,cluster2 有 10,20,1000,30,4,那么你可以猜想 word1 和 word4 正在解释 cluster1,word3 是 cluster2 的前导。跨度>

标签: python machine-learning cluster-analysis dbscan eli5


【解决方案1】:

首先,让我们了解您使用的嵌入空间是什么。 TfidfVectorizer 将创建一个非常稀疏的矩阵,其中一个维度对应于句子,另一个对应于您的词汇表(文本中的所有单词,除了“停用词”并且非常罕见 - 参见 min_dfstop_words)。当您要求 DBSCAN 对句子进行聚类时,它会采用单词 tf-idfs 的这些表示,并使用欧几里得距离度量找到彼此接近的句子。因此,希望您的集群应该由具有常用词的句子创建。为了找出特定聚类中哪些词(或“特征”)最重要,只需取属于同一聚类的句子(矩阵的行),然后找到顶部 K(比如说~10) 具有最常见非零值的列的索引。然后查找这些词使用的是什么vec.get_feature_names()

更新

cluster_id = 55   # select some cluster
feat_freq = (vectorized_train_data[(clustering.labels_== cluster_id)] > 0).astype(int).sum(axis=0)  # find frequencies of the words
max_idx = np.argwhere(feat_freq == feat_freq.max())[:,1]  # select those with maximum frequency
for i in max_idx:
    print(i, vec.get_feature_names()[i])
    

请注意,您在这里获得的集群非常小。集群 55 只有 4 个句子。其他大多数只有两句话。

【讨论】:

  • 我仍在尝试使用 scipy.sparse.csr_matrix 执行此操作,因为这是我从 TfidfVectorizer 获得的格式(并且在内存方面,这比密集数组更有效)。但我不擅长稀疏格式。您的回答是有道理的,但我对速度和内存使用有些担忧。如果您有任何其他建议,请告诉我。 (或者一段代码会很棒:D)
  • 好的,我已经取得了一些进展。我正在尝试使用 tf-idf 功能而不是“原始最常用词”。我可能会给你赏金。感谢您的帮助。
【解决方案2】:

DBSCAN 与 sklearn 中的大多数聚类算法一样,不提供predict 方法或特征重要性。因此,您可以 (1) 通过训练逻辑回归或使用集群标签的任何其他可解释分类器来重建决策过程,或者 (2) 切换到另一种文本聚类方法,例如 NMF 或 LDA。第一种方法正是 Lime 之类的方法。

【讨论】:

    猜你喜欢
    • 2018-12-24
    • 2018-04-14
    • 2019-12-04
    • 2014-07-10
    • 2017-09-24
    • 2016-02-23
    • 2019-10-20
    • 2016-07-28
    • 2014-08-13
    相关资源
    最近更新 更多