【问题标题】:Scipy, tf-idf and cosine similarityScipy、tf-idf 和余弦相似度
【发布时间】:2012-11-20 14:52:36
【问题描述】:

我正在尝试使用 python 根据 tf-idf 矩阵对一些文档进行聚类。

首先我遵循公式的维基百科定义,使用标准化的 tf. http://en.wikipedia.org/wiki/Tf-idf

Feat_vectors 以二维 numpy 数组开始,行表示文档,列表示术语,每个单元格中的值是每个文档中每个术语的出现次数。

import numpy as np

feat_vectors /= np.max(feat_vectors,axis=1)[:,np.newaxis]
idf = len(feat_vectors) / (feat_vectors != 0).sum(0)
idf = np.log(idf)
feat_vectors *= idf

然后我使用 scipy 对这些向量进行聚类:

from scipy.cluster import hierarchy

clusters = hierarchy.linkage(feat_vectors,method='complete',metric='cosine')
flat_clusters = hierarchy.fcluster(clusters, 0.8,'inconsistent')

但是,在最后一行它会抛出一个错误:

ValueError: Linkage 'Z' contains negative distances.

余弦相似度从 -1 变为 1。但是,余弦相似度的维基百科页面指出 http://en.wikipedia.org/wiki/Cosine_similarity

在信息检索的情况下,两个文档的余弦相似度范围 > 从 0 到 1,因为词频(tf-idf 权重)不能为负。

所以如果我得到一个负相似度,我似乎在计算 tf-idf 时犯了一些错误。任何想法我的错误是什么?

【问题讨论】:

  • 看起来您的 feat_vectors 具有负值。在乘以 idf 之前,或者在你取 np.log 之前 idf 的值小于 1。
  • 矩阵中的最小值为零。只是余弦相似度的结果是

标签: python scipy cluster-analysis trigonometry tf-idf


【解决方案1】:

我怀疑错误在以下行:

idf = len(feat_vectors) / (feat_vectors != 0).sum(0)

由于您的逻辑向量将在总和中转换为 int,而 len 是一个 int,因此您正在失去精度。替换为:

idf = float(len(feat_vectors)) / (feat_vectors != 0).sum(0)

为我工作(即用虚拟数据产生了我所期望的)。其他一切看起来都正确。

【讨论】:

    【解决方案2】:

    我知道这是一篇旧帖子,但最近我自己似乎偶然发现了这个问题。 事实上,一旦我自己的函数出现此错误,我什至使用 TfidfVectorizer(来自 sklearn.feature_extraction.text)生成 TFIDF 矩阵。这也没有帮助。

    似乎用于相似性的余弦度量会产生负值。我尝试了欧几里得,它立即起作用。 这是我发现的更详细答案的链接- https://stackoverflow.com/a/2590194/3228300

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-03
      • 1970-01-01
      • 2013-02-03
      • 2013-10-16
      • 2020-08-12
      • 2013-04-18
      • 2017-09-05
      相关资源
      最近更新 更多