我计算了两个文档的 tf/idf 值。以下是 tf/idf 值:
1.txt
0.0
0.5
2.txt
0.0
0.5
文件如下:
1.txt = > dog cat
2.txt = > cat elephant
如何使用这些值来计算余弦相似度?
我知道我应该计算点积,然后找到距离并将点积除以它。如何使用我的值计算这个?
还有一个问题:两个文档的字数相同是否重要?
我计算了两个文档的 tf/idf 值。以下是 tf/idf 值:
1.txt
0.0
0.5
2.txt
0.0
0.5
文件如下:
1.txt = > dog cat
2.txt = > cat elephant
如何使用这些值来计算余弦相似度?
我知道我应该计算点积,然后找到距离并将点积除以它。如何使用我的值计算这个?
还有一个问题:两个文档的字数相同是否重要?
a * b
sim(a,b) =--------
|a|*|b|
a*b 是点积
一些细节:
def dot(a,b):
n = length(a)
sum = 0
for i in xrange(n):
sum += a[i] * b[i];
return sum
def norm(a):
n = length(a)
for i in xrange(n):
sum += a[i] * a[i]
return math.sqrt(sum)
def cossim(a,b):
return dot(a,b) / (norm(a) * norm(b))
是的。在某种程度上,a 和 b 必须具有相同的长度。但是 a 和 b 通常具有稀疏表示,您只需要存储非零条目即可更快地计算范数和点。
简单的java代码实现:
static double cosine_similarity(Map<String, Double> v1, Map<String, Double> v2) {
Set<String> both = Sets.newHashSet(v1.keySet());
both.retainAll(v2.keySet());
double sclar = 0, norm1 = 0, norm2 = 0;
for (String k : both) sclar += v1.get(k) * v2.get(k);
for (String k : v1.keySet()) norm1 += v1.get(k) * v1.get(k);
for (String k : v2.keySet()) norm2 += v2.get(k) * v2.get(k);
return sclar / Math.sqrt(norm1 * norm2);
}
1)计算tf-idf(通常比单独的tf好,但完全取决于您的数据集和要求)
来自wiki(关于 idf )
加入了逆文档频率因子,它减少了文档集中出现频率很高的词项的权重,增加了很少出现的词项的权重。
2)不,两个文档的字数相同并不重要。
3)您现在可以通过调用一些机器学习库函数来查找tf-idf
或使用任何语言。cosine-similarity
我更喜欢蟒蛇
计算tf-idf和余弦相似度的Python 代码(使用scikit-learn 0.18.2)
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
# example dataset
from sklearn.datasets import fetch_20newsgroups
# replace with your method to get data
example_data = fetch_20newsgroups(subset='all').data
max_features_for_tfidf = 10000
is_idf = True
vectorizer = TfidfVectorizer(max_df=0.5, max_features=max_features_for_tf_idf,
min_df=2, stop_words='english',
use_idf=is_idf)
X_Mat = vectorizer.fit_transform(example_data)
# calculate cosine similarity between samples in X with samples in Y
cosine_sim = cosine_similarity(X=X_Mat, Y=X_Mat)
4) 您可能对截断奇异值分解 (SVD)感兴趣