Косинусное Сходство
-
22-09-2019 - |
Вопрос
Я вычислил значения 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 (как правило, лучше, чем только t-f, но полностью зависит от вашего набора данных и требований)
От Вики ( относительно Армии обороны Израиля )
Включен обратный коэффициент частоты документов, который уменьшает вес терминов, которые встречаются в наборе документов очень часто, и увеличивает вес терминов, которые встречаются редко.
2) Нет, не важно, чтобы в обоих документах было одинаковое количество слов.
3) Вы можете найти tf-idf
или cosine-similarity
на любом языке в наши дни, вызвав некоторую функцию библиотеки машинного обучения.Я предпочитаю python
Код Python для вычисления tf-идф и косинус-подобие ( используя 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)