如何对标记化的文档进行聚类
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
。不过感谢您的帮助。以上是关于如何对标记化的文档进行聚类的主要内容,如果未能解决你的问题,请参考以下文章