scikit learn中两种不同矢量化技术的余弦相似度得分相同
Posted
技术标签:
【中文标题】scikit learn中两种不同矢量化技术的余弦相似度得分相同【英文标题】:Cosine Similarity score in scikit learn for two different vectorization technique is same 【发布时间】:2018-03-07 08:49:49 【问题描述】:我最近在做一个任务,任务是使用 20_newgroups 数据集并使用 3 种不同的向量化技术(词袋、TF、TFIDF)来表示向量格式的文档,然后尝试分析平均余弦相似度之间的差异20_Newsgroups 数据集中的每个类之间。所以这就是我想要在 python 中做的事情。我正在读取数据并将其传递给 sklearn.feature_extraction.text.CountVectorizer 类的 fit() 和 transform() 函数用于词袋技术和 TfidfVectorizer 用于 TFIDF 技术。
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity,cosine_distances
import numpy
import math
import csv
===============================================================================================================================================
categories = ['alt.atheism','comp.graphics','comp.os.ms-windows.misc','comp.sys.ibm.pc.hardware','comp.sys.mac.hardware', 'comp.windows.x','misc.forsale','rec.autos','rec.motorcycles','rec.sport.baseball','rec.sport.hockey',
'sci.crypt','sci.electronics','sci.med','sci.space','soc.religion.christian','talk.politics.guns',
'talk.politics.mideast','talk.politics.misc','talk.religion.misc']
twenty_newsgroup = fetch_20newsgroups(subset='all',remove=('headers', 'footers', 'quotes'),shuffle=True, random_state=42)
dataset_groups = []
for group in range(0,20):
category = []
category.append(categories[group])
dataset_groups.append(fetch_20newsgroups(subset='all',remove=('headers','footers','quotes'),shuffle=True,random_state=42,categories=category))
===============================================================================================================================================
bag_of_word_vect = CountVectorizer(stop_words='english',analyzer='word') #,min_df = 0.09
bag_of_word_vect = bag_of_word_vect.fit(twenty_newsgroup.data,twenty_newsgroup.target)
datamatrix_bow_groups = []
for group in dataset_groups:
datamatrix_bow_groups.append(bag_of_word_vect.transform(group.data))
similarity_matrix = []
for i in range(0,20):
means = []
for j in range(i,20):
result_of_group_ij = cosine_similarity(datamatrix_bow_groups[i], datamatrix_bow_groups[j])
means.append(numpy.mean(result_of_group_ij))
similarity_matrix.append(means)
===============================================================================================================================================
tf_vectorizer = TfidfVectorizer(stop_words='english',analyzer='word',use_idf=False) #,sublinear_tf=True
tf_vectorizer = tf_vectorizer.fit(twenty_newsgroup.data)
datamatrix_tf_groups = []
for group in dataset_groups:
datamatrix_tf_groups.append(tf_vectorizer.transform(group.data))
similarity_matrix = []
for i in range(0,20):
means = []
for j in range(i,20):
result_of_group_ij = cosine_similarity(datamatrix_tf_groups[i], datamatrix_tf_groups[j])
means.append(numpy.mean(result_of_group_ij))
similarity_matrix.append(means)
从技术上讲,两者都应该给出不同的similarity_matrix,但它们的输出相同。更精确的 tf_vectorizer 应该创建相似度矩阵,其值更接近 1。
这里的问题是,两种技术为同一类的同一文档创建的向量(例如,alt.atheism)是不同的,它应该是不同的。但是当我计算一个类和另一类文档之间的相似度分数时,余弦相似度计分器给了我相同的值。如果我们从理论上理解,那么 TFIDF 在向量空间中以更精细的方式表示文档,因此余弦值应该更接近 1,然后我从 BAG OF WORD 技术中得到的值对吗?但它给出了相同的相似度分数。我尝试打印由 BOW 和 TFIDF 技术创建的矩阵值。如果有人能给我一个很好的理由来解决这个问题或支持正在发生的事情的有力论据,那将是一个很大的帮助? 我是这个平台的新手,所以请忽略任何错误,如果您需要更多信息,请告诉我。
感谢和问候, 达山索纳加拉
【问题讨论】:
请将代码作为格式化文本添加到您的问题中,而不是图像中。 @error 我已经更新了代码。你能帮帮我吗? 【参考方案1】:问题是代码中的这一行。
tf_vectorizer = TfidfVectorizer(stop_words='english',analyzer='word',use_idf=False) #,sublinear_tf=True
您已将use_idf
设置为False
。这意味着不计算逆文档频率。因此只计算词频。基本上你正在使用TfidfVectorizer
就像CountVectorizer
。因此两者的输出是相同的:导致相同的余弦距离。
使用tf_vectorizer = TfidfVectorizer(stop_words='english',analyzer='word',use_idf=True)
将导致 tfidf 的余弦相似度矩阵与 countvectorizer 不同。
【讨论】:
即使我使用的是真值,它给我的值更接近于零意味着两个向量之间的角度比我在词袋中得到的角度更大。但从理论上讲,如果我们说 tfidf 以比词袋技术更精细的方式表示文档是不正确的,对吧?以上是关于scikit learn中两种不同矢量化技术的余弦相似度得分相同的主要内容,如果未能解决你的问题,请参考以下文章
使用 scikit learn DictVectorizer 对特定列进行矢量化时出现问题?