余弦相似度
我计算了两个文件的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通常都有稀疏表示,你只需要存储非零项,你就可以更快地计算norm和dot。
简单的java代码实现:
static double cosine_similarity(Map v1, Map v2) { Set 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
。 我更喜欢python
用于计算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)感兴趣