Necesito calcular la similitud de coseno entre dos listas , digamos, por ejemplo, la lista 1 que es dataSetI
y la lista 2 que es dataSetII
. No puedo usar nada como numpy o un módulo de estadísticas. Debo usar módulos comunes (matemáticas, etc.) (y la menor cantidad posible de módulos, además, para reducir el tiempo empleado).
Digamos que dataSetI
es [3, 45, 7, 2]
y dataSetII
es [2, 54, 13, 15]
. La longitud de las listas siempre es igual.
Por supuesto, la similitud de coseno está entre 0 y 1 , y por el bien de ella, se redondeará al tercer o cuarto decimal con format(round(cosine, 3))
.
Muchas gracias de antemano por ayudar.
python
python-3.x
cosine-similarity
Rob Alsod
fuente
fuente
Respuestas:
Deberías probar SciPy . Tiene un montón de rutinas científicas útiles, por ejemplo, "rutinas para calcular integrales numéricamente, resolver ecuaciones diferenciales, optimización y matrices dispersas". Utiliza NumPy superrápido optimizado para su procesamiento numérico. Consulte aquí la instalación.
Tenga en cuenta que space.distance.cosine calcula la distancia y no la similitud. Entonces, debes restar el valor de 1 para obtener la similitud .
fuente
otra versión basada en
numpy
solofuente
np.inner(a, b) / (norm(a) * norm(b))
sea mejor de entender.dot
puede obtener el mismo resultado queinner
para los vectores.scipy.spatial.distance.cosine
.cos_sim = (a @ b.T) / (norm(a)*norm(b))
Puede utilizar documentos de
cosine_similarity
formulario de funciónsklearn.metrics.pairwise
fuente
cosine_similarity([[1, 0, -1]], [[-1,-1, 0]])
Supongo que el rendimiento no importa mucho aquí, pero no puedo resistirme. La función zip () vuelve a copiar completamente ambos vectores (más bien una transposición de matriz, en realidad) solo para obtener los datos en orden "Pythonic". Sería interesante cronometrar la implementación de tuercas y tornillos:
Eso pasa por el ruido tipo C de extraer elementos de uno en uno, pero no realiza copias masivas de matrices y hace que todo lo importante se haga en un solo bucle for, y usa una sola raíz cuadrada.
ETA: llamada de impresión actualizada para que sea una función. (El original era Python 2.7, no 3.3. El actual se ejecuta en Python 2.7 con una
from __future__ import print_function
declaración). El resultado es el mismo, de cualquier manera.CPYthon 2.7.3 en 3.0GHz Core 2 Duo:
Entonces, la forma no pitónica es aproximadamente 3.6 veces más rápida en este caso.
fuente
cosine_measure
en este caso?cosine_measure
ycosine_similarity
son simplemente diferentes implementaciones del mismo cálculo. Equivalente a escalar ambas matrices de entrada a "vectores unitarios" y tomar el producto escalar.cosine_measure
es el código publicado anteriormente por pkacprzak. Este código era una alternativa a la "otra" solución de Python totalmente estándar.sin usar ninguna importación
puede ser reemplazado con
sin usar numpy.dot (), debe crear su propia función de puntos usando la lista de comprensión:
y luego es solo una simple cuestión de aplicar la fórmula de similitud del coseno:
fuente
Hice un punto de referencia basado en varias respuestas en la pregunta y se cree que el siguiente fragmento es la mejor opción:
El resultado me sorprende de que la implementación basada en
scipy
no sea la más rápida. Hice un perfil y descubrí que el coseno en scipy lleva mucho tiempo convertir un vector de la lista de Python a la matriz numpy.fuente
Puede redondearlo después de calcular:
Si lo quieres realmente corto, puedes usar este de una sola línea:
fuente
[2,3,2,5]
y v2 siendo[3,2,2,0]
. Vuelve con1.0
, como si fueran exactamente iguales. ¿Alguna idea de lo que está mal?Puedes hacer esto en Python usando una función simple:
fuente
Usando numpy compare una lista de números con múltiples listas (matriz):
fuente
Puede utilizar esta sencilla función para calcular la similitud del coseno:
fuente
Si ya está usando PyTorch , debería ir con su implementación CosineSimilarity .
Suponga que tiene s
n
bidimensionales y , es decir, sus formas son ambas . Así es como obtienes su similitud de coseno:numpy.ndarray
v1
v2
(n,)
O supongamos que tiene dos
numpy.ndarray
sw1
yw2
, cuyas formas son a la vez(m, n)
. A continuación, obtendrá una lista de similitudes de coseno, cada una de las cuales es la similitud de coseno entre una fila dew1
y la fila correspondiente enw2
:fuente
Todas las respuestas son excelentes para situaciones en las que no puede usar NumPy. Si puede, aquí tiene otro enfoque:
También tenga en cuenta a cerca
EPSILON = 1e-07
de asegurar la división.fuente