Skip to content

Instantly share code, notes, and snippets.

@jbowles
Created December 13, 2024 20:03
Show Gist options
  • Save jbowles/15212d096ff8055b664669389362ca64 to your computer and use it in GitHub Desktop.
Save jbowles/15212d096ff8055b664669389362ca64 to your computer and use it in GitHub Desktop.
package metron
import "math"
// CosineSim calculate the similarity of two non-zero vectors using dot product (multiplying vector elements and summing) and deriving the cosine angle between the two vectors.
// TODO not fully tested yet!
//
// Dot Product:
// \vec{a} = (a_1, a_2, a_3, \ldots), \vec{b} = (b_1, b_2, b_3, \ldots); where a_n and a_b are elements of the vector.
// Cosine Similarity:
// cos(theta) = (A dotProduct B) / (||A|| ||B||)
// nice post: http://blog.christianperone.com/2013/09/machine-learning-cosine-similarity-for-vector-space-models-part-iii/
func CosineSim(a []float64, b []float64) float64 {
// TODO not fully tested yet!
var sum, s1, s2 float64
var count int
lenA := len(a)
lenB := len(b)
if lenA != lenB {
panic("vectors must be equal length!")
}
if lenA > lenB {
count = lenA
} else {
count = lenB
}
for k := 0; k < count; k++ {
if k >= lenA {
s2 += math.Pow(b[k], 2)
}
if k >= lenB {
s1 += math.Pow(a[k], 2)
}
sum += a[k] * b[k]
s1 += math.Pow(a[k], 2)
s2 += math.Pow(b[k], 2)
}
if s1 == 0 {
panic("First vector passed is all zeros. Non-zero vectors required.")
}
if s2 == 0 {
panic("Second vector passed is all zeros. Non-zero vectors required.")
}
return sum / (math.Sqrt(s1) * math.Sqrt(s2))
}
// CosineDist is cosine distance; simply 1 - CosineSim
func CosineDist(a []float64, b []float64) float64 {
return 1.0 - CosineSim(a, b)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment