python - 使用 scikit learn 计算文本相似度时出错

标签 python machine-learning nltk cosine-similarity

我是向量空间模型 (VSM) 的初学者。我尝试了代码 this site .这是对 VSM 的一个很好的介绍,但我以某种方式设法从作者那里得到了不同的结果。可能是因为一些兼容性问题 scikit learn自从写了介绍以来似乎发生了很大变化。可能是我也误解了解释。
我使用下面的代码得到了错误的答案。有人能弄清楚它有什么问题吗?我在下面发布代码的结果和下面的正确答案

我已经手工完成了计算,所以我知道网站的结果很好。 还有一个Stackoverflow question使用相同的代码,但也不会得到与网站相同的结果。

import numpy, scipy, sklearn

train_set = ("The sky is blue.","The sun is bright.")
test_set = ("The sun is the sky is bright.", "We can see the shining sun, the bright sun.")

from sklearn.feature_extraction.text import CountVectorizer
vectorizer = CountVectorizer(stop_words= 'english')

vectorizer.fit_transform(train_set)


smatrix = vectorizer.transform(test_set)


from sklearn.feature_extraction.text import TfidfTransformer


tfidf = TfidfTransformer(norm='l2', sublinear_tf=True)


tfidf.fit(smatrix)
#print smatrix.todense()
print tfidf.idf_

tf_idf_matrix = tfidf.transform(smatrix)
print tf_idf_matrix.todense()

tf-idf的结果向量
#[ 2.09861229 1. 1.40546511 1. ]

tf-idf的右向量
#[0.69314718, -0.40546511, -0.40546511, 0]

结果 tf_idf_matrix
#[[0.0.50154891 0.70490949 0.50154891]
#[ 0. 0.50854232 0. 0.861037 ]]

正确答案
# [[ 0.-0.70710678 -0.70710678 0.]
# [ 0.-0.89442719 -0.4472136 0.]]

最佳答案

这不是你的错,这是因为当前 sklearn 和教程中使用的公式不同。

sklearn 的当前版本使用此公式 (source):

idf = log ( n_samples / df ) + 1

其中n_samples指的是文档总数(教程中的|D|),df指的是文档的数量该术语出现在哪个位置(教程中的 {d:t_1\in D})。

为了处理零除法,它们默认使用平滑(TfidfVectorizer 中的选项 smooth_idf=True,请参阅 documentation),它会更改 dfn_samples 值是这样的,因此这些值至少为 1:

df += 1
n_samples += 1

虽然教程中的那个使用这个公式:

idf = log ( n_samples / (1+df) )

因此,除非您更改源代码中的公式,否则您无法获得与教程中完全相同的结果。

编辑:

严格来说,正确的公式是log(n_samples/df),但由于它在实践中会导致除零问题,人们试图修改公式以允许它在所有个案。最常见的如您所说:log(n_samples/(1+df)),但使用公式 log(n_samples/df)+1 也没有错> 鉴于您已经事先对其进行了平滑处理。但是阅读代码历史,似乎他们这样做是为了让他们不会有负 IDF 值(如本 pull request 中所讨论,后来在 this fix 中更新)。另一种去除负 IDF 值的方法是将负值转换为 0。我还没有找到更常用的方法。

他们确实同意他们这样做的方式不是标准方式。所以您可以放心地说 log(n_samples/(1+df)) 是正确的方法。

要编辑公式,首先我必须警告您,这将影响使用该代码的每个用户,请确保您知道自己在做什么。

您可以直接查看源代码(在 Unix 中:位于 /usr/local/lib/python2.7/dist-packages/sklearn/feature_extraction/text.py,在 Windows 中:我现在不使用 Windows,但您可以搜索文件“text.py”)并直接编辑公式。您可能需要管理员/root 访问权限,具体取决于您使用的平台。

补充说明:

作为补充说明,词汇表中术语的顺序也不同(至少在我的机器中),因此要获得完全相同的结果(如果公式相同),您还需要传入完全相同的与教程中显示的词汇相同。所以使用你的代码:

vocabulary = {'blue':0, 'sun':1, 'bright':2, 'sky':3}
vectorizer = CountVectorizer(vocabulary=vocabulary) # You don't need stop_words if you use vocabulary
vectorizer.fit_transform(train_set)
print 'Vocabulary:', vectorizer.vocabulary_
# Vocabulary: {'blue': 0, 'sun': 1, 'bright': 2, 'sky': 3}

关于python - 使用 scikit learn 计算文本相似度时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18687879/

相关文章:

python - MemoryError : Unable to allocate array with shape (2515, 406272) 和数据类型 float32

python - python中word的所有同义词?

python - Python 中的 NLP 短语搜索

python - 无法在 Mountain Lion 上导入 NumPy

python - 如何使用 itertools 替换设置字符替换限制?

python - 计算一次,缓存结果,并从缓存中无限返回的函数(Python)

python - 了解 Keras 层的形状

python - R 中的预测时间分析(数据挖掘算法)

python - 有什么方法可以用 Pandas 进行二维插值吗?

python - Pip3 不会更新 Tensorflow