Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用scikit学习计算文本相似度时出错_Python_Machine Learning_Nltk_Cosine Similarity - Fatal编程技术网

Python 使用scikit学习计算文本相似度时出错

Python 使用scikit学习计算文本相似度时出错,python,machine-learning,nltk,cosine-similarity,Python,Machine Learning,Nltk,Cosine Similarity,我是向量空间模型(VSM)的初学者。我试过了我的密码 . 这是对VSM的一个很好的介绍,但我不知怎的从作者那里得到了不同的结果。这可能是因为一些兼容性问题,因为自介绍撰写以来似乎已经发生了很大的变化。也可能是我误解了解释。 我用下面的代码得到了错误的答案。有人能找出它的毛病吗?我把下面代码的结果和正确答案贴在下面 我已经做了手工计算,所以我知道网站的结果是好的。 还有一个网站使用相同的代码,但也没有得到与网站相同的结果。 import numpy, scipy, sklearn train_s

我是向量空间模型(VSM)的初学者。我试过了我的密码 . 这是对VSM的一个很好的介绍,但我不知怎的从作者那里得到了不同的结果。这可能是因为一些兼容性问题,因为自介绍撰写以来似乎已经发生了很大的变化。也可能是我误解了解释。
我用下面的代码得到了错误的答案。有人能找出它的毛病吗?我把下面代码的结果和正确答案贴在下面

我已经做了手工计算,所以我知道网站的结果是好的。 还有一个网站使用相同的代码,但也没有得到与网站相同的结果。

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\u idf\u矩阵
#[[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
使用以下公式():

其中,
n|u samples
指文档总数(
|D |
在教程中),而
df
指出现术语的文档数量(
{D:t|u 1\在D}
在教程中)

为了处理零除法,默认情况下,它们使用平滑(在
TfidfVectorizer
中的选项
smooth\u idf=True
,请参见)来更改
df
n\u采样值,这样这些值至少为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值为负值(如本文所述,稍后在中更新)。另一种删除负IDF值的方法是将负值转换为0。我还没有找到哪种方法更常用

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

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

您只需转到源代码(在Unix中:位于
/usr/local/lib/python2.7/dist packages/sklearn/feature\u 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}

打印语句的输出是什么?我发布了打印语句谢谢。似乎公式是正确的,代码不是正确的。不是吗?我是这个领域的初学者。如果函数不正确,我如何编辑它?但我认为正确的公式应该是idf=log(n_samples/(1+df))。你能确认一下吗?代码中的公式可能不是“正确的”,但在实践中,它可以很好地提取机器学习和余弦相似性的良好特征@DJJ您确定要更改scikit learn中的代码吗?难道它不会产生与博客文章相同的相似性排名吗?我们不会在Stackoverflow上发表评论来表示感谢。但你真的让我开心。我的主要观点是TF-IDF从根本上说只是一种对文本特征进行加权的黑客,使机器学习和余弦sim查询在这些特征上运行良好。没有“普遍最佳”的TF-IDF方法。TF-IDF的“正确”变体是通过特定机器学习任务(如多类分类)的特定度量(如F1分数)来衡量的最有效的变体。
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}