在进行TfidfVectorizer变换后,我正试图使用DBSCAN对一堆字符串进行聚类,并将余弦实例作为度量。假设我有两根绳子。当只是这两个字符串时,它们之间的余弦距离(使用sklearn.metrics.pairwise.cosine_distance计算)不同于当它们是较大数据集(与许多其他字符串一起)的一部分时它们之间的距离。
为什么会发生这种情况?我如何确保任何两个字符串之间的距离是相同的,无论它们是数据集的一部分的大小?
这样,我的DBSCAN就可以可靠地进行集群了!
编辑:根据请求添加示例代码:
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_distances
X = [
'this is a string',
'this was a string'
]
Y = [
'this could be a string',
'this may be a string'
]
Z = [
'this is a string',
'this was a string',
'this could be a string',
'this may be a string'
]
for d in [X, Y, Z]:
tv = TfidfVectorizer()
print(cosine_distances(tv.fit_transform(d)))
输出:
[[ 0. 0.49689739]
[ 0.49689739 0. ]]
[[ 0. 0.39702518]
[ 0.39702518 0. ]]
[[ 0. 0.64740127 0.70225689 0.70225689]
[ 0.64740127 0. 0.70225689 0.70225689]
[ 0.70225689 0.70225689 0. 0.46163155]
[ 0.70225689 0.70225689 0.46163155 0. ]]
正如你在这里看到的,在数据集X
中,this is a string
和this was a string
之间的距离是0.497
,但在数据集中Z
中是0.647
。数据集Y
和Z
中的字符串this could be a string
和this may be a string
相同
在上面的例子中,如果我选择DBSCAN的最大距离(eps)参数为0.6,那么在数据集X中,两个字符串都将放在同一个集群中,但在数据集Z中,它们将放在不同的集群中。
余弦相似性适用于长文档。
短字符串没有足够的单词。
距离的变化是由于TFIDF的IDF部分。您选择了反向文档频率加权,因此如果文档频率发生变化,距离也会发生变化。