Skip to content

Instantly share code, notes, and snippets.

@cmantas
Last active August 9, 2017 10:13
Show Gist options
  • Save cmantas/7daa756a6a9ac2f8f8e48f254d7c9d70 to your computer and use it in GitHub Desktop.
Save cmantas/7daa756a6a9ac2f8f8e48f254d7c9d70 to your computer and use it in GitHub Desktop.
Kendall's tau measure in Ruby (Kendall rank correlation coefficient)
# careful!, a and b should have the same elements
# Kendall's tau (τ) measure for any two arrays
# @param a[Array] an array (sorted by a ranking)
# @param b[Array] array having the same elements as a, sorted by another ranking
# @return [Float] in range [-1, 1]
def kendal(a, b)
pairs = a.combination(2) # note that for each of those pairs, the position of
# the second element in array `a` is subsequent to the position of the first.
# (aka, if a = ['a', 'b', 'c'], value ['c','b'] cannot exist in `pairs`)
# due to this observation we only need to index the positions of array `b`
rank_b = b.each_with_index.to_h
concordant, discordant = 0,0
pairs.each do |v1, v2|
if rank_b[v1] > rank_b[v2]
discordant += 1
else
concordant +=1
end
end
n = a.size
(concordant - discordant).to_f / (n*(n-1.0)/2.0)
end
@cmantas
Copy link
Author

cmantas commented Aug 8, 2017

The formula was taken from wikipedia.
Other implementations I found in ruby did not agree with what was in wikipedia.

Some test cases

a = (0..100).to_a
kendal(a,a)
#=> 1.0
kendal(a,a.reverse)
#=> -1.0
b = a.dup
b[-2], b[-1] = b[-1], b[-2] #swap the 2 last places
kendal(a,b)
#=> 0.9996039603960396
c = a.dup
c[0], c[-1] = c[-1], c[0] # swap the first and last places
kendal(a,cc)
#=> 0.9211881188118812

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