La formule : cos(θ) = (A · B) / (||A|| × ||B||), où A · B est le produit scalaire et ||A||, ||B|| sont les magnitudes (longueurs) des vecteurs. En divisant par les magnitudes, la similarité cosinus ne mesure que la direction — un vecteur [1, 2, 3] est identique en similarité cosinus à [2, 4, 6] parce qu'ils pointent dans la même direction. Cette normalisation est la raison pour laquelle le cosinus fonctionne bien pour les embeddings : la direction encode le sens, tandis que la magnitude peut varier selon la longueur du texte ou les particularités du modèle.
Si les embeddings sont déjà normalisés à une longueur unitaire (magnitude 1), la similarité cosinus est égale au produit scalaire — et le produit scalaire est plus rapide à calculer (pas de division). La plupart des modèles d'embedding produisent des vecteurs normalisés exactement pour cette raison. Quand tu utilises une base de données vectorielle, vérifie si tes embeddings sont normalisés : si oui, utilise le produit scalaire (plus rapide). Sinon, utilise la similarité cosinus (correcte quelle que soit la normalisation).
La similarité cosinus traite toutes les dimensions de manière égale, mais certaines dimensions de l'embedding peuvent être plus importantes que d'autres. Elle mesure aussi la similarité directionnelle globale, ce qui peut manquer des différences nuancées. Deux phrases sur "la programmation Python" et "le serpent Python" pourraient avoir une similarité cosinus modérément élevée parce qu'elles partagent le concept "Python". Des mesures de similarité plus sophistiquées (métriques apprises, reclassement par cross-encoder) peuvent capturer des distinctions plus fines à un coût computationnel plus élevé.