Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.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
Scikit learn 余弦相似性=1.0,即使源/输入字符串具有语料库中未看到的额外标记?_Scikit Learn_Cosine Similarity_Tfidfvectorizer - Fatal编程技术网

Scikit learn 余弦相似性=1.0,即使源/输入字符串具有语料库中未看到的额外标记?

Scikit learn 余弦相似性=1.0,即使源/输入字符串具有语料库中未看到的额外标记?,scikit-learn,cosine-similarity,tfidfvectorizer,Scikit Learn,Cosine Similarity,Tfidfvectorizer,我正在使用来自scikit learn的TfidfVectorizer和余弦_相似度。当我有一个新字符串,并且我试图找到与原始训练语料库中的字符串的余弦相似性时,我注意到,即使字符串是精确匹配的,加上新字符串中的其他新标记,无论有多少这样的附加标记,余弦相似性都是1.0 例如,如果x、y和z根本不在原始语料库中,则形式为“ab x y z”的新字符串与原始字符串“ab”的余弦相似性为1.0 我理解这种情况是如何发生的,因为在根据训练语料库建立的特征对新字符串进行矢量化时,会忽略新的标记,但我希望

我正在使用来自scikit learn的TfidfVectorizer和余弦_相似度。当我有一个新字符串,并且我试图找到与原始训练语料库中的字符串的余弦相似性时,我注意到,即使字符串是精确匹配的,加上新字符串中的其他新标记,无论有多少这样的附加标记,余弦相似性都是1.0

例如,如果x、y和z根本不在原始语料库中,则形式为“ab x y z”的新字符串与原始字符串“ab”的余弦相似性为1.0

我理解这种情况是如何发生的,因为在根据训练语料库建立的特征对新字符串进行矢量化时,会忽略新的标记,但我希望能够检测到“ab x y z”与“ab”并非真正的“完美”匹配

关于如何将对这种类型的差异(新标记的存在)敏感的内容合并到匹配中,有什么想法吗


编辑:以下是基于@Arash评论的插图:

我描述的场景试图将新输入与经过训练的语料库相匹配:

corpus = (
        "The sky is blue",
        "The sun is bright",
        "The sun in the sky is bright",
        "We can see the shining sun, the bright sun"
        )
input = ("The sky is blue",
        "They say the sky is blue you know",
        )
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf_vectorizer = TfidfVectorizer()
tfidf_corpus = tfidf_vectorizer.fit_transform(corpus)
print(tfidf_corpus.shape)

tfidf_input = tfidf_vectorizer.transform(input)
print(tfidf_input.shape)

from sklearn.metrics.pairwise import cosine_similarity
cosine_similarity(tfidf_input, tfidf_corpus)
输出是

(4, 11)
(2, 11)
array([[1.        , 0.36651513, 0.52305744, 0.13448867],
       [1.        , 0.36651513, 0.52305744, 0.13448867]])
因此,您可以看到,两个输入字符串/文档与语料库的“天空是蓝色的”有着1.0的完美相似性,即使第二个输入(“他们说天空是蓝色的,您知道”)有几个不匹配的词(碰巧没有出现在语料库中)

我希望第二个输入项的余弦相似度可以在扩展向量上计算,该扩展向量为新单词添加元素(每个新单词的文档频率为0,因此最大IDF),这样相似度就会降低


简单地在语料库中包含新的输入数据并不是一个好的通用解决方案,因为我们将来可能会一次接收一个新的输入,我们不希望每次都要重新训练整个语料库来匹配一个新的输入文档/字符串。

我无法复制您所描述的内容。试试这个:

文档=(
“天是蓝的”,
“天空是蓝色的,你知道”,
“阳光明媚”,
“天空中的太阳是明亮的”,
“我们可以看到灿烂的太阳,灿烂的太阳”
)
从sklearn.feature\u extraction.text导入TfidfVectorizer
tfidf_矢量化器=TfidfVectorizer()
tfidf_矩阵=tfidf_矢量器.拟合变换(文档)
打印(tfidf_矩阵形状)
从sklearn.metrics.pairwise导入余弦_相似性
余弦相似性(tfidf_矩阵[0:1],tfidf_矩阵)
您的输出将是

数组([[1,0.67166626,0.35369001,0.50353381,0.13245011]]
这表明第一句和第二句之间的相似性是0.67,而不是1.0


编辑 您描述的问题是向量是相同的。您希望TF-IDF将生词和生词的频率考虑在内。 所以,你可以这样做:

#将tfidf#U矢量器重新安装到语料库和新文档中
tfidf_矢量器.fit(输入+语料库)
#使用新模型进行转换
tfidf_输入=tfidf_矢量器.转换(输入)

这似乎更适合于,因为它要求一种方法,而不是scikit学习本身的编程问题。这不完全是我的情况。我已经修改了你的例子,并将其添加到原来的问题中,以澄清我的问题。@dabru:也许你在看余弦相似性时把自己弄糊涂了。在更新的问题中,只需查看
tfidf\u input.toarray()
。为了解释你的问题,这两个向量是相同的,你不想这样,因为你想把新的词汇表考虑进去。所以,就这么做吧。您需要将新文档添加到旧文档中,然后再次进行调整/转换。以实时场景为例,新句子每隔几毫秒出现一次,我们必须在现有语料库中找到最佳匹配,并在几毫秒内发送出去。我们不能为每个输入句子重新训练整个词汇表。如果vectorizer.transform()通过在输入中添加任何新单词/Ngram的列来自动扩展其输出,然后如果cosine_相似度在计算相似度之前用零填充较短的向量(来自原始语料库的向量),我们就不必这样做了,但你不会再处理TF-IDF载体了。如果重新拟合,所有向量都会不同。您可以这样做:因为随着数据的增长,获得新词的概率将越来越小,因此,首先通过设置vocab(例如,此处)标记您的词,然后进行TF-IDF转换。您可以定期重新安装标记器和TF-IDF,以提高距离的准确性。查看^