J'ai besoin de calculer la similitude cosinus entre deux listes , disons par exemple la liste 1 qui est dataSetI
et la liste 2 qui est dataSetII
. Je ne peux rien utiliser comme numpy ou un module de statistiques. Je dois utiliser des modules communs (mathématiques, etc) (et le moins de modules possible, en plus, pour réduire le temps passé).
Disons dataSetI
est [3, 45, 7, 2]
et dataSetII
est [2, 54, 13, 15]
. La longueur des listes est toujours égale.
Bien sûr, la similitude cosinus est comprise entre 0 et 1 , et pour cela, elle sera arrondie à la troisième ou quatrième décimale avec format(round(cosine, 3))
.
Merci d'avance pour votre aide.
python
python-3.x
cosine-similarity
Rob Alsod
la source
la source
Réponses:
Vous devriez essayer SciPy . Il a un tas de routines scientifiques utiles, par exemple, "des routines pour calculer des intégrales numériquement, résoudre des équations différentielles, l'optimisation et des matrices clairsemées". Il utilise le NumPy optimisé ultra-rapide pour son calcul des nombres. Voir ici pour l'installation.
Notez que spatial.distance.cosine calcule la distance et non la similitude. Donc, vous devez soustraire la valeur de 1 pour obtenir la similitude .
la source
une autre version basée
numpy
uniquement surla source
np.inner(a, b) / (norm(a) * norm(b))
- être vaut mieux comprendre.dot
peut obtenir le même résultat queinner
pour les vecteurs.scipy.spatial.distance.cosine
.cos_sim = (a @ b.T) / (norm(a)*norm(b))
Vous pouvez utiliser
cosine_similarity
des documents de formulaire de fonctionsklearn.metrics.pairwise
la source
cosine_similarity([[1, 0, -1]], [[-1,-1, 0]])
Je ne pense pas que la performance compte beaucoup ici, mais je ne peux pas résister. La fonction zip () recopie complètement les deux vecteurs (plutôt une transposition matricielle, en fait) juste pour obtenir les données dans l'ordre "Pythonic". Il serait intéressant de chronométrer la mise en œuvre des écrous et boulons:
Cela passe par le bruit de type C d'extraction d'éléments un par un, mais ne fait pas de copie de tableau en bloc et fait tout ce qui est important dans une seule boucle for, et utilise une seule racine carrée.
ETA: appel d'impression mis à jour pour être une fonction. (L'original était Python 2.7, pas 3.3. Le courant fonctionne sous Python 2.7 avec un
from __future__ import print_function
instruction.) La sortie est la même, de toute façon.CPYthon 2.7.3 sur 3.0GHz Core 2 Duo:
Ainsi, la voie unpythonic est environ 3,6 fois plus rapide dans ce cas.
la source
cosine_measure
ce que dans ce cas?cosine_measure
etcosine_similarity
sont simplement des implémentations différentes du même calcul. Équivaut à mettre à l'échelle les deux tableaux d'entrée en «vecteurs unitaires» et à prendre le produit scalaire.cosine_measure
est le code publié précédemment par pkacprzak. Ce code était une alternative à «l'autre» solution Python tout standard.sans utiliser d'importations
peut être remplacé par
sans utiliser numpy.dot (), vous devez créer votre propre fonction de point en utilisant la compréhension de liste:
et puis il suffit d'appliquer la formule de similarité cosinus:
la source
J'ai fait un benchmark basé sur plusieurs réponses à la question et l'extrait suivant est considéré comme le meilleur choix:
Le résultat me surprend que l'implémentation basée sur
scipy
ne soit pas la plus rapide. J'ai profilé et je trouve que le cosinus dans scipy prend beaucoup de temps pour convertir un vecteur de la liste python en tableau numpy.la source
Vous pouvez l'arrondir après le calcul:
Si vous le voulez vraiment court, vous pouvez utiliser ce one-liner:
la source
[2,3,2,5]
et la version v2[3,2,2,0]
. Il revient avec1.0
, comme s'ils étaient exactement les mêmes. Une idée de ce qui ne va pas?Vous pouvez le faire en Python en utilisant une fonction simple:
la source
En utilisant numpy, comparez une liste de nombres à plusieurs listes (matrice):
la source
Vous pouvez utiliser cette fonction simple pour calculer la similitude cosinus:
la source
Si vous utilisez déjà PyTorch , vous devriez opter pour leur implémentation CosineSimilarity .
Supposons que vous ayez des s à deux
n
dimensionsnumpy.ndarray
,v1
etv2
, c'est-à-dire que leurs formes sont les deux(n,)
. Voici comment obtenir leur similitude cosinus:Ou supposons que vous ayez deux
numpy.ndarray
sw1
etw2
, dont les formes sont les deux(m, n)
. Ce qui suit vous donne une liste de similitudes en cosinus, chacune étant la similitude en cosinus entre une ligne dansw1
et la ligne correspondante dansw2
:la source
Toutes les réponses sont parfaites pour les situations où vous ne pouvez pas utiliser NumPy. Si vous le pouvez, voici une autre approche:
Gardez également à l'esprit sur le point
EPSILON = 1e-07
de sécuriser la division.la source