Skip to content

Instantly share code, notes, and snippets.

@turbod
Created July 23, 2023 16:44
Show Gist options
  • Save turbod/6d01967862ea0358c3c5892c4efd0ee5 to your computer and use it in GitHub Desktop.
Save turbod/6d01967862ea0358c3c5892c4efd0ee5 to your computer and use it in GitHub Desktop.
class Metrics
def self.euclidean_distance(a,b)
return unless a.any? && (a.size == b.size)
diff_squared = (0..a.size-1).reduce(0) do |sum, i|
sum + (a[i] - b[i])**2
end
Math.sqrt(diff_squared)
end
def self.manhattan_distance(a, b)
return unless a.any? && (a.size == b.size)
(0..a.size-1).reduce(0) do |sum, i|
sum + (a[i] - b[i]).abs
end
end
def self.minkowski_distance(a, b, p)
return unless a.any? && (a.size == b.size)
(0..a.size-1).reduce(0) do |sum, i|
sum + (a[i] - b[i]).abs**p
end**(1.0/p)
end
def self.chebyshev_distance(a, b)
return unless a.any? && (a.size == b.size)
(0..a.size-1).map do |i|
(a[i] - b[i]).abs
end.max
end
def self.hamming_distance(a, b)
return unless a.any? && (a.size == b.size)
(0..a.size-1).reduce(0) do |sum, i|
sum + ((a[i] != b[i]) ? 1 : 0)
end
end
def self.cosine_similarity(a, b)
return unless a.any? && (a.size == b.size)
return if is_zero?(a) || is_zero?(b)
dot_product(a,b) / (mod(a) * mod(b))
end
def self.cosine_distance(a, b)
return unless a.any? && (a.size == b.size)
return if is_zero?(a) || is_zero?(b)
1 - self.cosine_similarity(a, b)
end
def self.jaccard_similarity(a, b)
return unless a.any? && b.any?
(a & b).size / (a | b).size.to_f
end
# Private class methods
def self.dot_product(a, b)
(0..a.size-1).reduce(0) do |sum, i|
sum + a[i] * b[i]
end
end
private_class_method :dot_product
def self.mod(a)
Math.sqrt((0..a.size-1).reduce(0) do |sum, i|
sum + a[i]**2
end)
end
private_class_method :mod
def self.is_zero?(a)
a.all? {|i| i == 0 }
end
private_class_method :is_zero?
end
@Sivecano
Copy link

you might, want to generically include the metrics induced by the L_p norms

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment