如何对标记化的文档进行聚类

Posted

技术标签:

【中文标题】如何对标记化的文档进行聚类【英文标题】:how to cluster tokenized documents 【发布时间】:2018-09-20 19:11:11 【问题描述】:

我有一个文档列表,我想知道它们与某个文档的相似度有多接近。我只是想出了如何对标记化文档进行聚类,但我不知道如何检查它们与 target 文档的距离。

我实现聚类的方式是,我先取文档列表...

text = [
    "This is a test",
    "This is something else",
    "This is also a test"
]

然后我使用以下函数对它们进行标记...

def word_tokenizer(sentences):
    tokens = word_tokenize(sentences)
    stemmer = PorterStemmer()
    tokens = [stemmer.stem(t) for t in tokens if t not in stopwords.words('english')]
    return tokens

我将此函数传递给TfidfVectorizer...

tfidf_vect = TfidfVectorizer(
        tokenizer=word_tokenizer,
        max_df=0.9,
        min_df=0.1,
        lowercase=True
    )

tfidf_matrix = tfidf_vect.fit_transform(text)

然后我使用Kmeans 对矩阵进行聚类...

kmeans = KMeans(n_clusters=3)
kmeans.fit(tfidf_matrix)

然后我保存每个集群并打印出结果...

for i, label in enumerate(kmeans.labels_):
    clusters[label].append(i)
res = dict(clusters)

for cluster in range(3):
    print("cluster ", cluster, ":")
    for i, sentence in enumerate(res[cluster]):
        print("\tsentence ", i, ": ", text[sentence])

结果如下……

cluster  0 :
    sentence  0 :  This is also a test
cluster  1 :
    sentence  0 :  This is something else
cluster  2 :
    sentence  0 :  This is a test

这是有用的信息,但是假设我有一个目标文档,我想看看这些文档与目标的相似程度,我该怎么做?

例如,假设我有以下目标...

target = ["This is target"]

如何查看text 中的每个文档与此目标的相似程度?

【问题讨论】:

【参考方案1】:

对于您的问题,集群并没有真正用处。集群可以让您大致了解数据属于哪些组,但您不能使用它来比较两个单独的数据点。

此时您必须实现损失函数。我建议使用简单的方法,例如欧几里得距离或均方误差。

矢量化您的目标文档,并遍历您的tfidf_matrix。对于矩阵中的每个值,使用目标文档计算其损失。从这里您可以找到与哪个文档最相似/最不同的文档。

【讨论】:

【参考方案2】:

您想要相似性搜索,而不是聚类。

解决问题的工具不正确,你不需要为了喝啤酒就买下整个超市。

事实上,您现在又回到了最初遇到的相同问题...您将所有文档放入一个集群,现在需要找到最近的集群。马上找到最近的文件……或者回到超市的比喻:你买了整个超市,但现在你仍然需要去那里才能真正买到啤酒。

【讨论】:

对于这个特殊的挑战,我应该实施某种无监督的方法来检查相似性。如果这就是您所说的相似性搜索,我已经计算了文档之间的cosine similarity 哪个是无人监督的,不是吗? 我不确定,我认为这只是两个tfidf 矩阵之间的简单数学计算。但我想当你考虑它时,它是无人监督的。【参考方案3】:

您可以简单地使用KMeans.predict()

预测 X 中每个样本所属的最近聚类。

在向量量化文献中,cluster_centers_被称为 code book 和 predict 返回的每个值是 代码簿中最接近的代码。

这将返回新句子所属簇的索引。

对目标句子应用相同的预处理并调用 predict()。确保使用相同的 tfidfvectorizer 来转换句子。

类似:

target_tfidf_matrix = tfidf_vect.transform(target)
results = kmeans.predict(target_tfidf_matrix)

【讨论】:

我尝试实现这一点。您的回答似乎很有希望,但是我收到以下错误raise ValueError("After pruning, no terms remain. Try a lower" ValueError: After pruning, no terms remain. Try a lower min_df or a higher max_df.。知道为什么吗? @Bolboa。该错误似乎与 TfidfVectorizer 有关。确保您的 word_tokenizer 正在为提供的测试数据返回一些数据。请在问题中添加word_tokenize 函数,以便我可以复制行为。 错误很简单,我不小心将fit_transform应用于目标而不是transform。不过感谢您的帮助。

以上是关于如何对标记化的文档进行聚类的主要内容,如果未能解决你的问题,请参考以下文章

如何使用高斯混合模型进行聚类?

k均值聚类算法(k-means clustering algorithm)

聚类算法---引言

聚类K-means算法

分类与监督学习,朴素贝叶斯分类算法

出现标记聚类默认聚类