La similitud del coseno
-
22-09-2019 - |
Pregunta
Me calcula los valores tf / IDF de dos documentos. Los siguientes son los valores tf / IDF:
1.txt
0.0
0.5
2.txt
0.0
0.5
Los documentos son como:
1.txt = > dog cat
2.txt = > cat elephant
¿Cómo puedo utilizar estos valores para calcular la similitud del coseno?
Yo sé que debería calcular el producto escalar, y luego encontrar la distancia y el punto de división del producto por el mismo. ¿Cómo puedo calcular esto usando mis valores?
Una pregunta más:? ¿Es importante que ambos documentos deben tener el mismo número de palabras
Solución
a * b
sim(a,b) =--------
|a|*|b|
a * b es producto escalar
algunos detalles:
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))
Sí. en cierta medida, a y b deben tener la misma longitud. pero por lo general a y b tienen escasa representación, sólo es necesario para almacenar los no-cero entradas y se puede calcular la norma y el punto más rápido.
Otros consejos
implementación simple código de 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) Calcular TF-IDF (generalmente mejor que tf solos pero completamente depende de su conjunto de datos y el requisito)
wiki (con respecto IDF)
Un factor de frecuencia inversa de documento se incorpora que disminuye el peso de los términos que aparecen con mucha frecuencia en el conjunto de documentos y aumenta el peso de los términos que se producen en raras ocasiones.
2) No, no es importante que tanto los documentos tienen el mismo número de palabras.
3) Se puede encontrar tf-idf
o cosine-similarity
en cualquier idioma ahora los días invocando alguna de aprendizaje automático función de biblioteca. Yo prefiero pitón
Python código para calcular tf-idf y coseno similitud (usando 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) que podría estar interesado en truncada descomposición en valores singulares (SVD)