Ga naar de hoofdinhoud
BVDNET
Arnhem · websites & automatiseringBVDNET
Kernconcepten

Cosine similarity

Cosine similarity is een score tussen -1 en 1 die zegt hoeveel twee teksten op elkaar lijken, nadat een AI-model ze in getallen heeft omgezet.

Ook bekend als: cosinusgelijkenis, cosine distance

Cosine similarity (ook cosinusgelijkenis) is een score voor hoeveel twee teksten of afbeeldingen op elkaar lijken, nadat een AI-model ze heeft omgezet in rijen getallen (embeddings). De score kijkt naar de verhouding tussen die getallen en negeert hun grootte, dus een korte klantvraag en een lang helpartikel over hetzelfde onderwerp kunnen toch bij elkaar passen. Zoektools en chatbots vinden er de best passende passages mee.

Hoe reken je het uit?

Voor twee vectoren A en B:

Plain Text
1cos(A, B) = (A · B) / (‖A‖ × ‖B‖)

A · B is het inproduct: vermenigvuldig de getallen op elke positie en tel de uitkomsten op. ‖A‖ is de lengte van A: de wortel uit de som van de kwadraten van zijn getallen. scikit-learn omschrijft het als een genormaliseerd inproduct. De uitkomst is de cosinus van de hoek tussen de vectoren en ligt tussen -1 en 1: 1 als ze dezelfde kant op wijzen, 0 als ze haaks op elkaar staan en -1 als ze tegengesteld wijzen. Kan geen enkel getal negatief zijn, zoals bij woordtellingen, dan blijft de score tussen 0 en 1 (Wikipedia).

Waarom meet je niet gewoon de afstand?

De klassieke reden komt uit zoekmachines. In Introduction to Information Retrieval stellen Manning, Raghavan en Schütze documenten voor als woordtellingen. Twee documenten met bijna dezelfde inhoud kunnen dan ver uit elkaar liggen, alleen omdat het ene veel langer is. Cosine similarity compenseert voor dat verschil in lengte.

Voor embeddings geeft Pinecone een vuistregel: gebruik de maat waarmee het embeddingmodel is getraind. Het model all-MiniLM-L6-v2 is bijvoorbeeld getraind met cosine similarity. Cosine past slecht als de grootte van de vectoren zelf betekenis heeft. Voor vectoren met lengte 1 maakt de keuze weinig uit. OpenAI normaliseert zijn embeddings op lengte 1, dus is de cosinus gelijk aan het gewone inproduct en geeft hij dezelfde volgorde als de euclidische afstand, volgens de embeddingsgids van OpenAI, die cosine similarity aanraadt.

Hoe wordt het in AI gebruikt?

Een embeddingmodel zet een tekst om in een vast aantal waarden: 384 bij all-MiniLM-L6-v2, en standaard 1.536 bij text-embedding-3-small en 3.072 bij text-embedding-3-large van OpenAI. Bij semantisch zoeken en RAG wordt de vraag met hetzelfde model omgezet in een vector, en geeft het systeem de opgeslagen passages met de hoogste scores terug (de top k). Een vectordatabase hoeft de vraag daarbij niet met elke opgeslagen vector te vergelijken: indexen zoals HNSW (Malkov en Yashunin) zoeken bij benadering de dichtstbijzijnde buren, met een zoekinspanning die logaritmisch groeit met het aantal vectoren.

Waar gaat het mis?

  • Een score zegt op zichzelf weinig. Ethayarajh (2019) ontdekte dat de woordrepresentaties in de taalmodellen BERT, ELMo en GPT-2 in een smalle kegel liggen, en dat in de laatste laag van GPT-2 twee willekeurige woorden gemiddeld een bijna perfecte cosine similarity hebben. Een vaste drempelwaarde moet je daarom per model testen, op je eigen data.
  • Steck e.a. (Netflix, 2024) laten zien dat cosine similarity bij embeddings uit geregulariseerde lineaire modellen willekeurige uitkomsten kan geven, afhankelijk van hoe het model is getraind, en ze waarschuwen tegen blind gebruik.
  • De score is zo goed als de vectoren. Met woordtellingen worden "Jan is sneller dan Marie" en "Marie is sneller dan Jan" dezelfde vector, zoals het IR-boek opmerkt, dus is hun cosine similarity 1.

Voorbeeld

Stel: een webshop geeft elke tekst een score op drie onderwerpen: schoenen, retouren en prijzen. De vraag "Kan ik deze schoenen retourneren?" krijgt (1, 2, 0). De lange retourpagina krijgt (3, 6, 0): drie keer zoveel tekst, dezelfde verhouding. De prijslijst krijgt (1, 0, 5). De cosine similarity tussen de vraag en de retourpagina is 1,00, en tussen de vraag en de prijslijst 0,09. Gemeten als rechte afstand ligt de retourpagina 4,47 van de vraag af en de prijslijst 5,39, bijna even ver. Echte embeddings hebben honderden of duizenden dimensies zonder zulke namen, en de rekensom is dezelfde.