Created
January 28, 2020 02:49
-
-
Save komasaru/51a8341e56a5c9453ce60812a7d089f0 to your computer and use it in GitHub Desktop.
Ruby script to calculate a Spearman's Rank Correlation Coefficient.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/local/bin/ruby | |
class Array | |
def rcc_spearman(y) | |
# 以下の場合は例外スロー | |
# - 引数の配列が Array クラスでない | |
# - 自身配列が空 | |
# - 配列サイズが異なる | |
# - 数値以外のデータが存在する | |
raise "Argument is not a Array class!" unless y.class == Array | |
raise "Self array is nil!" if self.size == 0 | |
raise "Argument array size is invalid!" unless self.size == y.size | |
(self + y).each do |v| | |
raise "Items except numerical values exist!" unless v.to_s =~ /[\d\.]+/ | |
end | |
# ランク付け | |
rank_x = self.map { |v| self.count { |a| a > v } + 1 } | |
rank_y = y.map { |v| y.count { |a| a > v } + 1 } | |
# 同順位を中央(平均)順位(mid-rank)に | |
rank_x = rank_x.map do |v| | |
c = rank_x.count(v) | |
(v...(v + c)).sum / c.to_f | |
end | |
rank_y = rank_y.map do |v| | |
c = rank_y.count(v) | |
(v...(v + c)).sum / c.to_f | |
end | |
# 同順位の数 | |
tai_x = rank_x.group_by { |a| a }.map { |k, v| [k, v.size] }.to_h | |
tai_y = rank_y.group_by { |a| a }.map { |k, v| [k, v.size] }.to_h | |
# Tx, Ty の sum 部分 | |
s_x = tai_x.select { |k, v| v > 1 }.map do |a| | |
a[1] * a[1] * a[1] - a[1] | |
end.sum | |
s_y = tai_y.select { |k, v| v > 1 }.map do |a| | |
a[1] * a[1] * a[1] - a[1] | |
end.sum | |
# 相関係数 | |
n = self.size | |
n3 = n * n * n - n | |
t_x = (n3 - s_x) / 12.0 | |
t_y = (n3 - s_y) / 12.0 | |
s = rank_x.zip(rank_y).inject(0) { |s, a| s + (a[0] - a[1]) * (a[0] - a[1]) } | |
return (t_x + t_y - s) / (2 * Math.sqrt(t_x * t_y)) | |
end | |
end | |
# タイ(同順位)が存在しない例 | |
#X = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] | |
#Y = [1, 3, 5, 7, 9, 2, 4, 6, 8, 10] | |
# タイ(同順位)が存在する例 | |
X = [1, 2, 3, 4, 5, 5, 7, 8, 9, 10] | |
Y = [1, 3, 5, 6, 9, 2, 4, 6, 8, 10] | |
# サイズが異なる例 | |
#X = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] | |
#Y = [1, 3, 5, 7, 9, 2, 4, 6, 8] | |
# X のサイズがゼロの例 | |
#X = [] | |
#Y = [1, 3, 5, 7, 9, 2, 4, 6, 8, 10] | |
# 数値以外のものが存在する例 | |
#X = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] | |
#Y = [1, 3, 5, 7, 9, "ABC", 4, 6, 8, 10] | |
puts " X = #{X}" | |
puts " Y = #{Y}" | |
puts " Spearman's RCC = #{X.rcc_spearman(Y)}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment